[PATCH v6 3/8] Use OS version to set partition labels and UKI name

Demi Marie Obenour
2025-11-29T09:51:18Z

systemd-sysupdate has strict requirements on the partition layout:

- The label of the active partition must match the template in the
.transfer file. For instance, the root filesystem of Spectrum 0.0.0
must be in a partition with label "Spectrum_0.0.0", and the verity
partition must have the label "Spectrum_0.0.0.verity".

- The label of the inactive partition must be that of the old version of
Spectrum, or "_empty" for freshly installed systems.

- The partition type UUID must conform to the Discoverable Partition
Specification.

Also, the UKI must have a name that includes the OS version. Otherwise,
it will not be deleted during updates.

Since the partition label includes the OS version, add an OS version
number. Use 0.0.0 to indicate that Spectrum OS is still in very early
development and should not be used. The version number can be
overridden in the build configuration file.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
Reviewed-by: Alyssa Ross <hi@alyssa.is>
---
Changes since v5:
- Rebase and address merge conflicts.
Changes since v4:
- Rebase and address merge conflicts.
- Add missing "VERSION = config.version" in Nix files.
Changes since v2:
- Split off into separate commit.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/initramfs/Makefile | 4 ++--
host/initramfs/shell.nix | 2 ++
host/rootfs/Makefile | 4 ++--
host/rootfs/default.nix | 5 +++--
host/rootfs/shell.nix | 2 ++
lib/config.default.nix | 1 +
release/live/Makefile | 6 +++---
release/live/default.nix | 3 +++
release/live/shell.nix | 4 +++-
9 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
index 8a93c8d27dd8c097888bc418900eedbe36cd65a3..89f9a39b431022ec24476869e6ad10b11337fb1e 100644
--- a/host/initramfs/Makefile
+++ b/host/initramfs/Makefile
@@ -37,8 +37,8 @@ build/mountpoints:

build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
- $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)"):Spectrum_'$(VERSION).verity' \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))"):Spectrum_'$(VERSION)'
mv $@.tmp $@

clean:
diff --git a/host/initramfs/shell.nix b/host/initramfs/shell.nix
index 8b47aa53bc19a818ebf563e281f22e82202a8ea5..44d4a985e969c1a57ad42d0666189c704aef9afd 100644
--- a/host/initramfs/shell.nix
+++ b/host/initramfs/shell.nix
@@ -4,6 +4,7 @@
import ../../lib/call-package.nix (
{ callSpectrumPackage, rootfs, pkgsStatic, stdenv
, cryptsetup, jq, qemu_kvm, tar2ext4, util-linux
+, config
}:

let
@@ -18,5 +19,6 @@ initramfs.overrideAttrs ({ nativeBuildInputs ? [], env ? {}, ... }: {
env = env // {
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
ROOT_FS = rootfs;
+ VERSION = config.version;
};
})) (_: {})
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 5e902552ae22af3a353b8cbc7430329ef3794c79..065722d48951a17182ed94e168796700652db7b9 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -98,8 +98,8 @@ clean:

build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/verity-timestamp $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
- $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)"):Spectrum_'$(VERSION).verity' \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))"):Spectrum_'$(VERSION)'
mv $@.tmp $@

debug:
diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
index 4bbbe23ff14a2c3337ec96b36c74c3aa6569f1d1..4fe9058abdfaa1df7d63b84a629708d4d99388f4 100644
--- a/host/rootfs/default.nix
+++ b/host/rootfs/default.nix
@@ -3,8 +3,8 @@
# SPDX-FileCopyrightText: 2022 Unikie

import ../../lib/call-package.nix (
-{ callSpectrumPackage, spectrum-build-tools, src
-, pkgsMusl, inkscape, linux_latest, xorg
+{ callSpectrumPackage, config, spectrum-build-tools
+, src, pkgsMusl, inkscape, linux_latest, xorg
}:
pkgsMusl.callPackage (

@@ -118,6 +118,7 @@ stdenvNoCC.mkDerivation {
printf "%s\n/\n" ${packagesSysroot} >$out
sed p ${writeClosure [ packagesSysroot] } >>$out
'';
+ VERSION = config.version;
};

# The Makefile uses $(ROOT_FS), not $(dest), so it can share code
diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
index 6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6..27f93e05fce036257d27cf9992fee8c925073f80 100644
--- a/host/rootfs/shell.nix
+++ b/host/rootfs/shell.nix
@@ -5,6 +5,7 @@
import ../../lib/call-package.nix (
{ callSpectrumPackage, rootfs, pkgsStatic, srcOnly, stdenv
, btrfs-progs, cryptsetup, jq, netcat, qemu_kvm, reuse, util-linux
+, config
}:

rootfs.overrideAttrs (
@@ -20,5 +21,6 @@ rootfs.overrideAttrs (
KERNEL = "${passthru.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
LINUX_SRC = srcOnly passthru.kernel.configfile;
VMLINUX = "${passthru.kernel.dev}/vmlinux";
+ VERSION = config.version;
};
})) (_: {})
diff --git a/lib/config.default.nix b/lib/config.default.nix
index a8422345cc00f9413bb19ec968fd89c82fed801b..489c231490a8b66aa01f50053b25646060f7f963 100644
--- a/lib/config.default.nix
+++ b/lib/config.default.nix
@@ -4,4 +4,5 @@
{
pkgsFun = import ./nixpkgs.default.nix;
pkgsArgs = {};
+ version = "0.0.0";
}
diff --git a/release/live/Makefile b/release/live/Makefile
index 7ec1bfe36e930ed68b97fdf2dcf3caa7274b1317..e856f4ccb841fd003d419955d79669fac2593cd6 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -10,8 +10,8 @@ dest = build/live.img
$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
build/boot.fat:c12a7328-f81f-11d2-ba4b-00a0c93ec93b \
- $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)"):Spectrum_'$(VERSION).verity' \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))"):Spectrum_'$(VERSION)'
mv $@.tmp $@

build/boot.fat: $(SYSTEMD_BOOT_EFI) $(SPECTRUM_EFI)
@@ -19,7 +19,7 @@ build/boot.fat: $(SYSTEMD_BOOT_EFI) $(SPECTRUM_EFI)
$(TRUNCATE) -s 440401920 $@
$(MKFS_FAT) $@
$(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
- $(MCOPY) -i $@ $(SPECTRUM_EFI) ::/EFI/Linux/spectrum.efi
+ $(MCOPY) -i $@ $(SPECTRUM_EFI) ::/EFI/Linux/'Spectrum_$(VERSION).efi'
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)

clean:
diff --git a/release/live/default.nix b/release/live/default.nix
index 3b5fa061a5c3a745cc88c3811a1229622ab140ad..aa8dddd68497ced322961a6b551b73fe5ab4c475 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -1,11 +1,13 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2023, 2025 Alyssa Ross <hi@alyssa.is>
# SPDX-FileCopyrightText: 2022 Unikie
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>

import ../../lib/call-package.nix (
{ callSpectrumPackage, spectrum-build-tools, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
+, config
}:

let
@@ -43,6 +45,7 @@ stdenv.mkDerivation {
SYSTEMD_BOOT_EFI = "${efi.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
SPECTRUM_EFI = efi;
EFINAME = "BOOT${toUpper efiArch}.EFI";
+ VERSION = config.version;
};

buildFlags = [ "dest=$(out)" ];
diff --git a/release/live/shell.nix b/release/live/shell.nix
index 79cfe3a267236bd91a73b2c07ee6e274a662a123..e542793a66fb972cfde90f6be2204986442b7d4b 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,8 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>

-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
+import ../../lib/call-package.nix (
+{ callSpectrumPackage, config, stdenv, qemu_kvm }:

let
efi = callSpectrumPackage ../../host/efi.nix {};
@@ -16,6 +17,7 @@ in
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
ROOT_FS = efi.rootfs;
EFI_IMAGE = efi;
+ VERSION = config.version;
};
}
)) (_: {})

--
2.52.0