Skip to content

Commit 93421bb

Browse files
committed
refactor: break up image.jsonnet into modules
For system using EFI boot we also use btrfs with compression as the rootfs. Signed-off-by: ZHANG Yuntian <yt@radxa.com>
1 parent 5bd096b commit 93421bb

11 files changed

+430
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
local product_partition_table_type = import "../configs/product_partition_table_type.libjsonnet";
2+
local product_firmware_type = import "../configs/product_firmware_type.libjsonnet";
3+
local product_sector_size = import "../configs/product_sector_size.libjsonnet";
4+
5+
local create_image = import "lib/image/create_image.jsonnet";
6+
local create_partition_table = import "lib/image/create_partition_table.jsonnet";
7+
local format_partitions = import "lib/image/format_partitions.jsonnet";
8+
local mount_partitions = import "lib/image/mount_partitions.jsonnet";
9+
local deploy_rootfs = import "lib/image/deploy_rootfs.jsonnet";
10+
local update_partition_uuid = import "lib/image/update_partition_uuid.jsonnet";
11+
local shrink_root_partition = import "lib/image/shrink_root_partition.jsonnet";
12+
local install_bootloader = import "lib/image/install_bootloader.jsonnet";
13+
local expand_root_partition = import "lib/image/expand_root_partition.jsonnet";
14+
local clean_up = import "lib/image/clean_up.jsonnet";
15+
16+
function(
17+
product,
18+
suite,
19+
output = "output.img",
20+
rootfs = "rootfs.tar",
21+
temp_dir = "./temp_dir",
22+
partition_table_type = product_partition_table_type(product),
23+
firmware_type = product_firmware_type(product),
24+
sector_size = product_sector_size(product),
25+
create_efi_part = (partition_table_type == "gpt"),
26+
efi_boot = (firmware_type == "edk2" && create_efi_part),
27+
rootfs_type = (if efi_boot then "btrfs" else "ext4"),
28+
image_size = (if rootfs_type == "btrfs" then "5G" else "10G"),
29+
root_part_num = (if create_efi_part then 3 else 2),
30+
)
31+
create_image(output, sector_size, image_size) +
32+
create_partition_table(create_efi_part, efi_boot, sector_size, partition_table_type, root_part_num) +
33+
format_partitions(create_efi_part, suite, rootfs_type, root_part_num) +
34+
mount_partitions(create_efi_part, rootfs_type, root_part_num) +
35+
deploy_rootfs(rootfs, temp_dir, efi_boot, firmware_type) +
36+
update_partition_uuid(create_efi_part, temp_dir, efi_boot, rootfs_type, root_part_num) +
37+
// btrfs shrink requires the image to be mounted in the host system
38+
(if rootfs_type != "btrfs" then shrink_root_partition(rootfs_type, output, temp_dir, sector_size, partition_table_type, root_part_num) else "")+
39+
install_bootloader(firmware_type, output, temp_dir, product, sector_size) +
40+
expand_root_partition(output, sector_size, rootfs_type, root_part_num) +
41+
clean_up(temp_dir)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function(temp_dir)
2+
|||
3+
echo "Cleaning up..."
4+
!rm -rf "%(temp_dir)s"
5+
!sync
6+
7+
echo "Deploy succeed!"
8+
||| % {
9+
temp_dir: temp_dir,
10+
} + // end with a normal string to avoid double new lines at the end
11+
'!echo "Image generation finished at $(date)."'
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function(output, sector_size, image_size)
2+
|||
3+
#!/usr/bin/env -S guestfish -f
4+
5+
!echo "Image generation started at $(date)."
6+
echo "Allocating image file..."
7+
!rm -f "%(output)s"
8+
disk-create "%(output)s" raw "%(image_size)s"
9+
add-drive "%(output)s" format:raw discard:besteffort blocksize:%(sector_size)d
10+
run
11+
12+
||| % {
13+
output: output,
14+
sector_size: sector_size,
15+
image_size: image_size,
16+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// part_size unit is MiB
2+
local efi_part_end_sector_internal(part_size, start_sector, sector_size) =
3+
(part_size * 1024 * 1024 / sector_size) + start_sector - 1;
4+
5+
local efi_part_end_sector(efi_boot, start_sector, sector_size) =
6+
(if efi_boot
7+
then
8+
efi_part_end_sector_internal(1024, start_sector, sector_size)
9+
else
10+
efi_part_end_sector_internal(300, start_sector, sector_size)
11+
);
12+
13+
local create_config_partition(partition_table_type) =
14+
|||
15+
part-init /dev/sda %(partition_table_type)s
16+
part-add /dev/sda primary 32768 65535
17+
||| % {
18+
partition_table_type: partition_table_type,
19+
};
20+
21+
local create_efi_part_partition(create_efi_part, efi_boot, sector_size, partition_table_type) =
22+
(if create_efi_part
23+
then
24+
|||
25+
part-add /dev/sda primary 65536 %(efi_part_end_sector)d
26+
part-set-bootable /dev/sda 2 true
27+
||| % {
28+
efi_part_end_sector: efi_part_end_sector(efi_boot, 65536, sector_size),
29+
} +
30+
(if partition_table_type == "gpt"
31+
then
32+
|||
33+
part-set-gpt-type /dev/sda 2 C12A7328-F81F-11D2-BA4B-00A0C93EC93B
34+
part-set-gpt-attributes /dev/sda 2 4
35+
|||
36+
else
37+
""
38+
)
39+
else
40+
""
41+
);
42+
43+
local create_root_partition(create_efi_part, efi_boot, sector_size, partition_table_type, root_part_num) =
44+
|||
45+
part-add /dev/sda primary %(root_part_start_sector)d -34
46+
part-set-bootable /dev/sda %(root_part_num)d true
47+
||| % {
48+
root_part_start_sector: (if create_efi_part then efi_part_end_sector(efi_boot, 65536, sector_size) + 1 else 65536),
49+
root_part_num: root_part_num,
50+
} +
51+
(if partition_table_type == "gpt"
52+
then
53+
|||
54+
part-set-gpt-type /dev/sda %(root_part_num)d 0FC63DAF-8483-4772-8E79-3D69D8477DE4
55+
part-set-gpt-attributes /dev/sda %(root_part_num)d 4
56+
||| % {
57+
root_part_num: root_part_num,
58+
}
59+
else
60+
""
61+
);
62+
63+
function(create_efi_part, efi_boot, sector_size, partition_table_type, root_part_num)
64+
|||
65+
echo "Creating partition table..."
66+
||| +
67+
create_config_partition(partition_table_type) +
68+
create_efi_part_partition(create_efi_part, efi_boot, sector_size, partition_table_type) +
69+
create_root_partition(create_efi_part, efi_boot, sector_size, partition_table_type, root_part_num) +
70+
"\n"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
function(rootfs, temp_dir, efi_boot, firmware_type)
2+
|||
3+
echo "Deploying rootfs..."
4+
||| +
5+
|||
6+
%(deploy_method)s
7+
8+
echo "Copying content from rootfs..."
9+
!mkdir -p "%(temp_dir)s"
10+
copy-out /etc/kernel/cmdline "%(temp_dir)s"
11+
copy-out /boot/extlinux/extlinux.conf "%(temp_dir)s"
12+
||| % {
13+
deploy_method: (if std.endsWith(rootfs, ".tar")
14+
then
15+
"tar-in %(rootfs)s / xattrs:true" % { rootfs: rootfs, }
16+
else
17+
|||
18+
echo "WARNING: rootfs is a directory."
19+
echo "You will encounter 'Permission denied' error"
20+
echo "if the script is not running in escalated privilege."
21+
||| +
22+
"copy-in %(rootfs)s/. /" % { rootfs: rootfs, }
23+
),
24+
temp_dir: temp_dir,
25+
} +
26+
(if firmware_type == "u-boot"
27+
then
28+
|||
29+
!mkdir -p "%(temp_dir)s/u-boot"
30+
copy-out /usr/lib/u-boot/ "%(temp_dir)s"
31+
||| % {
32+
temp_dir: temp_dir,
33+
}
34+
else
35+
""
36+
) +
37+
(if efi_boot
38+
then
39+
|||
40+
!mkdir -p "%(temp_dir)s/entries"
41+
copy-out /boot/efi/loader/entries "%(temp_dir)s"
42+
||| % {
43+
temp_dir: temp_dir,
44+
}
45+
else
46+
""
47+
) +
48+
"\n"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
local expand_ext4_partition(root_part_num) =
2+
"resize2fs /dev/sda%(root_part_num)d" % {
3+
root_part_num: root_part_num,
4+
};
5+
6+
local expand_btrfs_partition(root_part_num) =
7+
|||
8+
mount-options compress=zstd /dev/sda%(root_part_num)d /
9+
btrfs-filesystem-resize /
10+
unmount-all
11+
||| % {
12+
root_part_num: root_part_num,
13+
};
14+
15+
function(output, sector_size, rootfs_type, root_part_num)
16+
|||
17+
echo "Enlarging rootfs to the underlying block device..."
18+
shutdown
19+
add-drive "%(output)s" format:raw discard:besteffort blocksize:%(sector_size)d
20+
run
21+
%(expand_command)s
22+
shutdown
23+
24+
||| % {
25+
output: output,
26+
root_part_num: root_part_num,
27+
sector_size: sector_size,
28+
expand_command: (if rootfs_type == "btrfs" then
29+
expand_btrfs_partition(root_part_num)
30+
else
31+
expand_ext4_partition(root_part_num)
32+
),
33+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
local format_config_partition() =
2+
|||
3+
mkfs vfat /dev/sda1 label:config
4+
|||;
5+
6+
local format_efi_partition(create_efi_part) =
7+
(if create_efi_part
8+
then
9+
|||
10+
mkfs vfat /dev/sda2 label:efi
11+
|||
12+
else
13+
""
14+
);
15+
16+
local format_ext4_partition(suite, root_part_num) =
17+
(if suite == "bullseye"
18+
then
19+
|||
20+
mkfs ext4 /dev/sda%(root_part_num)d features:^orphan_file label:rootfs
21+
|||
22+
else
23+
|||
24+
mkfs ext4 /dev/sda%(root_part_num)d label:rootfs
25+
|||
26+
) % {
27+
root_part_num: root_part_num,
28+
};
29+
30+
local format_btrfs_partition(suite, root_part_num) =
31+
|||
32+
mkfs-btrfs /dev/sda%(root_part_num)d label:rootfs
33+
||| % {
34+
root_part_num: root_part_num,
35+
};
36+
37+
local format_root_partition(suite, rootfs_type, root_part_num) =
38+
(if rootfs_type == "btrfs"
39+
then
40+
format_btrfs_partition(suite, root_part_num)
41+
else
42+
format_ext4_partition(suite, root_part_num)
43+
);
44+
45+
function(create_efi_part, suite, rootfs_type, root_part_num)
46+
|||
47+
echo "Formatting partitions..."
48+
||| +
49+
format_config_partition() +
50+
format_efi_partition(create_efi_part) +
51+
format_root_partition(suite, rootfs_type, root_part_num) +
52+
"\n"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function(firmware_type, output, temp_dir, product, sector_size)
2+
(if firmware_type == "u-boot"
3+
then
4+
|||
5+
echo "Installing bootloader..."
6+
shutdown
7+
!chmod +x "%(temp_dir)s/u-boot/%(product)s/setup.sh"
8+
!"%(temp_dir)s/u-boot/%(product)s/setup.sh" update_bootloader "%(output)s" %(sector_size)d 2> /dev/null
9+
10+
||| % {
11+
output: output,
12+
temp_dir: temp_dir,
13+
product: product,
14+
sector_size: sector_size,
15+
}
16+
else
17+
""
18+
)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
local mount_config_partition() =
2+
|||
3+
mkdir-p /config
4+
mount /dev/sda1 /config
5+
|||;
6+
7+
local mount_efi_partition(efi) =
8+
(if efi
9+
then
10+
|||
11+
mkdir-p /boot/efi
12+
mount /dev/sda2 /boot/efi
13+
|||
14+
else
15+
""
16+
);
17+
18+
local mount_root_partition(rootfs_type, root_part_num) =
19+
|||
20+
mount-options %(options)s /dev/sda%(root_part_num)d /
21+
||| % {
22+
root_part_num: root_part_num,
23+
options: (if rootfs_type == "btrfs" then "compress=zstd" else "defaults"),
24+
};
25+
26+
function(efi, rootfs_type, root_part_num)
27+
|||
28+
echo "Mounting partitions..."
29+
||| +
30+
mount_root_partition(rootfs_type, root_part_num) +
31+
mount_config_partition() +
32+
mount_efi_partition(efi) +
33+
"\n"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
local shrink_ext4_partition(temp_dir, root_part_num) =
2+
|||
3+
unmount-all
4+
resize2fs-M /dev/sda%(root_part_num)d
5+
tune2fs-l /dev/sda%(root_part_num)d | cat > "%(temp_dir)s/tune2fs"
6+
!echo "$(( $(grep "Block count:" %(temp_dir)s/tune2fs | cut -d " " -f 3) * $(grep "Block size:" %(temp_dir)s/tune2fs | cut -d " " -f 3) ))" > "%(temp_dir)s/rootfs_size"
7+
||| % {
8+
temp_dir: temp_dir,
9+
root_part_num: root_part_num,
10+
};
11+
12+
local shrink_btrfs_partition(temp_dir, root_part_num) =
13+
|||
14+
!btrfs filesystem resize "-$(btrfs fi usage -b / | awk '/Free \(estimated\)/{print substr($NF, 1, length($NF-1))}')" /
15+
!echo "$(btrfs fi usage -b / | awk '/Device size/{print $NF}')" > "%(temp_dir)s/rootfs_size"
16+
unmount-all
17+
||| % {
18+
temp_dir: temp_dir,
19+
root_part_num: root_part_num,
20+
};
21+
22+
function(rootfs_type, output, temp_dir, sector_size, partition_table_type, root_part_num)
23+
(if sector_size == 512
24+
then
25+
|||
26+
echo "Shrinking rootfs..."
27+
||| +
28+
(if rootfs_type == "btrfs"
29+
then
30+
shrink_btrfs_partition(temp_dir, root_part_num)
31+
else
32+
shrink_ext4_partition(temp_dir, root_part_num)
33+
) +
34+
|||
35+
!echo "resizepart %(root_part_num)d" > "%(temp_dir)s/parted"
36+
!echo "$(( $(sgdisk -i %(root_part_num)d "%(output)s" | grep "First sector:" | cut -d " " -f 3) * %(sector_size)d + $(cat "%(temp_dir)s/rootfs_size") ))B" >> "%(temp_dir)s/parted"
37+
!echo "yes" >> "%(temp_dir)s/parted"
38+
sync
39+
shutdown
40+
!cat "%(temp_dir)s/parted" | parted ---pretend-input-tty "%(output)s" > /dev/null 2>&1
41+
!truncate "--size=$(( ( $(sgdisk -i %(root_part_num)d "%(output)s" | grep "Last sector:" | cut -d " " -f 3) + 34 ) * %(sector_size)d ))" "%(output)s"
42+
||| % {
43+
output: output,
44+
temp_dir: temp_dir,
45+
root_part_num: root_part_num,
46+
sector_size: sector_size,
47+
} +
48+
(if partition_table_type == "gpt"
49+
then
50+
|||
51+
52+
echo "Fixing partition table..."
53+
echo "NOTICE: Some issues are expected result of shrinking the disk."
54+
!sgdisk -ge "%(output)s" > /dev/null 2>&1 || true
55+
||| % {
56+
output: output,
57+
}
58+
else
59+
""
60+
)+
61+
"\n"
62+
else
63+
""
64+
)

0 commit comments

Comments
 (0)