build: add CoCo addon image build and remove CoCo deps from confidential image

Add install_image_coco_addon() to kata-deploy-binaries.sh which:
- Unpacks the CoCo guest components and pause image tarballs into a
  temporary rootfs directory (under the repo root so Docker-in-Docker
  volume mounts resolve correctly)
- Calls image_builder.sh with USE_DOCKER=1, FS_TYPE=erofs,
  MEASURED_ROOTFS=yes, SKIP_DAX_HEADER=yes, and SKIP_ROOTFS_CHECK=yes
  to produce kata-containers-coco-addon.img + root_hash_coco-addon.txt

Add the rootfs-image-coco-addon-tarball Makefile target with
dependencies on pause-image-tarball and coco-guest-components-tarball.

Remove pause-image-tarball and coco-guest-components-tarball from the
standard confidential image dependencies -- those components now live
exclusively in the CoCo addon image.  NVIDIA confidential images
retain them until the NVIDIA addon split lands.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Fabiano Fidêncio
2026-05-10 19:05:04 +02:00
parent 41361ce93e
commit ed769282ca
4 changed files with 146 additions and 20 deletions

View File

@@ -11,11 +11,11 @@ OS_NAME=ubuntu
# This should be Ubuntu's code name, e.g. "focal" (Focal Fossa) for 20.04
OS_VERSION=${OS_VERSION:-""}
[[ -z "${OS_VERSION}" ]] && echo "OS_VERSION is required, but was not set" && exit 1
PACKAGES="chrony iptables dbus"
PACKAGES="chrony iptables dbus cryptsetup-bin"
# shellcheck disable=SC2154
[[ "${AGENT_INIT}" = no ]] && PACKAGES+=" init"
# CDH secure storage feature requires these tools in the guest
[[ "${CONFIDENTIAL_GUEST:-no}" = "yes" ]] && PACKAGES+=" cryptsetup-bin e2fsprogs"
[[ "${CONFIDENTIAL_GUEST:-no}" = "yes" ]] && PACKAGES+=" e2fsprogs"
# shellcheck disable=SC2154
[[ "${SECCOMP}" = yes ]] && PACKAGES+=" libseccomp2"
[[ "$(uname -m)" = "s390x" ]] && PACKAGES+=" libcurl4 libnghttp2-14"

View File

@@ -75,8 +75,17 @@ build_image() {
info "Build image"
info "image os: ${os_name}"
info "image os version: ${os_version}"
# The label used for BUILD_VARIANT (and therefore the emitted
# root_hash_<variant>.txt file) is normally the image filename suffix.
# The base image, however, has an empty suffix (it is shipped as
# kata-containers.img) yet may still be built measured. Callers can set
# ROOT_HASH_VARIANT to give that measured base a dedicated root-hash label
# (e.g. "base") without changing the image filename.
local build_variant="${ROOT_HASH_VARIANT:-${image_initrd_suffix}}"
make image \
BUILD_VARIANT="${image_initrd_suffix}" \
BUILD_VARIANT="${build_variant}" \
DISTRO="${os_name}" \
DEBUG="${DEBUG:-}" \
USE_DOCKER="1" \
@@ -94,9 +103,9 @@ build_image() {
fi
mv -f "kata-containers.img" "${install_dir}/${artifact_name}"
if [[ -e "root_hash_${image_initrd_suffix}.txt" ]]; then
info "Copying root hash file for variant: ${image_initrd_suffix} ${PWD}"
cp "root_hash_${image_initrd_suffix}.txt" "${install_dir}/"
if [[ -e "root_hash_${build_variant}.txt" ]]; then
info "Copying root hash file for variant: ${build_variant} ${PWD}"
cp "root_hash_${build_variant}.txt" "${install_dir}/"
fi
(
cd "${install_dir}"

View File

@@ -37,6 +37,7 @@ BASE_TARBALLS = serial-targets \
virtiofsd-tarball
BASE_SERIAL_TARBALLS = rootfs-image-tarball \
rootfs-image-confidential-tarball \
rootfs-image-coco-addon-tarball \
rootfs-image-mariner-tarball \
rootfs-initrd-confidential-tarball \
rootfs-initrd-tarball \
@@ -50,6 +51,7 @@ BASE_TARBALLS = serial-targets \
shim-v2-rust-tarball \
virtiofsd-tarball
BASE_SERIAL_TARBALLS = rootfs-image-tarball \
rootfs-image-coco-addon-tarball \
rootfs-initrd-tarball
else ifeq ($(ARCH), aarch64)
BASE_TARBALLS = serial-targets \
@@ -63,6 +65,7 @@ BASE_TARBALLS = serial-targets \
virtiofsd-tarball
BASE_SERIAL_TARBALLS = rootfs-image-tarball \
rootfs-image-confidential-tarball \
rootfs-image-coco-addon-tarball \
rootfs-cca-confidential-image-tarball \
rootfs-cca-confidential-initrd-tarball \
rootfs-initrd-tarball
@@ -268,10 +271,14 @@ DEPS := agent-tarball
rootfs-image-tarball: $(DEPS)
${MAKE} $@-build
DEPS := agent-tarball pause-image-tarball coco-guest-components-tarball kernel-tarball
DEPS := agent-tarball kernel-tarball
rootfs-image-confidential-tarball: $(DEPS)
${MAKE} $@-build
DEPS := pause-image-tarball coco-guest-components-tarball
rootfs-image-coco-addon-tarball: $(DEPS)
${MAKE} $@-build
DEPS := agent-tarball
rootfs-image-mariner-tarball: $(DEPS)
${MAKE} $@-build

View File

@@ -135,6 +135,7 @@ options:
stratovirt
rootfs-image
rootfs-image-confidential
rootfs-image-coco-addon
rootfs-image-mariner
rootfs-initrd
rootfs-initrd-confidential
@@ -187,7 +188,7 @@ cleanup_and_fail_shim_v2_specifics() {
local extra_tarballs="${3:-}"
local tarball_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build"
for variant in confidential nvidia-gpu nvidia-gpu-confidential; do
for variant in base confidential coco-addon nvidia-gpu nvidia-gpu-confidential; do
local root_hash_file="${tarball_dir}/${component}-root_hash_${variant}.txt"
[[ -f "${root_hash_file}" ]] && rm -f "${root_hash_file}"
done
@@ -217,8 +218,15 @@ install_cached_shim_v2_tarball_get_root_hash() {
local tarball_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build"
local root_hash_basedir="./opt/kata/share/kata-containers/"
for variant in confidential nvidia-gpu nvidia-gpu-confidential; do
local image_conf_tarball="kata-static-rootfs-image-${variant}.tar.zst"
for variant in base confidential coco-addon nvidia-gpu nvidia-gpu-confidential; do
# The measured base image ships as kata-static-rootfs-image.tar.zst
# (no variant suffix), but carries its root hash under the "base" label.
local image_conf_tarball
if [[ "${variant}" == "base" ]]; then
image_conf_tarball="kata-static-rootfs-image.tar.zst"
else
image_conf_tarball="kata-static-rootfs-image-${variant}.tar.zst"
fi
local tarball_path="${tarball_dir}/${image_conf_tarball}"
local root_hash_path="${root_hash_basedir}root_hash_${variant}.txt"
@@ -238,7 +246,7 @@ install_cached_shim_v2_tarball_compare_root_hashes() {
local found_any=""
local tarball_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build"
for variant in confidential nvidia-gpu nvidia-gpu-confidential; do
for variant in base confidential coco-addon nvidia-gpu nvidia-gpu-confidential; do
local image_root_hash="${tarball_dir}/root_hash_${variant}.txt"
local cached_root_hash="${component}-root_hash_${variant}.txt"
@@ -453,12 +461,11 @@ install_image() {
latest_artefact+="-$(get_latest_nvidia_ctk_version)"
latest_artefact+="-$(get_latest_nvidia_nvrc_version)"
latest_artefact+="-$(get_latest_nvidia_nvat_version)"
latest_artefact+="-$(get_latest_coco_guest_components_artefact_and_builder_image_version)"
latest_artefact+="-$(get_latest_pause_image_artefact_and_builder_image_version)"
else
latest_artefact+="-$(get_latest_kernel_artefact_and_builder_image_version)"
fi
latest_artefact+="-$(get_latest_coco_guest_components_artefact_and_builder_image_version)"
latest_artefact+="-$(get_latest_pause_image_artefact_and_builder_image_version)"
fi
if [[ "${variant}" == "nvidia-gpu" ]]; then
@@ -469,6 +476,19 @@ install_image() {
latest_artefact+="-$(get_latest_nvidia_nvrc_version)"
fi
# The base guest image (empty variant) is built as a measured rootfs so
# that confidential configurations can dm-verity-protect it; non-confidential
# configurations simply boot its data partition unverified. Reflect the
# measured build (and the kernel it is tied to, since measured boot depends
# on it) in the cache key, and emit the root hash under a dedicated "base"
# label so it never collides with the legacy confidential image hash.
local root_hash_variant="${variant}"
if [[ -z "${variant}" && "${MEASURED_ROOTFS:-no}" == "yes" ]]; then
root_hash_variant="base"
latest_artefact+="-measured-$(get_latest_kernel_artefact_and_builder_image_version)"
fi
export ROOT_HASH_VARIANT="${root_hash_variant}"
latest_builder_image=""
install_cached_tarball_component \
@@ -482,7 +502,11 @@ install_image() {
info "Create image"
if [[ -n "${variant}" ]]; then
if [[ "${variant}" == *confidential ]]; then
# NVIDIA confidential images still bake CoCo components into the
# rootfs (until the NVIDIA addon split lands). Standard
# confidential images no longer need them -- CoCo components are
# built as a separate addon image (rootfs-image-coco-addon).
if [[ "${variant}" == "nvidia-gpu-confidential" ]]; then
COCO_GUEST_COMPONENTS_TARBALL="$(get_coco_guest_components_tarball_path)"
export COCO_GUEST_COMPONENTS_TARBALL
PAUSE_IMAGE_TARBALL="$(get_pause_image_tarball_path)"
@@ -518,7 +542,29 @@ install_image() {
"${rootfs_builder}" --osname="${os_name}" --osversion="${os_version}" --imagetype=image --prefix="${prefix}" --destdir="${destdir}" --image_initrd_suffix="${variant}"
}
#Install the base guest image
#
# The base image (kata-containers.img) is shared by both non-confidential and
# confidential configurations. It is built once as a measured rootfs (dm-verity
# hash partition + root hash emitted under the "base" label). Confidential
# configurations enforce that hash via the kernel command line, while
# non-confidential configurations ignore it and boot the data partition
# directly. Measured rootfs is not used on s390x (Secure Execution measures the
# guest through a different mechanism), so the base stays unmeasured there.
install_image_base() {
if [[ "${ARCH}" == "s390x" ]]; then
export MEASURED_ROOTFS="no"
else
export MEASURED_ROOTFS="yes"
fi
install_image
}
#Install guest image for confidential guests
#
# CoCo guest components are no longer baked into this image.
# They are built separately as a CoCo addon image
# (rootfs-image-coco-addon) and attached as an extra block device.
install_image_confidential() {
export CONFIDENTIAL_GUEST="yes"
if [[ "${ARCH}" == "s390x" ]]; then
@@ -529,6 +575,64 @@ install_image_confidential() {
install_image "confidential"
}
#Install CoCo addon image (erofs+verity, contains CoCo guest components + pause)
install_image_coco_addon() {
local component="rootfs-image-coco-addon"
local coco_last_commit
coco_last_commit="$(get_latest_coco_guest_components_artefact_and_builder_image_version)"
local pause_last_commit
pause_last_commit="$(get_latest_pause_image_artefact_and_builder_image_version)"
latest_artefact="$(get_kata_version)-coco-addon-${coco_last_commit}-${pause_last_commit}"
latest_builder_image=""
install_cached_tarball_component \
"${component}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "Create CoCo addon image"
# Use a temp dir under the repo root so the path is valid both inside
# the outer build-kata-deploy container and in the nested image-builder
# container (Docker-in-Docker mounts use host paths).
local addon_rootfs
addon_rootfs="$(mktemp -d "${repo_root_dir}/.coco-addon-rootfs.XXXX")"
COCO_GUEST_COMPONENTS_TARBALL="$(get_coco_guest_components_tarball_path)"
PAUSE_IMAGE_TARBALL="$(get_pause_image_tarball_path)"
info "Unpacking CoCo guest components into addon rootfs"
tar --zstd -xvf "${COCO_GUEST_COMPONENTS_TARBALL}" -C "${addon_rootfs}"
info "Unpacking pause image into addon rootfs"
tar --zstd -xvf "${PAUSE_IMAGE_TARBALL}" -C "${addon_rootfs}"
local install_dir="${destdir}/${prefix}/share/kata-containers/"
mkdir -p "${install_dir}"
local image_builder="${repo_root_dir}/tools/osbuilder/image-builder/image_builder.sh"
export USE_DOCKER="1"
export BUILD_VARIANT="coco-addon"
export FS_TYPE="erofs"
export MEASURED_ROOTFS="yes"
export SKIP_DAX_HEADER="yes"
export SKIP_ROOTFS_CHECK="yes"
"${image_builder}" -o "${install_dir}/kata-containers-coco-addon.img" "${addon_rootfs}"
if [[ -e "${install_dir}/root_hash_coco-addon.txt" ]]; then
info "Root hash file: ${install_dir}/root_hash_coco-addon.txt"
fi
rm -rf "${addon_rootfs}"
}
#Install cbl-mariner guest image
install_image_mariner() {
export IMAGE_SIZE_ALIGNMENT_MB=2
@@ -1054,9 +1158,13 @@ install_nydus() {
# Shared helper: extract measured-rootfs root hashes from confidential image tarballs.
# These are needed by the Rust runtime (runtime-rs) at build time for dm-verity.
_collect_root_hashes() {
for variant in confidential nvidia-gpu nvidia-gpu-confidential; do
for variant in base confidential coco-addon nvidia-gpu nvidia-gpu-confidential; do
# The measured base image ships as kata-static-rootfs-image.tar.zst
# (no variant suffix), but carries its root hash under the "base" label.
local tarball_glob="kata-static-rootfs-image-${variant}.tar.zst"
[[ "${variant}" == "base" ]] && tarball_glob="kata-static-rootfs-image.tar.zst"
local image_conf_tarball
image_conf_tarball="$(find "${workdir}" -maxdepth 1 -name "kata-static-rootfs-image-${variant}.tar.zst" 2>/dev/null | head -n 1)"
image_conf_tarball="$(find "${workdir}" -maxdepth 1 -name "${tarball_glob}" 2>/dev/null | head -n 1)"
# Only one variant may be built at a time so we need to
# skip one or the other if not available.
[[ -f "${image_conf_tarball}" ]] || continue
@@ -1498,10 +1606,12 @@ handle_build() {
stratovirt) install_stratovirt ;;
rootfs-image) install_image ;;
rootfs-image) install_image_base ;;
rootfs-image-confidential) install_image_confidential ;;
rootfs-image-coco-addon) install_image_coco_addon ;;
rootfs-image-mariner) install_image_mariner ;;
rootfs-initrd) install_initrd ;;
@@ -1571,7 +1681,7 @@ handle_build() {
;;
shim-v2-go|shim-v2-rust)
if [[ "${MEASURED_ROOTFS}" == "yes" ]]; then
for variant in confidential nvidia-gpu nvidia-gpu-confidential; do
for variant in base confidential coco-addon nvidia-gpu nvidia-gpu-confidential; do
[[ -f "${workdir}/root_hash_${variant}.txt" ]] && mv "${workdir}/root_hash_${variant}.txt" "${workdir}/${build_target}-root_hash_${variant}.txt"
done
fi
@@ -1640,7 +1750,7 @@ handle_build() {
shim-v2-go|shim-v2-rust)
if [[ "${MEASURED_ROOTFS}" == "yes" ]]; then
local found_any=""
for variant in confidential nvidia-gpu nvidia-gpu-confidential; do
for variant in base confidential coco-addon nvidia-gpu nvidia-gpu-confidential; do
# The variants could be built independently we need to check if
# they exist and then push them to the registry
[[ -f "${workdir}/${build_target}-root_hash_${variant}.txt" ]] && files_to_push+=("${build_target}-root_hash_${variant}.txt") && found_any="yes"