split out hash because rocky doesnt support it inline
This commit is contained in:
@@ -4,9 +4,9 @@
|
||||
# Pulls the diskless deliverables out of the Packer-built disk image:
|
||||
# vmlinuz -> HTTPS boot server
|
||||
# initramfs.img -> HTTPS boot server (the fleet-generic image)
|
||||
# rootfs.erofs -> nvmet target: shared READ-ONLY NVMe/TCP namespace
|
||||
# (erofs data + dm-verity hash tree appended in-file)
|
||||
# verity.json -> root hash + hash offset (feeds the kernel cmdline)
|
||||
# rootfs.erofs -> nvmet target: READ-ONLY NVMe/TCP DATA namespace (erofs)
|
||||
# rootfs.hash -> nvmet target: READ-ONLY NVMe/TCP dm-verity HASH namespace
|
||||
# verity.json -> root hash + data/hash namespace UUIDs (feed the cmdline)
|
||||
# cmdline.txt -> ready-made kernel cmdline fragment for this build
|
||||
#
|
||||
# Requires on the build host: libguestfs-tools, erofs-utils (mkfs.erofs),
|
||||
@@ -23,14 +23,19 @@ DISABLE_DOT1X=${3:-false}
|
||||
# environments. Defaults to the literal placeholder so build-oci.sh's warning
|
||||
# fires if it was never set.
|
||||
NVMET_TRADDR=${NVMET_TRADDR:-NVMET_TRADDR}
|
||||
# Stable root-namespace UUID. The root device is referenced by-id
|
||||
# (/dev/disk/by-id/nvme-uuid.$ROOT_NS_UUID) rather than /dev/nvmeNn1 because
|
||||
# NVMe controller indices are NOT stable: a transient discovery controller can
|
||||
# take nvme0, pushing the I/O controller to nvme1, so a hardcoded node is a
|
||||
# latent brick in an immutable signed cmdline. MUST match ROOT_NS_UUID in
|
||||
# serving/spdk-setup.sh (which assigns it on the target via add_ns -u).
|
||||
ROOT_NS_UUID=${ROOT_NS_UUID:-f1ee7000-0000-4000-8000-000000000001}
|
||||
ROOT_DEV="/dev/disk/by-id/nvme-uuid.${ROOT_NS_UUID}"
|
||||
# Stable namespace UUIDs. Devices are referenced by-id
|
||||
# (/dev/disk/by-id/nvme-uuid.<uuid>) rather than /dev/nvmeNnM because NVMe
|
||||
# controller/namespace indices are NOT stable (a transient discovery controller
|
||||
# can shift them), so a hardcoded node is a latent brick in an immutable signed
|
||||
# cmdline. dm-verity needs TWO namespaces — erofs DATA and the verity HASH tree
|
||||
# — because this distro's systemd-veritysetup does not support the in-file
|
||||
# hash-offset layout (it ignores hash-offset= and fails to load the superblock).
|
||||
# MUST match ROOT_DATA_UUID / ROOT_HASH_UUID in serving/spdk-setup.sh (assigned
|
||||
# on the target via add_ns -u).
|
||||
ROOT_DATA_UUID=${ROOT_DATA_UUID:-f1ee7000-0000-4000-8000-000000000001}
|
||||
ROOT_HASH_UUID=${ROOT_HASH_UUID:-f1ee7000-0000-4000-8000-000000000002}
|
||||
ROOT_DATA_DEV="/dev/disk/by-id/nvme-uuid.${ROOT_DATA_UUID}"
|
||||
ROOT_HASH_DEV="/dev/disk/by-id/nvme-uuid.${ROOT_HASH_UUID}"
|
||||
|
||||
for bin in virt-copy-out virt-tar-out virt-ls mkfs.erofs veritysetup jq; do
|
||||
command -v "$bin" >/dev/null || { echo "ERROR: $bin not found on build host" >&2; exit 1; }
|
||||
@@ -69,21 +74,24 @@ FIXED_UUID="6c10a7f0-1d2e-4f5a-9b3c-000000000001"
|
||||
mkfs.erofs -T 0 -U "$FIXED_UUID" --all-root \
|
||||
"$WORK/rootfs.erofs" "$WORK/root"
|
||||
|
||||
echo "==> Appending dm-verity hash tree (single-file / single-namespace layout)"
|
||||
DATA_BYTES=$(stat -c %s "$WORK/rootfs.erofs")
|
||||
# Align hash area to 4 KiB after the data
|
||||
HASH_OFFSET=$(( (DATA_BYTES + 4095) / 4096 * 4096 ))
|
||||
VERITY_OUT=$(veritysetup format "$WORK/rootfs.erofs" "$WORK/rootfs.erofs" \
|
||||
--hash-offset="$HASH_OFFSET" \
|
||||
echo "==> Generating dm-verity hash tree as a SEPARATE file (two-namespace layout)"
|
||||
# Hash tree in its OWN file (served as a 2nd namespace), NOT appended in-file:
|
||||
# this distro's systemd-veritysetup ignores hash-offset= ("unknown option") and
|
||||
# fails to load the verity superblock. With separate data/hash devices the
|
||||
# cmdline needs no offset. Deterministic for identical input trees (fixed erofs
|
||||
# UUID + -T0 => stable data => stable hash tree => stable root hash).
|
||||
VERITY_OUT=$(veritysetup format "$WORK/rootfs.erofs" "$WORK/rootfs.hash" \
|
||||
--data-block-size=4096 --hash-block-size=4096)
|
||||
ROOT_HASH=$(printf '%s\n' "$VERITY_OUT" | awk '/Root hash:/ {print $3}')
|
||||
[ -n "$ROOT_HASH" ] || { echo "ERROR: veritysetup produced no root hash" >&2; exit 1; }
|
||||
|
||||
mv "$WORK/rootfs.erofs" "$OUT/rootfs.erofs"
|
||||
mv "$WORK/rootfs.hash" "$OUT/rootfs.hash"
|
||||
|
||||
jq -n --arg hash "$ROOT_HASH" --argjson offset "$HASH_OFFSET" \
|
||||
--arg uuid "$FIXED_UUID" \
|
||||
'{root_hash: $hash, hash_offset: $offset, erofs_uuid: $uuid,
|
||||
jq -n --arg hash "$ROOT_HASH" --arg erofs_uuid "$FIXED_UUID" \
|
||||
--arg data_uuid "$ROOT_DATA_UUID" --arg hash_uuid "$ROOT_HASH_UUID" \
|
||||
'{root_hash: $hash, erofs_uuid: $erofs_uuid,
|
||||
data_ns_uuid: $data_uuid, hash_ns_uuid: $hash_uuid,
|
||||
data_block_size: 4096, hash_block_size: 4096}' \
|
||||
> "$OUT/verity.json"
|
||||
|
||||
@@ -110,21 +118,20 @@ printf '%s' \
|
||||
"rd.nvmf.discover=tcp,${NVMET_TRADDR},4420 " \
|
||||
"root=/dev/mapper/root rootfstype=erofs rootflags=ro " \
|
||||
"systemd.verity=yes roothash=${ROOT_HASH} " \
|
||||
"systemd.verity_root_data=${ROOT_DEV} " \
|
||||
"systemd.verity_root_hash=${ROOT_DEV} " \
|
||||
"systemd.verity_root_options=hash-offset=${HASH_OFFSET}" \
|
||||
"systemd.verity_root_data=${ROOT_DATA_DEV} " \
|
||||
"systemd.verity_root_hash=${ROOT_HASH_DEV}" \
|
||||
> "$OUT/cmdline.txt"
|
||||
|
||||
echo "==> Checksums"
|
||||
( cd "$OUT" && sha256sum vmlinuz initramfs.img rootfs.erofs | tee SHA256SUMS )
|
||||
( cd "$OUT" && sha256sum vmlinuz initramfs.img rootfs.erofs rootfs.hash | tee SHA256SUMS )
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Artifacts in $OUT:
|
||||
vmlinuz, initramfs.img -> publish to the HTTPS boot server (versioned dir,
|
||||
flip a symlink for atomic rollout/rollback)
|
||||
rootfs.erofs -> expose as a READ-ONLY nvmet namespace; version
|
||||
rollout = publish new namespace, repoint hosts
|
||||
rootfs.erofs -> expose as a READ-ONLY nvmet DATA namespace
|
||||
rootfs.hash -> expose as a READ-ONLY nvmet HASH namespace (verity)
|
||||
cmdline.txt -> kernel cmdline for this build. The roothash binds
|
||||
the root fs to the boot artifacts: serve via a
|
||||
signed UKI or signed GRUB config so Secure Boot
|
||||
|
||||
Reference in New Issue
Block a user