diff --git a/build.sh b/build.sh index e6d5446..ef795b4 100755 --- a/build.sh +++ b/build.sh @@ -130,6 +130,9 @@ fi cp -v "${OUTPUT}_live.efi" "${OUTPUT}/efi-template/EFI/Linux/$EFI" systemd-repart --no-pager --empty=allow --size=auto --dry-run=no --root="${OUTPUT}" --definitions=mkosi.repart --defer-partitions=root "$IMG" +# Finally rebuild the actual image file with appropriate partition sizing. In particular with squeezed btrfs. +./part-rebuild.py "$IMG" + # TODO before accepting new uploads perform sanity checks on the artifacts (e.g. the tar being well formed) chmod go+r ./*.efi # efi images are 700, make them readable so the server can serve them ls -lah diff --git a/mkosi.repart-rebuild/00-esp.conf b/mkosi.repart-rebuild/00-esp.conf new file mode 100644 index 0000000..0015dd0 --- /dev/null +++ b/mkosi.repart-rebuild/00-esp.conf @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2023 Harald Sitter + +[Partition] +Type=esp +SplitName=esp +CopyBlocks=/esp.raw diff --git a/mkosi.repart-rebuild/50-root.conf b/mkosi.repart-rebuild/50-root.conf new file mode 100644 index 0000000..ac439c8 --- /dev/null +++ b/mkosi.repart-rebuild/50-root.conf @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2023 Harald Sitter + +[Partition] +Type=root +Label=KDEOSLive +SplitName=root +CopyBlocks=/KDEOSLive.raw diff --git a/mkosi.repart-rebuild/README.md b/mkosi.repart-rebuild/README.md new file mode 100644 index 0000000..c3995d7 --- /dev/null +++ b/mkosi.repart-rebuild/README.md @@ -0,0 +1,9 @@ + + +This isn't actually used by mkosi but named like it so it is next to the actual mkosi directory. +The configs in here simply pick up split partitions from the original repart run into a rebuild run. + +Also see part-rebuild.py diff --git a/mkosi.repart/50-root.conf b/mkosi.repart/50-root.conf index 7a50cae..d91fb4c 100644 --- a/mkosi.repart/50-root.conf +++ b/mkosi.repart/50-root.conf @@ -5,6 +5,7 @@ Type=root Format=btrfs SizeMinBytes=1G +# Do not use spaces. We need to extract this later as a file path. Label=KDEOSLive SplitName=root # NOTE: the FS isn't read only because we have mutable subvolumes. Individual subvolumes may be readonly though. diff --git a/part-rebuild.py b/part-rebuild.py new file mode 100755 index 0000000..153328d --- /dev/null +++ b/part-rebuild.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 + +# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL +# SPDX-FileCopyrightText: 2024 Harald Sitter + +# Rebuilds the image using appropriate partition sizes. + +import json +import math +import subprocess +from subprocess import check_output +import sys +import os + +RAW = sys.argv[1] + +# Load the partition table +out = check_output(["sfdisk", "--json", RAW]) +data = json.loads(out) +partitiontable = data["partitiontable"] +sectorsize = partitiontable["sectorsize"] +partitions = partitiontable["partitions"] + +# Find the root partition +root_partition = None +for index, partition in enumerate(partitions): + if partition["name"] == "KDEOSLive": + root_partition = partition + +# Update its size to what it actually is on the filesystem level +btrfs = json.loads(open("btrfs.json").read()) +root_partition["size"] = math.ceil(btrfs['size'] / sectorsize) + +# Fish out the partitions with appropriate skip and count values (i.e. the actual filesystem sizes) +for index, partition in enumerate(partitions): + subprocess.run(["dd", f"if={RAW}", f"of={partition["name"]}.raw", f"bs={sectorsize}", f"skip={partition["start"]}", f"count={partition["size"]}"], check=True) + +# Then reassemble them into a new image using those squeezed partition images. +open(RAW, "w").close() +subprocess.run(["systemd-repart", "--empty=allow", "--dry-run=no", "--definitions=mkosi.repart-rebuild", "--root", os.getcwd(), RAW], check=True)