From bd93a93990bb84b5ea8f65ea4cfda67a2caf7eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Sun, 10 May 2026 19:04:30 +0200 Subject: [PATCH] config: use split CoCo image for runtime-rs, keep Go on monolithic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During the transition to composable (base + extension) CoCo images, run the two runtimes on different image layouts so CI exercises both paths via the existing qemu-{snp,tdx,coco-dev} (Go) and -runtime-rs (Rust) shims: - runtime-rs (Rust) CoCo templates use the standard base image plus a CoCo extension extra_image: image = "@IMAGEPATH@" (was @IMAGECONFIDENTIALPATH@) [[hypervisor.qemu.guest_extension_images]] name = "coco" path = "@COCOIMAGEPATH@" verity_params = "@COCOVERITYPARAMS@" COCOIMAGENAME/COCOIMAGEPATH/COCOVERITYPARAMS are added to the runtime-rs Makefile only. - runtime (Go) CoCo templates keep the monolithic confidential image (@IMAGECONFIDENTIALPATH@) and pull rootfs-image-confidential. shim-components.json reflects this: Go CoCo shims depend on rootfs-image-confidential while the runtime-rs CoCo shims depend on rootfs-image + rootfs-image-coco-extension. shim-v2/build.sh feeds each runtime its own dm-verity params: Rust gets the measured base image hash (@KERNELVERITYPARAMS@) plus the extension hash (@COCOVERITYPARAMS@); Go gets the monolithic confidential image hash (@KERNELVERITYPARAMS@). This is wired per make invocation so the same @KERNELVERITYPARAMS@ placeholder resolves correctly for each. Once the split path is validated we can flip the Go templates too and drop the monolithic confidential image. Signed-off-by: Fabiano FidĂȘncio Assisted-by: Cursor --- src/runtime-rs/Makefile | 6 ++ ...iguration-qemu-coco-dev-runtime-rs.toml.in | 7 ++- .../configuration-qemu-snp-runtime-rs.toml.in | 7 ++- .../configuration-qemu-tdx-runtime-rs.toml.in | 7 ++- .../kata-deploy/shim-components.json | 10 ++-- tools/packaging/static-build/shim-v2/build.sh | 55 +++++++++++++------ 6 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/runtime-rs/Makefile b/src/runtime-rs/Makefile index 06103856cd..160e8ae953 100644 --- a/src/runtime-rs/Makefile +++ b/src/runtime-rs/Makefile @@ -105,6 +105,9 @@ PKGRUNDIR := $(LOCALSTATEDIR)/run/$(PROJECT_DIR) KERNELDIR := $(PKGDATADIR) IMAGEPATH := $(PKGDATADIR)/$(IMAGENAME) IMAGECONFIDENTIALPATH := $(PKGDATADIR)/$(IMAGECONFIDENTIALNAME) +COCOIMAGENAME := $(PROJECT_TAG)-coco-extension.img +COCOIMAGEPATH := $(PKGDATADIR)/$(COCOIMAGENAME) +COCOVERITYPARAMS := INITRDPATH := $(PKGDATADIR)/$(INITRDNAME) INITRDCONFIDENTIALPATH := $(PKGDATADIR)/$(INITRDCONFIDENTIALNAME) @@ -645,6 +648,9 @@ USER_VARS += IMAGEPATH USER_VARS += IMAGEPATH_CLH_AZURE USER_VARS += IMAGEPATH_NV USER_VARS += IMAGECONFIDENTIALPATH +USER_VARS += COCOIMAGENAME +USER_VARS += COCOIMAGEPATH +USER_VARS += COCOVERITYPARAMS USER_VARS += INITRDNAME USER_VARS += INITRDCONFIDENTIALNAME USER_VARS += INITRDPATH diff --git a/src/runtime-rs/config/configuration-qemu-coco-dev-runtime-rs.toml.in b/src/runtime-rs/config/configuration-qemu-coco-dev-runtime-rs.toml.in index 3f543f76e4..1324d911e4 100644 --- a/src/runtime-rs/config/configuration-qemu-coco-dev-runtime-rs.toml.in +++ b/src/runtime-rs/config/configuration-qemu-coco-dev-runtime-rs.toml.in @@ -15,7 +15,7 @@ [hypervisor.qemu] path = "@QEMUPATH@" kernel = "@KERNELPATH_COCO@" -image = "@IMAGECONFIDENTIALPATH@" +image = "@IMAGEPATH@" machine_type = "@MACHINETYPE@" # rootfs filesystem type: @@ -733,3 +733,8 @@ enable_pprof = false # to the hypervisor. # (default: /run/kata-containers/dans) dan_conf = "@DEFDANCONF@" + +[[hypervisor.qemu.guest_extension_images]] +name = "coco" +path = "@COCOIMAGEPATH@" +verity_params = "@COCOVERITYPARAMS@" diff --git a/src/runtime-rs/config/configuration-qemu-snp-runtime-rs.toml.in b/src/runtime-rs/config/configuration-qemu-snp-runtime-rs.toml.in index 796872c72f..5f280243df 100644 --- a/src/runtime-rs/config/configuration-qemu-snp-runtime-rs.toml.in +++ b/src/runtime-rs/config/configuration-qemu-snp-runtime-rs.toml.in @@ -16,7 +16,7 @@ [hypervisor.qemu] path = "@QEMUPATH@" kernel = "@KERNELPATH_COCO@" -image = "@IMAGECONFIDENTIALPATH@" +image = "@IMAGEPATH@" machine_type = "@MACHINETYPE@" # Enable confidential guest support. @@ -755,3 +755,8 @@ enable_pprof = false # to the hypervisor. # (default: /run/kata-containers/dans) dan_conf = "@DEFDANCONF@" + +[[hypervisor.qemu.guest_extension_images]] +name = "coco" +path = "@COCOIMAGEPATH@" +verity_params = "@COCOVERITYPARAMS@" diff --git a/src/runtime-rs/config/configuration-qemu-tdx-runtime-rs.toml.in b/src/runtime-rs/config/configuration-qemu-tdx-runtime-rs.toml.in index 15a07a014b..667d698846 100644 --- a/src/runtime-rs/config/configuration-qemu-tdx-runtime-rs.toml.in +++ b/src/runtime-rs/config/configuration-qemu-tdx-runtime-rs.toml.in @@ -15,7 +15,7 @@ [hypervisor.qemu] path = "@QEMUPATH@" kernel = "@KERNELPATH_COCO@" -image = "@IMAGECONFIDENTIALPATH@" +image = "@IMAGEPATH@" # initrd = "@INITRDPATH@" machine_type = "@MACHINETYPE@" # Set to 0 to use Unix Domain Socket (/var/run/tdx-qgs/qgs.socket) instead of vsock. @@ -733,3 +733,8 @@ enable_pprof = false # to the hypervisor. # (default: /run/kata-containers/dans) dan_conf = "@DEFDANCONF@" + +[[hypervisor.qemu.guest_extension_images]] +name = "coco" +path = "@COCOIMAGEPATH@" +verity_params = "@COCOVERITYPARAMS@" diff --git a/tools/packaging/kata-deploy/shim-components.json b/tools/packaging/kata-deploy/shim-components.json index 322047a429..7573cd1557 100644 --- a/tools/packaging/kata-deploy/shim-components.json +++ b/tools/packaging/kata-deploy/shim-components.json @@ -19,13 +19,13 @@ "x86_64": ["shim-v2-go", "qemu-snp-experimental", "kernel", "rootfs-image-confidential", "ovmf-sev"] }, "qemu-snp-runtime-rs": { - "x86_64": ["shim-v2-rust", "qemu-snp-experimental", "kernel", "rootfs-image-confidential", "ovmf-sev"] + "x86_64": ["shim-v2-rust", "qemu-snp-experimental", "kernel", "rootfs-image", "rootfs-image-coco-extension", "ovmf-sev"] }, "qemu-tdx": { "x86_64": ["shim-v2-go", "qemu-tdx-experimental", "kernel", "rootfs-image-confidential", "ovmf-tdx"] }, "qemu-tdx-runtime-rs": { - "x86_64": ["shim-v2-rust", "qemu-tdx-experimental", "virtiofsd", "kernel", "rootfs-image-confidential", "ovmf-tdx"] + "x86_64": ["shim-v2-rust", "qemu-tdx-experimental", "virtiofsd", "kernel", "rootfs-image", "rootfs-image-coco-extension", "ovmf-tdx"] }, "qemu-se": { "s390x": ["shim-v2-go", "qemu", "virtiofsd", "kernel", "rootfs-initrd-confidential", "boot-image-se"] @@ -56,9 +56,9 @@ "s390x": ["shim-v2-go", "qemu", "kernel", "rootfs-image-confidential"] }, "qemu-coco-dev-runtime-rs": { - "x86_64": ["shim-v2-rust", "qemu", "kernel", "kernel-debug", "rootfs-image-confidential"], - "aarch64": ["shim-v2-rust", "qemu", "kernel", "kernel-debug", "rootfs-image-confidential", "ovmf"], - "s390x": ["shim-v2-rust", "qemu", "kernel", "rootfs-image-confidential"] + "x86_64": ["shim-v2-rust", "qemu", "kernel", "kernel-debug", "rootfs-image", "rootfs-image-coco-extension"], + "aarch64": ["shim-v2-rust", "qemu", "kernel", "kernel-debug", "rootfs-image", "rootfs-image-coco-extension", "ovmf"], + "s390x": ["shim-v2-rust", "qemu", "kernel", "rootfs-image", "rootfs-image-coco-extension"] }, "clh": { "x86_64": ["shim-v2-go", "cloud-hypervisor", "virtiofsd", "nydus", "kernel", "kernel-debug", "rootfs-image", "rootfs-initrd"], diff --git a/tools/packaging/static-build/shim-v2/build.sh b/tools/packaging/static-build/shim-v2/build.sh index 5650a0002f..2c8fb5633b 100755 --- a/tools/packaging/static-build/shim-v2/build.sh +++ b/tools/packaging/static-build/shim-v2/build.sh @@ -42,30 +42,51 @@ esac [[ "${CROSS_BUILD}" == "true" ]] && container_image_bk="${container_image}" && container_image="${container_image}-cross-build" # Variants (targets) that build a measured rootfs as of now are: -# - rootfs-image-confidential +# - rootfs-image (the base image, measured; root hash labelled "base") +# - rootfs-image-confidential (monolithic CoCo image, root hash "confidential") +# - rootfs-image-coco-extension # - rootfs-image-nvidia-gpu # - rootfs-image-nvidia-gpu-confidential # +# The CoCo configs come in two flavours during the transition to split images: +# - runtime-rs (Rust) uses the split layout: the measured base image +# (@KERNELVERITYPARAMS@) plus the CoCo extension (@COCOVERITYPARAMS@). +# - runtime (Go) still uses the monolithic confidential image, whose dm-verity +# hash is carried by @KERNELVERITYPARAMS@. +# Because the two runtimes are built in separate `make` invocations, each gets +# its own @KERNELVERITYPARAMS@ value (base hash for Rust, confidential hash for +# Go). The NVIDIA GPU verity params are shared by both runtimes. +# # shellcheck disable=SC2154 root_hash_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build" -verity_variants=( - "confidential:KERNELVERITYPARAMS" - "nvidia-gpu:KERNELVERITYPARAMS_NV" - "nvidia-gpu-confidential:KERNELVERITYPARAMS_CONFIDENTIAL_NV" -) -for entry in "${verity_variants[@]}"; do - variant="${entry%%:*}" - param_var="${entry#*:}" - root_hash_file="${root_hash_dir}/root_hash_${variant}.txt" - [[ -f "${root_hash_file}" ]] || continue + +# read_verity_param +# Emits " VAR=value" if the matching root_hash_.txt exists, else nothing. +read_verity_param() { + local variant="$1" + local param_var="$2" + local root_hash_file="${root_hash_dir}/root_hash_${variant}.txt" + [[ -f "${root_hash_file}" ]] || return 0 # root_hash_*.txt contains a single kernel_verity_params line. + local root_measure_config IFS= read -r root_measure_config < "${root_hash_file}" root_measure_config="${root_measure_config%$'\r'}" [[ -n "${root_measure_config}" ]] || die "Empty kernel verity params in ${root_hash_file}" - EXTRA_OPTS+=" ${param_var}=${root_measure_config}" -done + printf ' %s=%s' "${param_var}" "${root_measure_config}" +} + +# Shared by both runtimes (NVIDIA GPU variants). +EXTRA_OPTS+="$(read_verity_param "nvidia-gpu" "KERNELVERITYPARAMS_NV")" +EXTRA_OPTS+="$(read_verity_param "nvidia-gpu-confidential" "KERNELVERITYPARAMS_CONFIDENTIAL_NV")" + +# runtime-rs (Rust): split image -> base hash + CoCo extension hash. +RUST_EXTRA_OPTS="$(read_verity_param "base" "KERNELVERITYPARAMS")" +RUST_EXTRA_OPTS+="$(read_verity_param "coco-extension" "COCOVERITYPARAMS")" + +# runtime (Go): monolithic confidential image -> confidential hash. +GO_EXTRA_OPTS="$(read_verity_param "confidential" "KERNELVERITYPARAMS")" # shellcheck disable=SC2154,SC2086 docker pull "${container_image}" || \ @@ -95,7 +116,7 @@ case "${RUNTIME_CHOICE}" in -w "${repo_root_dir}/src/runtime-rs" \ --user "$(id -u)":"$(id -g)" \ "${container_image}" \ - bash -c "make clean-generated-files && make PREFIX=${PREFIX} QEMUCMD=qemu-system-${arch} ${EXTRA_OPTS}" + bash -c "make clean-generated-files && make PREFIX=${PREFIX} QEMUCMD=qemu-system-${arch} ${EXTRA_OPTS}${RUST_EXTRA_OPTS}" docker run --rm -i -v "${repo_root_dir}:${repo_root_dir}" \ --env CROSS_BUILD="${CROSS_BUILD}" \ @@ -104,7 +125,7 @@ case "${RUNTIME_CHOICE}" in -w "${repo_root_dir}/src/runtime-rs" \ --user "$(id -u)":"$(id -g)" \ "${container_image}" \ - bash -c "make PREFIX='${PREFIX}' DESTDIR='${DESTDIR}' ${EXTRA_OPTS} install" + bash -c "make PREFIX='${PREFIX}' DESTDIR='${DESTDIR}' ${EXTRA_OPTS}${RUST_EXTRA_OPTS} install" ;; esac @@ -117,14 +138,14 @@ case "${RUNTIME_CHOICE}" in --user "$(id -u)":"$(id -g)" \ --env GOMODCACHE=/opt/.cache/gomod \ "${container_image}" \ - bash -c "make clean-generated-files && make PREFIX=${PREFIX} QEMUCMD=qemu-system-${arch} ${EXTRA_OPTS}" + bash -c "make clean-generated-files && make PREFIX=${PREFIX} QEMUCMD=qemu-system-${arch} ${EXTRA_OPTS}${GO_EXTRA_OPTS}" docker run --rm -i -v "${repo_root_dir}:${repo_root_dir}" \ -w "${repo_root_dir}/src/runtime" \ --user "$(id -u)":"$(id -g)" \ --env GOMODCACHE=/opt/.cache/gomod \ "${container_image}" \ - bash -c "make PREFIX='${PREFIX}' DESTDIR='${DESTDIR}' ${EXTRA_OPTS} install" + bash -c "make PREFIX='${PREFIX}' DESTDIR='${DESTDIR}' ${EXTRA_OPTS}${GO_EXTRA_OPTS} install" ;; esac