Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/spec/disk-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ The debootstrap must create the minimal viable bootable system.

r[image.base.machine-id]
`/etc/machine-id` must be truncated to zero bytes so that systemd generates a
unique machine ID on each first boot.
unique machine ID on each first boot. The image's initramfs must also carry an
uninitialized `/etc/machine-id` (zero bytes, or a string systemd recognises as
uninitialized such as the all-zeros UUID): if the initramfs ships a populated
value, systemd commits it to the root filesystem at switch-root, and every
install ends up with the same machine ID.

r[image.base.resolver]
systemd-resolved must be enabled and configured as the system DNS resolver.
Expand Down
11 changes: 11 additions & 0 deletions image/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,17 @@ if [ -z "$KVER" ]; then
fi
echo "Kernel version: $KVER"

# r[image.base.machine-id]
# dracut's 10systemd module copies /etc/machine-id verbatim into the
# initramfs. Truncating it earlier in this script is not enough: something
# between that truncate and this dracut invocation has been observed to
# repopulate the file (so every flashed install inherited the same UUID via
# systemd-machine-id-commit at switch-root). Force systemd's all-zeros
# "uninitialized" marker right here so the value baked into the initramfs is
# one systemd will regenerate per install at first boot. The post-chroot
# cleanup in build.sh truncates the rootfs copy back to zero bytes.
printf '%s\n' '00000000000000000000000000000000' > /etc/machine-id

# r[image.boot.dracut]
echo "Generating initramfs with dracut..."
dracut --force --kver "$KVER"
Expand Down
14 changes: 14 additions & 0 deletions tests/test-image-structure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,20 @@ check "image-variant contains '$VARIANT'" [ "$ACTUAL_VARIANT" = "$VARIANT" ]
MACHINE_ID_SIZE="$(stat -c%s "$MNT/etc/machine-id" 2>/dev/null || echo "missing")"
check "/etc/machine-id is empty (size=0)" [ "$MACHINE_ID_SIZE" = "0" ]

# A populated machine-id in the initramfs gets committed to the empty rootfs
# /etc/machine-id at switch-root, producing duplicate IDs across every flashed
# install. Empty bytes or systemd's all-zeros UUID both register as
# uninitialized and trigger regeneration on first boot.
INITRD_MID="$(chroot "$MNT" bash -c 'lsinitrd -f etc/machine-id /boot/initrd.img-* 2>/dev/null' | tr -d '[:space:]' || true)"
case "$INITRD_MID" in
"" | "00000000000000000000000000000000")
pass "initramfs /etc/machine-id is uninitialized"
;;
*)
fail "initramfs /etc/machine-id is uninitialized (got '$INITRD_MID')"
;;
esac

# r[verify image.hostname.metal-dhcp+2] r[verify image.hostname.cloud-default+2]
if [ "$VARIANT" = "metal" ] || [ "$VARIANT" = "pi" ]; then
HOSTNAME_SIZE="$(stat -c%s "$MNT/etc/hostname" 2>/dev/null || echo "missing")"
Expand Down