From f528bc910a2e4553f20582bac2461f44456a7759 Mon Sep 17 00:00:00 2001 From: Craig Schardt Date: Wed, 3 Jul 2024 01:00:11 -0500 Subject: [PATCH] Support optimizing (shrinking) bootable partitions on images with GPT partition tables (#117) * Fix bug #116 by resizing boot partition instead of deleting and recreating it --- .../workflows/test-gpt-partition-table.yml | 2 +- .../test-shrink-bootable-partition.yml | 25 +++++++++++++++++++ cleanup_image.sh | 15 +++++++++-- 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/test-shrink-bootable-partition.yml diff --git a/.github/workflows/test-gpt-partition-table.yml b/.github/workflows/test-gpt-partition-table.yml index ef8a85a..2f945e2 100644 --- a/.github/workflows/test-gpt-partition-table.yml +++ b/.github/workflows/test-gpt-partition-table.yml @@ -18,4 +18,4 @@ jobs: image_additional_mb: 2048 cpu: cortex-a53 commands: | - test $(df -h --output=size / | tail -n 1) = '2.8G' + test $(df -h --output=size / | tail -n 1) = '2.8G' \ No newline at end of file diff --git a/.github/workflows/test-shrink-bootable-partition.yml b/.github/workflows/test-shrink-bootable-partition.yml new file mode 100644 index 0000000..b616c4d --- /dev/null +++ b/.github/workflows/test-shrink-bootable-partition.yml @@ -0,0 +1,25 @@ +name: Test shrink_bootable_partition +on: + push: + branches: + - 'main' + - 'releases/**' + pull_request: + workflow_dispatch: + +jobs: + optimized: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./ # pguyot/arm-runner-action@HEAD + id: shrink + with: + base_image: https://github.com/Joshua-Riek/ubuntu-rockchip/releases/download/v2.2.1/ubuntu-24.04-preinstalled-server-arm64-orangepi-5.img.xz + optimize_image: yes + commands: | + echo "Shrink Bootable Partition" + - name: Check image + run: | + parted --script ${{ steps.shrink.outputs.image }} print free | tail -n2 | head -n1 | grep -c "boot, esp" + diff --git a/cleanup_image.sh b/cleanup_image.sh index 8474aeb..04c4977 100644 --- a/cleanup_image.sh +++ b/cleanup_image.sh @@ -48,6 +48,9 @@ if [[ -d "${mount}" ]]; then if [[ "${optimize}x" == "x" || "${optimize}x" == "yesx" ]]; then rootfs_partnum=${rootpartition} rootdev="${loopdev}p${rootfs_partnum}" + + part_type=$(blkid -o value -s PTTYPE "${loopdev}") + echo "Image is using ${part_type} partition table" echo "Resizing root filesystem to minimal size." e2fsck -p -f "${rootdev}" @@ -63,8 +66,7 @@ if [[ -d "${mount}" ]]; then # parted --script "${loopdev}" unit B resizepart "${rootfs_partnum}" "${rootfs_partend}" # Can't use resizepart for shrinking with --script (parted bug#22167) => must rm then mkpart if [ "$rootfs_partoldend" -gt "$rootfs_partend" ]; then - parted --script "${loopdev}" rm "${rootfs_partnum}" - parted --script "${loopdev}" unit B mkpart primary "${rootfs_partstart}" "${rootfs_partend}" + echo y | parted ---pretend-input-tty "${loopdev}" unit B resizepart "${rootfs_partnum}" "${rootfs_partend}" else echo "Rootfs partition not resized as it was not shrunk" fi @@ -73,8 +75,17 @@ if [[ -d "${mount}" ]]; then if [[ "${free_space}" =~ "free" ]]; then initial_image_size=$(stat -L --printf="%s" "${image}") image_size=$(echo "${free_space}" | awk -F ":" '{print $2}' | tr -d 'B') + if [[ "${part_type}" == "gpt" ]]; then + # for GPT partition table, leave space at the end for the secondary GPT + # it requires 33 sectors, which is 16896 bytes + image_size=$((image_size + 16896)) + fi echo "Shrinking image from ${initial_image_size} to ${image_size} bytes." truncate -s "${image_size}" "${image}" + if [[ "${part_type}" == "gpt" ]]; then + # use sgdisk to fix the secondary GPT after truncation + sgdisk -e "${image}" + fi fi fi rmdir "${mount}" || true