kata-containers/tools/packaging/kata-deploy/local-build/kata-deploy-binaries.sh
Beraldo Leal c99ba42d62 deps: bumping yq to v4.40.7
Since yq frequently updates, let's upgrade to a version from February to
bypass potential issues with versions 4.41-4.43 for now. We can always
upgrade to the newest version if necessary.

Fixes #9354
Depends-on:github.com/kata-containers/tests#5818

Signed-off-by: Beraldo Leal <bleal@redhat.com>
2024-05-31 13:28:34 -04:00

1298 lines
38 KiB
Bash
Executable File

#!/usr/bin/env bash
# Copyright (c) 2018-2021 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
[ -z "${DEBUG}" ] || set -x
set -o errexit
set -o nounset
set -o pipefail
set -o errtrace
readonly project="kata-containers"
readonly script_name="$(basename "${BASH_SOURCE[0]}")"
readonly script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${script_dir}/../../scripts/lib.sh"
readonly prefix="/opt/kata"
readonly static_build_dir="${repo_root_dir}/tools/packaging/static-build"
readonly version_file="${repo_root_dir}/VERSION"
readonly versions_yaml="${repo_root_dir}/versions.yaml"
readonly agent_builder="${static_build_dir}/agent/build.sh"
readonly coco_guest_components_builder="${static_build_dir}/coco-guest-components/build.sh"
readonly clh_builder="${static_build_dir}/cloud-hypervisor/build-static-clh.sh"
readonly firecracker_builder="${static_build_dir}/firecracker/build-static-firecracker.sh"
readonly kernel_builder="${static_build_dir}/kernel/build.sh"
readonly ovmf_builder="${static_build_dir}/ovmf/build.sh"
readonly pause_image_builder="${static_build_dir}/pause-image/build.sh"
readonly qemu_builder="${static_build_dir}/qemu/build-static-qemu.sh"
readonly qemu_experimental_builder="${static_build_dir}/qemu/build-static-qemu-experimental.sh"
readonly stratovirt_builder="${static_build_dir}/stratovirt/build-static-stratovirt.sh"
readonly shimv2_builder="${static_build_dir}/shim-v2/build.sh"
readonly virtiofsd_builder="${static_build_dir}/virtiofsd/build.sh"
readonly nydus_builder="${static_build_dir}/nydus/build.sh"
readonly rootfs_builder="${repo_root_dir}/tools/packaging/guest-image/build_image.sh"
readonly tools_builder="${static_build_dir}/tools/build.sh"
readonly se_image_builder="${repo_root_dir}/tools/packaging/guest-image/build_se_image.sh"
ARCH=${ARCH:-$(uname -m)}
MEASURED_ROOTFS=${MEASURED_ROOTFS:-no}
PULL_TYPE=${PULL_TYPE:-default}
USE_CACHE="${USE_CACHE:-"yes"}"
ARTEFACT_REGISTRY="${ARTEFACT_REGISTRY:-ghcr.io}"
ARTEFACT_REPOSITORY="${ARTEFACT_REPOSITORY:-kata-containers}"
ARTEFACT_REGISTRY_USERNAME="${ARTEFACT_REGISTRY_USERNAME:-}"
ARTEFACT_REGISTRY_PASSWORD="${ARTEFACT_REGISTRY_PASSWORD:-}"
TARGET_BRANCH="${TARGET_BRANCH:-main}"
PUSH_TO_REGISTRY="${PUSH_TO_REGISTRY:-}"
KERNEL_HEADERS_PKG_TYPE="${KERNEL_HEADERS_PKG_TYPE:-deb}"
RELEASE="${RELEASE:-"no"}"
workdir="${WORKDIR:-$PWD}"
destdir="${workdir}/kata-static"
default_binary_permissions='0744'
die() {
msg="$*"
echo "ERROR: ${msg}" >&2
exit 1
}
info() {
echo "INFO: $*"
}
error() {
echo "ERROR: $*"
}
usage() {
return_code=${1:-0}
cat <<EOF
This script is used as part of the ${project} release process.
It is used to create a tarball with static binaries.
Usage:
${script_name} <options> [version]
Args:
version: The kata version that will be use to create the tarball
options:
-h|--help : Show this help
-s : Silent mode (produce output in case of failure only)
--build=<asset> :
all
agent
agent-ctl
boot-image-se
coco-guest-components
cloud-hypervisor
cloud-hypervisor-glibc
firecracker
genpolicy
kata-ctl
kata-manager
kernel
kernel-confidential
kernel-dragonball-experimental
kernel-experimental
kernel-nvidia-gpu
kernel-nvidia-gpu-confidential
nydus
pause-image
ovmf
ovmf-sev
qemu
qemu-snp-experimental
stratovirt
rootfs-image
rootfs-image-confidential
rootfs-initrd
rootfs-initrd-confidential
rootfs-initrd-mariner
runk
shim-v2
trace-forwarder
virtiofsd
EOF
exit "${return_code}"
}
get_kernel_headers_dir() {
local kernel_name"=${1:-}"
[ -z "${kernel_name}" ] && die "kernel name is a required argument"
local kernel_headers_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build/${kernel_name}/builddir"
echo "${kernel_headers_dir}"
}
get_kernel_modules_dir() {
local kernel_version="${1:-}"
local kernel_kata_config_version="${2:-}"
local kernel_name"=${3:-}"
[ -z "${kernel_version}" ] && die "kernel version is a required argument"
[ -z "${kernel_kata_config_version}" ] && die "kernel kata config version is a required argument"
[ -z "${kernel_name}" ] && die "kernel name is a required argument"
local version=${kernel_version#v}
local numeric_final_version=${version}
# Every first release of a kernel is x.y, while the resulting folder would be x.y.0
local dots=$(echo ${version} | grep -o '\.' | wc -l)
[ "${dots}" == "1" ] && numeric_final_version="${version}.0"
local kernel_modules_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build/${kernel_name}/builddir/kata-linux-${version}-${kernel_kata_config_version}/lib/modules/${numeric_final_version}"
case ${kernel_name} in
kernel-nvidia-gpu-confidential)
kernel_modules_dir+="-nvidia-gpu-confidential"
;;
*)
;;
esac
echo ${kernel_modules_dir}
}
cleanup_and_fail() {
local component_tarball_name="${1:-}"
local extra_tarballs="${2:-}"
rm -f "${component_tarball_name}"
if [ -n "${extra_tarballs}" ]; then
local mapping
IFS=' ' read -a mapping <<< "${extra_tarballs}"
for m in ${mapping[@]}; do
local extra_tarball_name=${m%:*}
rm -f "${extra_tarball_name}"
done
fi
return 1
}
install_cached_tarball_component() {
if [ "${USE_CACHE}" != "yes" ]; then
return 1
fi
local component="${1}"
local current_version="${2}-$(git log -1 --abbrev=9 --pretty=format:"%h" ${repo_root_dir}/tools/packaging/kata-deploy/local-build)"
local current_image_version="${3}"
local component_tarball_name="${4}"
local component_tarball_path="${5}"
# extra_tarballs must be in the following format:
# "tarball1_name:tarball1_path tarball2_name:tarball2_path ... tarballN_name:tarballN_path"
local extra_tarballs="${6:-}"
oras pull ${ARTEFACT_REGISTRY}/${ARTEFACT_REPOSITORY}/cached-artefacts/${build_target}:latest-${TARGET_BRANCH}-$(uname -m) || return 1
cached_version="$(cat ${component}-version)"
cached_image_version="$(cat ${component}-builder-image-version)"
rm -f ${component}-version
rm -f ${component}-builder-image-version
[ "${cached_image_version}" != "${current_image_version}" ] && return 1
[ "${cached_version}" != "${current_version}" ] && return 1
sha256sum -c "${component}-sha256sum" || return $(cleanup_and_fail "${component_tarball_path}" "${extra_tarballs}")
info "Using cached tarball of ${component}"
mv "${component_tarball_name}" "${component_tarball_path}"
[ -z "${extra_tarballs}" ] && return 0
local mapping
IFS=' ' read -a mapping <<< "${extra_tarballs}"
for m in ${mapping[@]}; do
local extra_tarball_name=${m%:*}
local extra_tarball_path=${m#*:}
mv ${extra_tarball_name} ${extra_tarball_path}
done
}
get_agent_tarball_path() {
agent_local_build_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build"
agent_tarball_name="kata-static-agent.tar.xz"
echo "${agent_local_build_dir}/${agent_tarball_name}"
}
get_coco_guest_components_tarball_path() {
coco_guest_components_local_build_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build"
coco_guest_components_tarball_name="kata-static-coco-guest-components.tar.xz"
echo "${coco_guest_components_local_build_dir}/${coco_guest_components_tarball_name}"
}
get_latest_coco_guest_components_artefact_and_builder_image_version() {
local coco_guest_components_version=$(get_from_kata_deps ".externals.coco-guest-components.version")
local coco_guest_components_toolchain=$(get_from_kata_deps ".externals.coco-guest-components.toolchain")
local latest_coco_guest_components_artefact="${coco_guest_components_version}-${coco_guest_components_toolchain}"
local latest_coco_guest_components_builder_image="$(get_coco_guest_components_image_name)"
echo "${latest_coco_guest_components_artefact}-${latest_coco_guest_components_builder_image}"
}
get_pause_image_tarball_path() {
pause_image_local_build_dir="${repo_root_dir}/tools/packaging/kata-deploy/local-build/build"
pause_image_tarball_name="kata-static-pause-image.tar.xz"
echo "${pause_image_local_build_dir}/${pause_image_tarball_name}"
}
get_latest_pause_image_artefact_and_builder_image_version() {
local pause_image_repo="$(get_from_kata_deps ".externals.pause.repo")"
local pause_image_version=$(get_from_kata_deps ".externals.pause.version")
local latest_pause_image_artefact="${pause_image_repo}-${pause_image_version}"
local latest_pause_image_builder_image="$(get_pause_image_name)"
echo "${latest_pause_image_artefact}-${latest_pause_image_builder_image}"
}
get_latest_kernel_confidential_artefact_and_builder_image_version() {
local kernel_version=$(get_from_kata_deps ".assets.kernel.confidential.version")
local kernel_kata_config_version="$(cat ${repo_root_dir}/tools/packaging/kernel/kata_config_version)"
local latest_kernel_artefact="${kernel_version}-${kernel_kata_config_version}-$(get_last_modification $(dirname $kernel_builder))"
local latest_kernel_builder_image="$(get_kernel_image_name)"
echo "${latest_kernel_artefact}-${latest_kernel_builder_image}"
}
#Install guest image
install_image() {
local variant="${1:-}"
image_type="image"
if [ -n "${variant}" ]; then
image_type+="-${variant}"
fi
local component="rootfs-${image_type}"
local osbuilder_last_commit="$(get_last_modification "${repo_root_dir}/tools/osbuilder")"
local guest_image_last_commit="$(get_last_modification "${repo_root_dir}/tools/packaging/guest-image")"
local libs_last_commit="$(get_last_modification "${repo_root_dir}/src/libs")"
local gperf_version="$(get_from_kata_deps ".externals.gperf.version")"
local libseccomp_version="$(get_from_kata_deps ".externals.libseccomp.version")"
local rust_version="$(get_from_kata_deps ".languages.rust.meta.newest-version")"
local agent_last_commit=$(merge_two_hashes \
"$(get_last_modification "${repo_root_dir}/src/agent")" \
"$(get_last_modification "${repo_root_dir}/tools/packaging/static-build/agent")")
latest_artefact="${osbuilder_last_commit}-${guest_image_last_commit}-${agent_last_commit}-${libs_last_commit}-${gperf_version}-${libseccomp_version}-${rust_version}-${image_type}"
if [ "${variant}" == "confidential" ]; then
# For the confidential image we depend on the kernel built in order to ensure that
# measured boot is used
latest_artefacts+="-$(get_latest_kernel_confidential_artefact_and_builder_image_version)"
latest_artefacts+="-$(get_latest_coco_guest_components_artefact_and_builder_image_version)"
latest_artefacts+="-$(get_latest_pause_image_artefact_and_builder_image_version)"
fi
latest_builder_image=""
install_cached_tarball_component \
"${component}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "Create image"
if [ -n "${variant}" ]; then
os_name="$(get_from_kata_deps ".assets.image.architecture.${ARCH}.${variant}.name")"
os_version="$(get_from_kata_deps ".assets.image.architecture.${ARCH}.${variant}.version")"
if [ "${variant}" == "confidential" ]; then
export COCO_GUEST_COMPONENTS_TARBALL="$(get_coco_guest_components_tarball_path)"
export PAUSE_IMAGE_TARBALL="$(get_pause_image_tarball_path)"
fi
else
os_name="$(get_from_kata_deps ".assets.image.architecture.${ARCH}.name")"
os_version="$(get_from_kata_deps ".assets.image.architecture.${ARCH}.version")"
fi
export AGENT_TARBALL=$(get_agent_tarball_path)
export AGENT_POLICY=yes
"${rootfs_builder}" --osname="${os_name}" --osversion="${os_version}" --imagetype=image --prefix="${prefix}" --destdir="${destdir}" --image_initrd_suffix="${variant}"
}
#Install guest image for confidential guests
install_image_confidential() {
export MEASURED_ROOTFS=yes
export PULL_TYPE=default
install_image "confidential"
}
#Install guest initrd
install_initrd() {
local variant="${1:-}"
initrd_type="initrd"
if [ -n "${variant}" ]; then
initrd_type+="-${variant}"
fi
local component="rootfs-${initrd_type}"
local osbuilder_last_commit="$(get_last_modification "${repo_root_dir}/tools/osbuilder")"
local guest_image_last_commit="$(get_last_modification "${repo_root_dir}/tools/packaging/guest-image")"
local libs_last_commit="$(get_last_modification "${repo_root_dir}/src/libs")"
local gperf_version="$(get_from_kata_deps ".externals.gperf.version")"
local libseccomp_version="$(get_from_kata_deps ".externals.libseccomp.version")"
local rust_version="$(get_from_kata_deps ".languages.rust.meta.newest-version")"
local agent_last_commit=$(merge_two_hashes \
"$(get_last_modification "${repo_root_dir}/src/agent")" \
"$(get_last_modification "${repo_root_dir}/tools/packaging/static-build/agent")")
latest_artefact="${osbuilder_last_commit}-${guest_image_last_commit}-${agent_last_commit}-${libs_last_commit}-${gperf_version}-${libseccomp_version}-${rust_version}-${initrd_type}"
if [ "${variant}" == "confidential" ]; then
# For the confidential initrd we depend on the kernel built in order to ensure that
# measured boot is used
latest_artefacts+="-$(get_latest_kernel_confidential_artefact_and_builder_image_version)"
latest_artefacts+="-$(get_latest_coco_guest_components_artefact_and_builder_image_version)"
latest_artefacts+="-$(get_latest_pause_image_artefact_and_builder_image_version)"
fi
latest_builder_image=""
[[ "${ARCH}" == "aarch64" && "${CROSS_BUILD}" == "true" ]] && echo "warning: Don't cross build initrd for aarch64 as it's too slow" && exit 0
install_cached_tarball_component \
"${component}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "Create initrd"
if [ -n "${variant}" ]; then
os_name="$(get_from_kata_deps ".assets.initrd.architecture.${ARCH}.${variant}.name")"
os_version="$(get_from_kata_deps ".assets.initrd.architecture.${ARCH}.${variant}.version")"
if [ "${variant}" == "confidential" ]; then
export COCO_GUEST_COMPONENTS_TARBALL="$(get_coco_guest_components_tarball_path)"
export PAUSE_IMAGE_TARBALL="$(get_pause_image_tarball_path)"
fi
else
os_name="$(get_from_kata_deps ".assets.initrd.architecture.${ARCH}.name")"
os_version="$(get_from_kata_deps ".assets.initrd.architecture.${ARCH}.version")"
fi
export AGENT_TARBALL=$(get_agent_tarball_path)
export AGENT_POLICY=yes
"${rootfs_builder}" --osname="${os_name}" --osversion="${os_version}" --imagetype=initrd --prefix="${prefix}" --destdir="${destdir}" --image_initrd_suffix="${variant}"
}
#Install guest initrd for confidential guests
install_initrd_confidential() {
export MEASURED_ROOTFS=yes
export PULL_TYPE=default
install_initrd "confidential"
}
#Install Mariner guest initrd
install_initrd_mariner() {
install_initrd "mariner"
}
#Instal NVIDIA GPU image
install_image_nvidia_gpu() {
export AGENT_POLICY="yes"
export AGENT_INIT="yes"
export EXTRA_PKGS="apt udev"
install_image "nvidia-gpu"
}
#Install NVIDIA GPU initrd
install_initrd_nvidia_gpu() {
export AGENT_POLICY="yes"
export AGENT_INIT="yes"
export EXTRA_PKGS="apt udev"
install_initrd "nvidia-gpu"
}
#Instal NVIDIA GPU confidential image
install_image_nvidia_gpu_confidential() {
export AGENT_POLICY="yes"
export AGENT_INIT="yes"
export EXTRA_PKGS="apt udev"
install_image "nvidia-gpu-confidential"
}
#Install NVIDIA GPU confidential initrd
install_initrd_nvidia_gpu_confidential() {
export AGENT_POLICY="yes"
export AGENT_INIT="yes"
export EXTRA_PKGS="apt udev"
install_initrd "nvidia-gpu-confidential"
}
install_se_image() {
info "Create IBM SE image configured with AA_KBC=${AA_KBC}"
"${se_image_builder}" --destdir="${destdir}"
}
#Install kernel component helper
install_cached_kernel_tarball_component() {
local kernel_name=${1}
local extra_tarballs="${2:-}"
latest_artefact="${kernel_version}-${kernel_kata_config_version}-$(get_last_modification $(dirname $kernel_builder))"
latest_builder_image="$(get_kernel_image_name)"
install_cached_tarball_component \
"${kernel_name}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
"${extra_tarballs}" \
|| return 1
case ${kernel_name} in
"kernel-nvidia-gpu"*"")
local kernel_headers_dir=$(get_kernel_headers_dir "${kernel_name}")
mkdir -p ${kernel_headers_dir} || true
tar xvf ${workdir}/${kernel_name}/builddir/kata-static-${kernel_name}-headers.tar.xz -C "${kernel_headers_dir}" || return 1
;;& # fallthrough in the confidential case we need the modules.tar.xz and for every kernel-nvidia-gpu we need the headers
"kernel"*"-confidential")
local modules_dir=$(get_kernel_modules_dir ${kernel_version} ${kernel_kata_config_version} ${build_target})
mkdir -p "${modules_dir}" || true
tar xvf "${workdir}/kata-static-${kernel_name}-modules.tar.xz" -C "${modules_dir}" || return 1
;;
esac
return 0
}
#Install kernel asset
install_kernel_helper() {
local kernel_version_yaml_path="${1}"
local kernel_name="${2}"
local extra_cmd="${3:-}"
local extra_tarballs=""
export kernel_version="$(get_from_kata_deps .${kernel_version_yaml_path})"
export kernel_kata_config_version="$(cat ${repo_root_dir}/tools/packaging/kernel/kata_config_version)"
if [[ "${kernel_name}" == "kernel"*"-confidential" ]]; then
kernel_version="$(get_from_kata_deps .assets.kernel.confidential.version)"
fi
if [[ "${kernel_name}" == "kernel"*"-confidential" ]]; then
local kernel_modules_tarball_name="kata-static-${kernel_name}-modules.tar.xz"
local kernel_modules_tarball_path="${workdir}/${kernel_modules_tarball_name}"
extra_tarballs="${kernel_modules_tarball_name}:${kernel_modules_tarball_path}"
fi
if [[ "${kernel_name}" == "kernel-nvidia-gpu*" ]]; then
local kernel_headers_tarball_name="kata-static-${kernel_name}-headers.tar.xz"
local kernel_headers_tarball_path="${workdir}/${kernel_headers_tarball_name}"
extra_tarballs+=" ${kernel_headers_tarball_name}:${kernel_headers_tarball_path}"
fi
default_patches_dir="${repo_root_dir}/tools/packaging/kernel/patches"
install_cached_kernel_tarball_component ${kernel_name} ${extra_tarballs} && return 0
info "build ${kernel_name}"
info "Kernel version ${kernel_version}"
DESTDIR="${destdir}" PREFIX="${prefix}" "${kernel_builder}" -v "${kernel_version}" ${extra_cmd}
}
#Install kernel asset
install_kernel() {
install_kernel_helper \
"assets.kernel.version" \
"kernel" \
"-f"
}
install_kernel_confidential() {
local kernel_url="$(get_from_kata_deps .assets.kernel.confidential.url)"
export MEASURED_ROOTFS=yes
install_kernel_helper \
"assets.kernel.confidential.version" \
"kernel-confidential" \
"-x -u ${kernel_url}"
}
install_kernel_dragonball_experimental() {
install_kernel_helper \
"assets.kernel-dragonball-experimental.version" \
"kernel-dragonball-experimental" \
"-e -t dragonball"
}
#Install GPU enabled kernel asset
install_kernel_nvidia_gpu() {
local kernel_url="$(get_from_kata_deps .assets.kernel.url)"
install_kernel_helper \
"assets.kernel.version" \
"kernel-nvidia-gpu" \
"-g nvidia -u ${kernel_url} -H deb"
}
#Install GPU and TEE enabled kernel asset
install_kernel_nvidia_gpu_confidential() {
local kernel_url="$(get_from_kata_deps .assets.kernel.confidential.url)"
install_kernel_helper \
"assets.kernel.confidential.version" \
"kernel-nvidia-gpu-confidential" \
"-x -g nvidia -u ${kernel_url} -H deb"
}
install_qemu_helper() {
local qemu_repo_yaml_path="${1}"
local qemu_version_yaml_path="${2}"
local qemu_name="${3}"
local builder="${4}"
local qemu_tarball_name="${qemu_tarball_name:-kata-static-qemu.tar.gz}"
export qemu_repo="$(get_from_kata_deps .${qemu_repo_yaml_path})"
export qemu_version="$(get_from_kata_deps .${qemu_version_yaml_path})"
latest_artefact="${qemu_version}-$(calc_qemu_files_sha256sum)"
latest_builder_image="$(get_qemu_image_name)"
install_cached_tarball_component \
"${qemu_name}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static ${qemu_name}"
"${builder}"
tar xvf "${qemu_tarball_name}" -C "${destdir}"
}
# Install static qemu asset
install_qemu() {
install_qemu_helper \
"assets.hypervisor.qemu.url" \
"assets.hypervisor.qemu.version" \
"qemu" \
"${qemu_builder}"
}
install_qemu_snp_experimental() {
export qemu_suffix="snp-experimental"
export qemu_tarball_name="kata-static-qemu-${qemu_suffix}.tar.gz"
install_qemu_helper \
"assets.hypervisor.qemu-${qemu_suffix}.url" \
"assets.hypervisor.qemu-${qemu_suffix}.tag" \
"qemu-${qemu_suffix}" \
"${qemu_experimental_builder}"
}
# Install static firecracker asset
install_firecracker() {
local firecracker_version=$(get_from_kata_deps ".assets.hypervisor.firecracker.version")
latest_artefact="${firecracker_version}"
latest_builder_image=""
install_cached_tarball_component \
"firecracker" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static firecracker"
"${firecracker_builder}"
info "Install static firecracker"
mkdir -p "${destdir}/opt/kata/bin/"
install -D --mode "$default_binary_permissions" release-${firecracker_version}-${ARCH}/firecracker-${firecracker_version}-${ARCH} "${destdir}/opt/kata/bin/firecracker"
install -D --mode "$default_binary_permissions" release-${firecracker_version}-${ARCH}/jailer-${firecracker_version}-${ARCH} "${destdir}/opt/kata/bin/jailer"
}
install_clh_helper() {
libc="${1}"
features="${2}"
suffix="${3:-""}"
latest_artefact="$(get_from_kata_deps ".assets.hypervisor.cloud_hypervisor.version")"
latest_builder_image=""
install_cached_tarball_component \
"cloud-hypervisor${suffix}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static cloud-hypervisor"
libc="${libc}" features="${features}" "${clh_builder}"
info "Install static cloud-hypervisor"
mkdir -p "${destdir}/opt/kata/bin/"
install -D --mode "$default_binary_permissions" cloud-hypervisor/cloud-hypervisor "${destdir}/opt/kata/bin/cloud-hypervisor${suffix}"
}
# Install static cloud-hypervisor asset
install_clh() {
if [[ "${ARCH}" == "x86_64" ]]; then
features="mshv,tdx"
else
features=""
fi
install_clh_helper "musl" "${features}"
}
# Install static cloud-hypervisor-glibc asset
install_clh_glibc() {
if [[ "${ARCH}" == "x86_64" ]]; then
features="mshv"
else
features=""
fi
install_clh_helper "gnu" "${features}" "-glibc"
}
# Install static stratovirt asset
install_stratovirt() {
local stratovirt_version=$(get_from_kata_deps ".assets.hypervisor.stratovirt.version")
latest_artefact="${stratovirt_version}"
latest_builder_image=""
install_cached_tarball_component \
"stratovirt" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static stratovirt"
"${stratovirt_builder}"
info "Install static stratovirt"
mkdir -p "${destdir}/opt/kata/bin/"
install -D --mode "$default_binary_permissions" static-stratovirt/stratovirt "${destdir}/opt/kata/bin/stratovirt"
}
# Install static virtiofsd asset
install_virtiofsd() {
latest_artefact="$(get_from_kata_deps ".externals.virtiofsd.version")-$(get_from_kata_deps ".externals.virtiofsd.toolchain")"
latest_builder_image="$(get_virtiofsd_image_name)"
install_cached_tarball_component \
"virtiofsd" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static virtiofsd"
"${virtiofsd_builder}"
info "Install static virtiofsd"
mkdir -p "${destdir}/opt/kata/libexec/"
install -D --mode "$default_binary_permissions" virtiofsd/virtiofsd "${destdir}/opt/kata/libexec/virtiofsd"
}
# Install static nydus asset
install_nydus() {
[ "${ARCH}" == "aarch64" ] && ARCH=arm64
latest_artefact="$(get_from_kata_deps ".externals.nydus.version")"
latest_builder_image=""
install_cached_tarball_component \
"nydus" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static nydus"
"${nydus_builder}"
info "Install static nydus"
mkdir -p "${destdir}/opt/kata/libexec/"
ls -tl . || true
ls -tl nydus-static || true
install -D --mode "$default_binary_permissions" nydus-static/nydusd "${destdir}/opt/kata/libexec/nydusd"
}
#Install all components that are not assets
install_shimv2() {
local shim_v2_last_commit="$(get_last_modification "${repo_root_dir}/src/runtime")"
local runtime_rs_last_commit="$(get_last_modification "${repo_root_dir}/src/runtime-rs")"
local protocols_last_commit="$(get_last_modification "${repo_root_dir}/src/libs/protocols")"
local GO_VERSION="$(get_from_kata_deps ".languages.golang.meta.newest-version")"
local RUST_VERSION="$(get_from_kata_deps ".languages.rust.meta.newest-version")"
latest_artefact="${shim_v2_last_commit}-${protocols_last_commit}-${runtime_rs_last_commit}-${GO_VERSION}-${RUST_VERSION}"
latest_builder_image="$(get_shim_v2_image_name)"
install_cached_tarball_component \
"shim-v2" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
export GO_VERSION
export RUST_VERSION
DESTDIR="${destdir}" PREFIX="${prefix}" "${shimv2_builder}"
}
install_ovmf() {
ovmf_type="${1:-x86_64}"
tarball_name="${2:-edk2-x86_64.tar.gz}"
local component_name="ovmf"
[ "${ovmf_type}" == "sev" ] && component_name="ovmf-sev"
latest_artefact="$(get_from_kata_deps ".externals.ovmf.${ovmf_type}.version")"
latest_builder_image="$(get_ovmf_image_name)"
install_cached_tarball_component \
"${component_name}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
DESTDIR="${destdir}" PREFIX="${prefix}" ovmf_build="${ovmf_type}" "${ovmf_builder}"
tar xvf "${builddir}/${tarball_name}" -C "${destdir}"
}
# Install OVMF SEV
install_ovmf_sev() {
install_ovmf "sev" "edk2-sev.tar.gz"
}
install_agent() {
latest_artefact="$(git log -1 --abbrev=9 --pretty=format:"%h" ${repo_root_dir}/src/agent)"
artefact_tag="$(git log -1 --pretty=format:"%H" ${repo_root_dir})"
latest_builder_image="$(get_agent_image_name)"
install_cached_tarball_component \
"${build_target}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
export LIBSECCOMP_VERSION="$(get_from_kata_deps ".externals.libseccomp.version")"
export LIBSECCOMP_URL="$(get_from_kata_deps ".externals.libseccomp.url")"
export GPERF_VERSION="$(get_from_kata_deps ".externals.gperf.version")"
export GPERF_URL="$(get_from_kata_deps ".externals.gperf.url")"
info "build static agent"
DESTDIR="${destdir}" AGENT_POLICY="yes" PULL_TYPE=${PULL_TYPE} "${agent_builder}"
}
install_coco_guest_components() {
latest_artefact="$(get_from_kata_deps ".externals.coco-guest-components.version")-$(get_from_kata_deps ".externals.coco-guest-components.toolchain")"
artefact_tag="$(get_from_kata_deps ".externals.coco-guest-components.version")"
latest_builder_image="$(get_coco_guest_components_image_name)"
install_cached_tarball_component \
"${build_target}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static coco-guest-components"
DESTDIR="${destdir}" "${coco_guest_components_builder}"
}
install_pause_image() {
latest_artefact="$(get_from_kata_deps ".externals.pause.repo")-$(get_from_kata_deps ".externals.pause.version")"
artefact_tag=${latest_artefact}
latest_builder_image="$(get_pause_image_name)"
install_cached_tarball_component \
"${build_target}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static pause-image"
DESTDIR="${destdir}" "${pause_image_builder}"
}
install_script_helper() {
local script="${1:-}"
[ -n "$script" ] || die "need script"
local script_path
# If the script isn't specified as an absolute or relative path,
# find it.
if grep -q '/' <<< "$script"
then
script_path="$script"
else
script_path=$(find "${repo_root_dir}/" -type f -name "$script")
fi
local script_file
script_file=$(basename "$script_path")
local script_file_name
# Remove any extension
script_file_name="${script_file%%.*}"
info "installing utility script ${script}"
local bin_dir
bin_dir="${destdir}/opt/kata/bin/"
mkdir -p "$bin_dir"
install -D \
--mode "${default_binary_permissions}" \
"${script_path}" \
"${bin_dir}/${script_file}"
[ "$script_file" = "$script_file_name" ] && return 0
pushd "$bin_dir" &>/dev/null
# Create a sym-link with the extension removed
ln -sf "$script_file" "$script_file_name"
popd &>/dev/null
}
install_tools_helper() {
tool=${1}
latest_artefact="$(git log -1 --abbrev=9 --pretty=format:"%h" ${repo_root_dir}/src/tools/${tool})"
latest_builder_image="$(get_tools_image_name)"
install_cached_tarball_component \
"${tool}" \
"${latest_artefact}" \
"${latest_builder_image}" \
"${final_tarball_name}" \
"${final_tarball_path}" \
&& return 0
info "build static ${tool}"
${tools_builder} ${tool}
tool_binary=${tool}
[ ${tool} = "agent-ctl" ] && tool_binary="kata-agent-ctl"
[ ${tool} = "trace-forwarder" ] && tool_binary="kata-trace-forwarder"
binary=$(find ${repo_root_dir}/src/tools/${tool}/ -type f -name ${tool_binary})
if [[ "${tool}" == "genpolicy" ]]; then
defaults_path="${destdir}/opt/kata/share/defaults/kata-containers"
mkdir -p "${defaults_path}"
install -D --mode 0644 ${repo_root_dir}/src/tools/${tool}/rules.rego "${defaults_path}/rules.rego"
install -D --mode 0644 ${repo_root_dir}/src/tools/${tool}/genpolicy-settings.json "${defaults_path}/genpolicy-settings.json"
binary_permissions="0755"
else
binary_permissions="$default_binary_permissions"
fi
info "Install static ${tool_binary}"
mkdir -p "${destdir}/opt/kata/bin/"
install -D --mode ${binary_permissions} ${binary} "${destdir}/opt/kata/bin/${tool_binary}"
}
install_agent_ctl() {
install_tools_helper "agent-ctl"
}
install_genpolicy() {
install_tools_helper "genpolicy"
}
install_kata_ctl() {
install_tools_helper "kata-ctl"
}
install_kata_manager() {
install_script_helper "kata-manager.sh"
}
install_runk() {
install_tools_helper "runk"
}
install_trace_forwarder() {
install_tools_helper "trace-forwarder"
}
get_kata_version() {
local v
v=$(cat "${version_file}")
echo ${v}
}
handle_build() {
info "DESTDIR ${destdir}"
latest_artefact=""
latest_builder_image=""
local build_target
build_target="$1"
export final_tarball_path="${workdir}/kata-static-${build_target}.tar.xz"
export final_tarball_name="$(basename ${final_tarball_path})"
rm -f ${final_tarball_name}
case "${build_target}" in
all)
install_agent_ctl
install_clh
install_firecracker
install_image
install_image_confidential
install_initrd
install_initrd_confidential
install_initrd_mariner
install_kata_ctl
install_kata_manager
install_kernel
install_kernel_confidential
install_kernel_dragonball_experimental
install_log_parser_rs
install_nydus
install_ovmf
install_ovmf_sev
install_qemu
install_qemu_snp_experimental
install_stratovirt
install_runk
install_shimv2
install_trace_forwarder
install_virtiofsd
;;
agent) install_agent ;;
agent-ctl) install_agent_ctl ;;
boot-image-se) install_se_image ;;
coco-guest-components) install_coco_guest_components ;;
cloud-hypervisor) install_clh ;;
cloud-hypervisor-glibc) install_clh_glibc ;;
firecracker) install_firecracker ;;
genpolicy) install_genpolicy ;;
kata-ctl) install_kata_ctl ;;
kata-manager) install_kata_manager ;;
kernel) install_kernel ;;
kernel-confidential) install_kernel_confidential ;;
kernel-dragonball-experimental) install_kernel_dragonball_experimental ;;
kernel-nvidia-gpu) install_kernel_nvidia_gpu ;;
kernel-nvidia-gpu-confidential) install_kernel_nvidia_gpu_confidential ;;
nydus) install_nydus ;;
ovmf) install_ovmf ;;
ovmf-sev) install_ovmf_sev ;;
pause-image) install_pause_image ;;
qemu) install_qemu ;;
qemu-snp-experimental) install_qemu_snp_experimental ;;
stratovirt) install_stratovirt ;;
rootfs-image) install_image ;;
rootfs-image-confidential) install_image_confidential ;;
rootfs-initrd) install_initrd ;;
rootfs-initrd-confidential) install_initrd_confidential ;;
rootfs-initrd-mariner) install_initrd_mariner ;;
rootfs-nvidia-gpu-image) install_image_nvidia_gpu ;;
rootfs-nvidia-gpu-initrd) install_initrd_nvidia_gpu ;;
rootfs-nvidia-gpu-confidential-image) install_image_nvidia_gpu_confidential ;;
rootfs-nvidia-gpu-confidential-initrd) install_initrd_nvidia_gpu_confidential ;;
runk) install_runk ;;
shim-v2) install_shimv2 ;;
trace-forwarder) install_trace_forwarder ;;
virtiofsd) install_virtiofsd ;;
*)
die "Invalid build target ${build_target}"
;;
esac
if [ ! -f "${final_tarball_path}" ]; then
cd "${destdir}"
tar cvfJ "${final_tarball_path}" "."
fi
tar tvf "${final_tarball_path}"
case ${build_target} in
kernel-nvidia-gpu*)
local kernel_headers_final_tarball_path="${workdir}/kata-static-${build_target}-headers.tar.xz"
if [ ! -f "${kernel_headers_final_tarball_path}" ]; then
local kernel_headers_dir
kernel_headers_dir=$(get_kernel_headers_dir "${build_target}")
pushd "${kernel_headers_dir}"
find . -type f -name "*.${KERNEL_HEADERS_PKG_TYPE}" -exec tar cvfJ "${kernel_headers_final_tarball_path}" {} +
popd
fi
tar tvf "${kernel_headers_final_tarball_path}"
;;& # fallthrough in the confidential case we need the modules.tar.xz and for every kernel-nvidia-gpu we need the headers
kernel*-confidential)
local modules_final_tarball_path="${workdir}/kata-static-${build_target}-modules.tar.xz"
if [ ! -f "${modules_final_tarball_path}" ]; then
local modules_dir=$(get_kernel_modules_dir ${kernel_version} ${kernel_kata_config_version} ${build_target})
pushd "${modules_dir}"
rm -f build
tar cvfJ "${modules_final_tarball_path}" "."
popd
fi
tar tvf "${modules_final_tarball_path}"
;;
esac
pushd ${workdir}
echo "${latest_artefact}-$(git log -1 --abbrev=9 --pretty=format:"%h" ${repo_root_dir}/tools/packaging/kata-deploy/local-build)" > ${build_target}-version
echo "${latest_builder_image}" > ${build_target}-builder-image-version
sha256sum "${final_tarball_name}" > ${build_target}-sha256sum
if [ "${PUSH_TO_REGISTRY}" = "yes" ]; then
if [ -z "${ARTEFACT_REGISTRY}" ] ||
[ -z "${ARTEFACT_REPOSITORY}" ] ||
[ -z "${ARTEFACT_REGISTRY_USERNAME}" ] ||
[ -z "${ARTEFACT_REGISTRY_PASSWORD}" ] ||
[ -z "${TARGET_BRANCH}" ]; then
die "ARTEFACT_REGISTRY, ARTEFACT_REPOSITORY, ARTEFACT_REGISTRY_USERNAME, ARTEFACT_REGISTRY_PASSWORD and TARGET_BRANCH must be passed to the script when pushing the artefacts to the registry!"
fi
echo "${ARTEFACT_REGISTRY_PASSWORD}" | oras login "${ARTEFACT_REGISTRY}" -u "${ARTEFACT_REGISTRY_USERNAME}" --password-stdin
tags=(latest-"${TARGET_BRANCH}")
if [ -n "${artefact_tag:-}" ]; then
tags+=("${artefact_tag}")
fi
if [ "${RELEASE}" == "yes" ]; then
tags+=("$(cat "${version_file}")")
fi
echo "Pushing ${build_target} with tags: ${tags[*]}"
for tag in "${tags[@]}"; do
# tags can only contain lowercase and uppercase letters, digits, underscores, periods, and hyphens
# and limited to 128 characters, so filter out non-printable characers, replace invalid printable
# characters with underscode and trim down to leave enough space for the arch suffix
tag_length_limit=$(expr 128 - $(echo "-$(uname -m)" | wc -c))
tag=("$(echo ${tag} | tr -dc '[:print:]' | tr -c '[a-zA-Z0-9\_\.\-]' _ | head -c ${tag_length_limit})-$(uname -m)")
case ${build_target} in
kernel-nvidia-gpu)
oras push \
${ARTEFACT_REGISTRY}/kata-containers/cached-artefacts/${build_target}:${tag} \
${final_tarball_name} \
"kata-static-${build_target}-headers.tar.xz" \
${build_target}-version \
${build_target}-builder-image-version \
${build_target}-sha256sum
;;
kernel-nvidia-gpu-confidential)
oras push \
${ARTEFACT_REGISTRY}/${ARTEFACT_REPOSITORY}/cached-artefacts/${build_target}:${tag} \
${final_tarball_name} \
"kata-static-${build_target}-modules.tar.xz" \
"kata-static-${build_target}-headers.tar.xz" \
${build_target}-version \
${build_target}-builder-image-version \
${build_target}-sha256sum
;;
kernel*-confidential)
oras push \
${ARTEFACT_REGISTRY}/${ARTEFACT_REPOSITORY}/cached-artefacts/${build_target}:${tag} \
${final_tarball_name} \
"kata-static-${build_target}-modules.tar.xz" \
${build_target}-version \
${build_target}-builder-image-version \
${build_target}-sha256sum
;;
*)
oras push \
${ARTEFACT_REGISTRY}/${ARTEFACT_REPOSITORY}/cached-artefacts/${build_target}:${tag} \
${final_tarball_name} \
${build_target}-version \
${build_target}-builder-image-version \
${build_target}-sha256sum
;;
esac
done
oras logout "${ARTEFACT_REGISTRY}"
fi
popd
}
silent_mode_error_trap() {
local stdout="$1"
local stderr="$2"
local t="$3"
local log_file="$4"
exec 1>&${stdout}
exec 2>&${stderr}
error "Failed to build: $t, logs:"
cat "${log_file}"
exit 1
}
main() {
local build_targets
local silent
build_targets=(
agent
agent-ctl
cloud-hypervisor
coco-guest-components
firecracker
genpolicy
kata-ctl
kata-manager
kernel
kernel-experimental
nydus
pause-image
qemu
stratovirt
rootfs-image
rootfs-image-confidential
rootfs-initrd
rootfs-initrd-confidential
rootfs-initrd-mariner
runk
shim-v2
trace-forwarder
virtiofsd
)
silent=false
while getopts "hs-:" opt; do
case $opt in
-)
case "${OPTARG}" in
build=*)
build_targets=(${OPTARG#*=})
;;
help)
usage 0
;;
*)
usage 1
;;
esac
;;
h) usage 0 ;;
s) silent=true ;;
*) usage 1 ;;
esac
done
shift $((OPTIND - 1))
kata_version=$(get_kata_version)
workdir="${workdir}/build"
for t in "${build_targets[@]}"; do
destdir="${workdir}/${t}/destdir"
builddir="${workdir}/${t}/builddir"
echo "Build kata version ${kata_version}: ${t}"
mkdir -p "${destdir}"
mkdir -p "${builddir}"
if [ "${silent}" == true ]; then
log_file="${builddir}/log"
echo "build log: ${log_file}"
fi
(
cd "${builddir}"
if [ "${silent}" == true ]; then
local stdout
local stderr
# Save stdout and stderr, to be restored
# by silent_mode_error_trap() in case of
# build failure.
exec {stdout}>&1
exec {stderr}>&2
trap "silent_mode_error_trap $stdout $stderr $t \"$log_file\"" ERR
handle_build "${t}" &>"$log_file"
else
handle_build "${t}"
fi
)
done
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main $@
fi