Signed OS-dependent sysexts
Sign OS-dependent sysexts using an ephemeral key which is baked into the image.
The signed sysexts are generated using systemd-repart and they are built as a DDI with a dm-verity partition and signature partition.
TODO: determine if we enable the CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG in this PR or separate (@chewi was planning to use this for the kernel move, but the plans have shifted now).
How to use
Just enable any OS dependent sysexts, they should be verified using dm-verity has signature when loading.
Testing done
When you boot the built image, all OS-dependent sysexts (including OEM) should be signed. When booting, the systemd-sysext will merge them and verify the signature automatically. To merge again with explicitly stricter policy (which forces signed sysexts only), you can use the following command:
systemd-sysext refresh --image-policy="root=verity+signed+absent:usr=verity+signed+absent"
See related sysext-bakery PR#175
- [x] Changelog entries added in the respective
changelog/directory (user-facing change, bug fix, security fix, update) - [ ] Inspected CI output for image differences:
/bootand/usrsize, packages, list files for any missing binaries, kernel modules, config files, kernel modules, etc.
systemd-repart only gained the ability to apply compression to erofs in v257, but as far as I can tell, this is only configurable through the repart.d files, which aren't used when creating DDIs.
Actually, I got that slightly wrong. The files in /usr/lib/repart.d aren't used when creating a DDI, but the tool internally uses files from /usr/lib/systemd/repart/definitions. I think it might even pick up files from /etc/systemd/repart/definitions. It doesn't seem to be documented, but it looks like you could just add your own configuration here.
Test report for 4524.0.0+nightly-20251119-0830 / amd64 arm64
Platforms tested : qemu_uefi-amd64 qemu_update-amd64 qemu_uefi-arm64 qemu_update-arm64
bpf.execsnoop π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
bpf.local-gadget π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.basic π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.cloudinit.basic π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.cloudinit.multipart-mime π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.cloudinit.script π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.disk.raid0.data π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.disk.raid0.root π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.disk.raid1.data π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.disk.raid1.root π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.etcd-member.discovery π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.etcd-member.etcdctlv3 π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.etcd-member.v2-backup-restore π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.filesystem π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.flannel.udp π’ Succeeded: qemu_uefi-amd64 (1)
cl.flannel.vxlan π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.instantiated.enable-unit π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.kargs π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.luks π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.oem.indirect π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.oem.indirect.new π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.oem.regular π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.oem.regular.new π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.oem.reuse π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.oem.wipe π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.partition_on_boot_disk π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.symlink π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.translation π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v1.btrfsroot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v1.ext4root π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v1.groups π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v1.once π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v1.sethostname π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v1.users π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v1.xfsroot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v2.btrfsroot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v2.ext4root π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v2.users π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v2.xfsroot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v2_1.ext4checkexisting π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v2_1.swap π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.ignition.v2_1.vfat π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.install.cloudinit π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.internet π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.locksmith.cluster π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.network.initramfs.second-boot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.network.iptables π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.network.listeners π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.network.nftables π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.network.wireguard π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.omaha.ping π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.osreset.ignition-rerun π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.overlay.cleanup π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.swap_activation π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.sysext.boot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.sysext.fallbackdownload # SKIP π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.tang.nonroot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.tang.root π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.toolbox.dnf-install π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.tpm.eventlog π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.tpm.nonroot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.tpm.root π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.tpm.root-cryptenroll π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.tpm.root-cryptenroll-pcr-noupdate π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.tpm.root-cryptenroll-pcr-withupdate π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.update.badverity π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.update.payload π’ Succeeded: qemu_update-amd64 (1); qemu_update-arm64 (1)
cl.update.payload-boot-part-too-small π’ Succeeded: qemu_update-amd64 (1); qemu_update-arm64 (1)
cl.update.reboot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.users.shells π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
cl.verity π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.auth.verify π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.ignition.groups π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.ignition.once π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.ignition.resource.local π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.ignition.resource.remote π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.ignition.resource.s3.versioned π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.ignition.security.tls π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.ignition.sethostname π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.ignition.systemd.enable-service π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.locksmith.reboot π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.locksmith.tls π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.selinux.boolean π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.selinux.enforce π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
coreos.tls.fetch-urls π’ Succeeded: qemu_uefi-amd64 (2); qemu_uefi-arm64 (1) β Failed: qemu_uefi-amd64 (1)
Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Diagnostic output for qemu_uefi-amd64, run 1
L1: " Error: _cluster.go:125: curl: (35) Recv failure: Connection reset by peer"
L2: "cluster.go:145: __curl -s -S -m 30 --retry 2 https://start.fedoraproject.org/__ failed: output , status Process exited with status 35_"
L3: " "
L4: " "
coreos.update.badusr π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
devcontainer.docker π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
devcontainer.systemd-nspawn π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
docker.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
docker.btrfs-storage π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
docker.containerd-restart π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
docker.enable-service.sysext π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
docker.lib-coreos-dockerd-compat π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
docker.network-openbsd-nc π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
docker.selinux π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
docker.userns π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
extra-test.[first_dual].cl.update.docker-btrfs-compat π’ Succeeded: qemu_update-amd64 (1); qemu_update-arm64 (1)
extra-test.[first_dual].cl.update.payload π’ Succeeded: qemu_update-amd64 (1); qemu_update-arm64 (1)
extra-test.[first_dual].cl.update.payload-boot-part-too-small π’ Succeeded: qemu_update-amd64 (1); qemu_update-arm64 (1)
kubeadm.v1.32.4.calico.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
kubeadm.v1.32.4.cilium.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
kubeadm.v1.32.4.flannel.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
kubeadm.v1.33.0.calico.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
kubeadm.v1.33.0.cilium.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
kubeadm.v1.33.0.flannel.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
kubeadm.v1.34.1.calico.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
kubeadm.v1.34.1.cilium.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
kubeadm.v1.34.1.flannel.base π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
linux.nfs.v3 π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
linux.nfs.v4 π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
linux.ntp π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
misc.fips π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
packages π’ Succeeded: qemu_uefi-amd64 (2); qemu_uefi-arm64 (2) β Failed: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Diagnostic output for qemu_uefi-arm64, run 1
L1: " _packages/sys-block/open-iscsi (30.73s)"
L2: "cluster.go:125: Unable to find image _ghcr.io/flatcar/targetcli-fb:latest_ locally"
L3: "cluster.go:125: latest: Pulling from flatcar/targetcli-fb"
L4: "cluster.go:125: a2318d6c47ec: Pulling fs layer"
L5: "cluster.go:125: 3d3086a1439f: Pulling fs layer"
L6: "cluster.go:125: a2318d6c47ec: Verifying Checksum"
L7: "cluster.go:125: a2318d6c47ec: Download complete"
L8: "cluster.go:125: 3d3086a1439f: Verifying Checksum"
L9: "cluster.go:125: 3d3086a1439f: Download complete"
L10: "cluster.go:125: a2318d6c47ec: Pull complete"
L11: "cluster.go:125: 3d3086a1439f: Pull complete"
L12: "cluster.go:125: Digest: sha256:b6cd65db981974e8b74938617218dd023775b969f9a059ced21e6ce6fa4763c1"
L13: "cluster.go:125: Status: Downloaded newer image for ghcr.io/flatcar/targetcli-fb:latest"
L14: "cluster.go:125: mke2fs 1.47.3 (8-Jul-2025)"
L15: "cluster.go:125: Created symlink _/etc/systemd/system/remote-fs.target.wants/iscsi.service_ ??? _/usr/lib/systemd/system/iscsi.service_."
L16: "cluster.go:145: __sudo /check__ failed: output no /dev/sda device after reboot, status Process exited with status 1_"
L17: " "
L18: " _packages/sys-block/open-iscsi (39.54s)"
L19: "cluster.go:125: Unable to find image _ghcr.io/flatcar/targetcli-fb:latest_ locally"
L20: "cluster.go:125: latest: Pulling from flatcar/targetcli-fb"
L21: "cluster.go:125: 92c3b3500be6: Pulling fs layer"
L22: "cluster.go:125: 48bc879b34ee: Pulling fs layer"
L23: "cluster.go:125: 92c3b3500be6: Verifying Checksum"
L24: "cluster.go:125: 92c3b3500be6: Download complete"
L25: "cluster.go:125: 48bc879b34ee: Verifying Checksum"
L26: "cluster.go:125: 48bc879b34ee: Download complete"
L27: "cluster.go:125: 92c3b3500be6: Pull complete"
L28: "cluster.go:125: 48bc879b34ee: Pull complete"
L29: "cluster.go:125: Digest: sha256:b6cd65db981974e8b74938617218dd023775b969f9a059ced21e6ce6fa4763c1"
L30: "cluster.go:125: Status: Downloaded newer image for ghcr.io/flatcar/targetcli-fb:latest"
L31: "cluster.go:125: mke2fs 1.47.3 (8-Jul-2025)"
L32: "cluster.go:125: Created symlink _/etc/systemd/system/remote-fs.target.wants/iscsi.service_ ??? _/usr/lib/systemd/system/iscsi.service_."
L33: "cluster.go:145: __sudo /check__ failed: output no /dev/sda device after reboot, status Process exited with status 1_"
L34: " "
Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Diagnostic output for qemu_uefi-amd64, run 1
L1: " _packages/sys-block/open-iscsi (30.73s)"
L2: "cluster.go:125: Unable to find image _ghcr.io/flatcar/targetcli-fb:latest_ locally"
L3: "cluster.go:125: latest: Pulling from flatcar/targetcli-fb"
L4: "cluster.go:125: a2318d6c47ec: Pulling fs layer"
L5: "cluster.go:125: 3d3086a1439f: Pulling fs layer"
L6: "cluster.go:125: a2318d6c47ec: Verifying Checksum"
L7: "cluster.go:125: a2318d6c47ec: Download complete"
L8: "cluster.go:125: 3d3086a1439f: Verifying Checksum"
L9: "cluster.go:125: 3d3086a1439f: Download complete"
L10: "cluster.go:125: a2318d6c47ec: Pull complete"
L11: "cluster.go:125: 3d3086a1439f: Pull complete"
L12: "cluster.go:125: Digest: sha256:b6cd65db981974e8b74938617218dd023775b969f9a059ced21e6ce6fa4763c1"
L13: "cluster.go:125: Status: Downloaded newer image for ghcr.io/flatcar/targetcli-fb:latest"
L14: "cluster.go:125: mke2fs 1.47.3 (8-Jul-2025)"
L15: "cluster.go:125: Created symlink _/etc/systemd/system/remote-fs.target.wants/iscsi.service_ ??? _/usr/lib/systemd/system/iscsi.service_."
L16: "cluster.go:145: __sudo /check__ failed: output no /dev/sda device after reboot, status Process exited with status 1_"
L17: " "
L18: " _packages/sys-block/open-iscsi (39.54s)"
L19: "cluster.go:125: Unable to find image _ghcr.io/flatcar/targetcli-fb:latest_ locally"
L20: "cluster.go:125: latest: Pulling from flatcar/targetcli-fb"
L21: "cluster.go:125: 92c3b3500be6: Pulling fs layer"
L22: "cluster.go:125: 48bc879b34ee: Pulling fs layer"
L23: "cluster.go:125: 92c3b3500be6: Verifying Checksum"
L24: "cluster.go:125: 92c3b3500be6: Download complete"
L25: "cluster.go:125: 48bc879b34ee: Verifying Checksum"
L26: "cluster.go:125: 48bc879b34ee: Download complete"
L27: "cluster.go:125: 92c3b3500be6: Pull complete"
L28: "cluster.go:125: 48bc879b34ee: Pull complete"
L29: "cluster.go:125: Digest: sha256:b6cd65db981974e8b74938617218dd023775b969f9a059ced21e6ce6fa4763c1"
L30: "cluster.go:125: Status: Downloaded newer image for ghcr.io/flatcar/targetcli-fb:latest"
L31: "cluster.go:125: mke2fs 1.47.3 (8-Jul-2025)"
L32: "cluster.go:125: Created symlink _/etc/systemd/system/remote-fs.target.wants/iscsi.service_ ??? _/usr/lib/systemd/system/iscsi.service_."
L33: "cluster.go:145: __sudo /check__ failed: output no /dev/sda device after reboot, status Process exited with status 1_"
L34: " "
sysext.custom-docker.sysext π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
sysext.custom-oem π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
sysext.disable-containerd π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
sysext.disable-docker π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
sysext.simple π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
systemd.journal.remote π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
systemd.journal.user π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
systemd.sysusers.gshadow π’ Succeeded: qemu_uefi-amd64 (1); qemu_uefi-arm64 (1)
I've just tested using erofs compression and without (using SYSTEMD_REPART_MKFS_OPTIONS_EROFS="-zlz4hc,12 -C65536 -Efragments,ztailpacking"). There seems to be negligible (8MB difference), so I'm not sure if it's worth the double compression.
Uncompressed
flatcar_production_qemu_uefi_image.img 503M (526516224)
# df -h /usr/
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/usr 1016M 546M 331M 63% /usr
# btrfs filesystem usage /usr
Overall:
Device size: 1015.99MiB
Device allocated: 684.00MiB
Device unallocated: 331.99MiB
Device missing: 0.00B
Device slack: 0.00B
Used: 542.51MiB
Free (estimated): 466.62MiB (min: 466.62MiB)
Free (statfs, df): 330.94MiB
Data ratio: 1.00
Metadata ratio: 1.00
Global reserve: 2.87MiB (used: 0.00B)
Multiple profiles: no
Data+Metadata,single: Size:680.00MiB, Used:542.51MiB (79.78%)
/dev/mapper/usr 680.00MiB
System,single: Size:4.00MiB, Used:4.00KiB (0.10%)
/dev/mapper/usr 4.00MiB
Unallocated:
/dev/mapper/usr 331.99MiB
# ls -lah /usr/share/flatcar/sysext/
total 328M
drwxr-xr-x. 1 root root 80 Oct 23 13:44 .
drwxr-xr-x. 1 root root 166 Oct 23 13:47 ..
-rw-r--r--. 1 root root 156M Oct 23 13:44 containerd-flatcar.raw
-rw-r--r--. 1 root root 192M Oct 23 13:44 docker-flatcar.raw
Compressed
flatcar_production_qemu_uefi_image.img 500M (523436032)
# df -h /usr/
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/usr 1016M 538M 331M 62% /usr
# btrfs filesystem usage /usr
Overall:
Device size: 1015.99MiB
Device allocated: 684.00MiB
Device unallocated: 331.99MiB
Device missing: 0.00B
Device slack: 0.00B
Used: 534.66MiB
Free (estimated): 474.64MiB (min: 474.64MiB)
Free (statfs, df): 330.94MiB
Data ratio: 1.00
Metadata ratio: 1.00
Global reserve: 2.69MiB (used: 0.00B)
Multiple profiles: no
Data+Metadata,single: Size:680.00MiB, Used:534.66MiB (78.63%)
/dev/mapper/usr 680.00MiB
System,single: Size:4.00MiB, Used:4.00KiB (0.10%)
/dev/mapper/usr 4.00MiB
Unallocated:
/dev/mapper/usr 331.99MiB
# ls -lah /usr/share/flatcar/sysext/
total 150M
drwxr-xr-x. 1 root root 80 Oct 23 14:12 .
drwxr-xr-x. 1 root root 166 Oct 23 14:15 ..
-rw-r--r--. 1 root root 86M Oct 23 14:12 containerd-flatcar.raw
-rw-r--r--. 1 root root 85M Oct 23 14:12 docker-flatcar.raw
Interesting, thank you! I was just a little surprised by the results, as I thought plain zstd might come out smaller, but I discussed them with Copilot, and it thought they seemed legitimate. I fully agree that the double compression isn't worth it, especially when it only makes 3MB difference to the QCOW2.
I think, I've fixed most of the stuff now. To sum it up:
- we don't use FS compression for the built-in sysexts (they'll get compressed by btrfs when placed to the
/usrfilesystem) - switch format of the built-in sysexts from raw squashfs to DDI with erofs
- sign all sysexts with ephemeral key (available only during Flatcar build) and place the certificate in
/usr/lib/verity.d- NOTE: this uses userspace verification, this might cause futre problems if we decide to support IPE, so we might have to switch to baking the sysext key into kernel keyring and switch to kernel-space verification
- this PR doesn't add much security per se, as the content of
/usr, including the built-in sysext has already been verified using dm-verity- however, if even built-in sysexts are signed, it opens way to enforce signed-only policy system-wide (including bakery/custom sysexts)
- it pulls in three packages
erofs-utils,xxhash(dependency oferofs-utils) andvirtual/zlib(Gentoo switched to virtual package for zlib)
Can you start GitHub Actions and a Jenkins build (and link it in the PR description)? That would be nice for testing.
Just updated the changelog. The GH action finished successfully yesterday and passed all tests, feel free to grab the artifacts and test! I've just rebased the branch onto main, and I am re-running the tests as well as Jenkins job: http://jenkins.infra.kinvolk.io:8080/job/container/job/packages_all_arches/7008/