Compare commits

..

1 Commits

Author SHA1 Message Date
stevenhorsman
aa11441c1a workflows: Create workflow to stale issues based on date
The standard stale/action is intended to be run regularly with
a date offset, but we want to have one we can run against a specific
date in order to run the stale bot against issues created since a particular
release milestone, so calculate the offset in one step and use it in the next.

At the moment we want to run this to stale issues before 9th October 2022 when Kata 3.0 was release, so default to this.

Note the stale action only processes a few issues at a time to avoid rate limiting, so why we want a cron job to it can get through
the backlog, but also to stale/unstale issues that are commented on.
2026-01-22 11:32:01 +00:00
148 changed files with 909 additions and 2133 deletions

View File

@@ -32,7 +32,6 @@ jobs:
matrix:
vmm:
- qemu
- qemu-runtime-rs
k8s:
- kubeadm
runs-on: arm64-k8s

41
.github/workflows/stale_issues.yaml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: 'Stale issues with activity before a fixed date'
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
date:
description: "Date of stale cut-off. All issues not updated since this date will be marked as stale. Format: YYYY-MM-DD e.g. 2022-10-09"
default: "2022-10-09"
required: false
type: string
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
stale:
name: stale
runs-on: ubuntu-24.04
permissions:
actions: write # Needed to manage caches for state persistence across runs
issues: write # Needed to add/remove labels, post comments, or close issues
steps:
- name: Calculate the age to stale
run: |
echo AGE=$(( ( $(date +%s) - $(date -d "${DATE:-2022-10-09}" +%s) ) / 86400 )) >> "$GITHUB_ENV"
env:
DATE: ${{ inputs.date }}
- name: Run the stale action
uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
with:
stale-pr-message: 'This issue has had no activity for at least ${AGE} days. Please comment on the issue, or it will be closed in 30 days'
days-before-pr-stale: -1
days-before-pr-close: -1
days-before-issue-stale: ${AGE}
days-before-issue-close: 30

View File

@@ -21,7 +21,7 @@ jobs:
persist-credentials: false
- name: Run zizmor
uses: zizmorcore/zizmor-action@135698455da5c3b3e55f73f4419e481ab68cdd95 # v0.4.1
uses: zizmorcore/zizmor-action@e673c3917a1aef3c65c972347ed84ccd013ecda4 # v0.2.0
with:
advanced-security: false
annotations: true

1
Cargo.lock generated
View File

@@ -4005,7 +4005,6 @@ version = "0.1.0"
dependencies = [
"anyhow",
"common",
"containerd-shim-protos",
"go-flag",
"logging",
"nix 0.26.4",

View File

@@ -1 +1 @@
3.26.0
3.25.0

View File

@@ -41,9 +41,12 @@ gperf_version="${GPERF_VERSION:-""}"
if [[ -z "${gperf_version}" ]]; then
gperf_version=$(get_from_kata_deps ".externals.gperf.version")
fi
gperf_url="${GPERF_URL:-""}"
if [[ -z "${gperf_url}" ]]; then
gperf_url=$(get_from_kata_deps ".externals.gperf.url")
fi
gperf_tarball="gperf-${gperf_version}.tar.gz"
# Path to the urls array in versions.yaml (used by download_from_mirror_list)
gperf_urls_path=".externals.gperf.urls"
gperf_tarball_url="${gperf_url}/${gperf_tarball}"
# Use ORAS cache for gperf downloads (gperf upstream can be unreliable)
USE_ORAS_CACHE="${USE_ORAS_CACHE:-yes}"
@@ -73,8 +76,6 @@ build_and_install_gperf() {
echo "Build and install gperf version ${gperf_version}"
mkdir -p "${gperf_install_dir}"
local downloaded_tarball=""
# Use ORAS cache if available and enabled
if [[ "${USE_ORAS_CACHE}" == "yes" ]] && [[ -f "${oras_cache_helper}" ]]; then
echo "Using ORAS cache for gperf download"
@@ -82,21 +83,16 @@ build_and_install_gperf() {
local cached_tarball
cached_tarball=$(download_component gperf "$(pwd)")
if [[ -f "${cached_tarball}" ]]; then
downloaded_tarball="${cached_tarball}"
gperf_tarball="${cached_tarball}"
else
echo "ORAS cache download failed, falling back to mirror list"
echo "ORAS cache download failed, falling back to direct download"
curl -sLO "${gperf_tarball_url}"
fi
else
curl -sLO "${gperf_tarball_url}"
fi
# If ORAS cache failed or was not used, try downloading from mirror list
if [[ -z "${downloaded_tarball}" ]]; then
downloaded_tarball=$(download_from_mirror_list "${gperf_urls_path}" "${gperf_tarball}" "$(pwd)")
if [[ ! -f "${downloaded_tarball}" ]]; then
die "Failed to download gperf tarball from any mirror"
fi
fi
tar -xf "${downloaded_tarball}"
tar -xf "${gperf_tarball}"
pushd "gperf-${gperf_version}"
# Unset $CC for configure, we will always use native for gperf
CC="" ./configure --prefix="${gperf_install_dir}"

View File

@@ -46,12 +46,16 @@ fi
[[ ${SELINUX_PERMISSIVE} == "yes" ]] && oc delete -f "${deployments_dir}/machineconfig_selinux.yaml.in"
# Delete kata-containers
helm uninstall kata-deploy --wait --namespace kube-system
pushd "${katacontainers_repo_dir}/tools/packaging/kata-deploy" || { echo "Failed to push to ${katacontainers_repo_dir}/tools/packaging/kata-deploy"; exit 125; }
oc delete -f kata-deploy/base/kata-deploy.yaml
oc -n kube-system wait --timeout=10m --for=delete -l name=kata-deploy pod
oc apply -f kata-cleanup/base/kata-cleanup.yaml
echo "Wait for all related pods to be gone"
( repeats=1; for _ in $(seq 1 600); do
oc get pods -l name="kubelet-kata-cleanup" --no-headers=true -n kube-system 2>&1 | grep "No resources found" -q && ((repeats++)) || repeats=1
[[ "${repeats}" -gt 5 ]] && echo kata-cleanup finished && break
sleep 1
done) || { echo "There are still some kata-cleanup related pods after 600 iterations"; oc get all -n kube-system; exit 1; }
oc delete -f kata-cleanup/base/kata-cleanup.yaml
oc delete -f kata-rbac/base/kata-rbac.yaml
oc delete -f runtimeclasses/kata-runtimeClasses.yaml

View File

@@ -51,13 +51,13 @@ apply_kata_deploy() {
oc label --overwrite ns kube-system pod-security.kubernetes.io/enforce=privileged pod-security.kubernetes.io/warn=baseline pod-security.kubernetes.io/audit=baseline
local version chart
version='0.0.0-dev'
version=$(curl -sSL https://api.github.com/repos/kata-containers/kata-containers/releases/latest | jq .tag_name | tr -d '"')
chart="oci://ghcr.io/kata-containers/kata-deploy-charts/kata-deploy"
# Ensure any potential leftover is cleaned up ... and this secret usually is not in case of previous failures
oc delete secret sh.helm.release.v1.kata-deploy.v1 -n kube-system || true
echo "Installing kata using helm ${chart} ${version} (sha printed in helm output)"
echo "Installing kata using helm ${chart} ${version}"
helm install kata-deploy --wait --namespace kube-system --set "image.reference=${KATA_DEPLOY_IMAGE%%:*},image.tag=${KATA_DEPLOY_IMAGE##*:}" "${chart}" --version "${version}"
}

View File

@@ -157,16 +157,6 @@ if [[ -z "${CAA_IMAGE}" ]]; then
fi
# Get latest PP image
#
# You can list the CI images by:
# az sig image-version list-community --location "eastus" --public-gallery-name "cocopodvm-d0e4f35f-5530-4b9c-8596-112487cdea85" --gallery-image-definition "podvm_image0" --output table
# or the release images by:
# az sig image-version list-community --location "eastus" --public-gallery-name "cococommunity-42d8482d-92cd-415b-b332-7648bd978eff" --gallery-image-definition "peerpod-podvm-fedora" --output table
# or the release debug images by:
# az sig image-version list-community --location "eastus" --public-gallery-name "cococommunity-42d8482d-92cd-415b-b332-7648bd978eff" --gallery-image-definition "peerpod-podvm-fedora-debug" --output table
#
# Note there are other flavours of the released images, you can list them by:
# az sig image-definition list-community --location "eastus" --public-gallery-name "cococommunity-42d8482d-92cd-415b-b332-7648bd978eff" --output table
if [[ -z "${PP_IMAGE_ID}" ]]; then
SUCCESS_TIME=$(curl -s \
-H "Accept: application/vnd.github+json" \

View File

@@ -125,7 +125,7 @@ If you want to enable SELinux in Permissive mode, add `enforcing=0` to the kerne
Enable full debug as follows:
```bash
$ sudo sed -i -E 's/^(\s*enable_debug\s*=\s*)false/\1true/' /etc/kata-containers/configuration.toml
$ sudo sed -i -e 's/^# *\(enable_debug\).*=.*$/\1 = true/g' /etc/kata-containers/configuration.toml
$ sudo sed -i -e 's/^kernel_params = "\(.*\)"/kernel_params = "\1 agent.log=debug initcall_debug"/g' /etc/kata-containers/configuration.toml
```

View File

@@ -51,7 +51,6 @@ containers started after the VM has been launched.
Users can check to see if the container uses the `devicemapper` block
device as its rootfs by calling `mount(8)` within the container. If
the `devicemapper` block device is used, the root filesystem (`/`)
will be mounted from `/dev/vda`. Users can enable direct mounting of
the underlying block device by setting the runtime
[configuration](README.md#configuration) flag `disable_block_device_use` to
`false`.
will be mounted from `/dev/vda`. Users can disable direct mounting of
the underlying block device through the runtime
[configuration](README.md#configuration).

View File

@@ -50,7 +50,7 @@ There are several kinds of Kata configurations and they are listed below.
| `io.katacontainers.config.hypervisor.default_max_vcpus` | uint32| the maximum number of vCPUs allocated for the VM by the hypervisor |
| `io.katacontainers.config.hypervisor.default_memory` | uint32| the memory assigned for a VM by the hypervisor in `MiB` |
| `io.katacontainers.config.hypervisor.default_vcpus` | float32| the default vCPUs assigned for a VM by the hypervisor |
| `io.katacontainers.config.hypervisor.disable_block_device_use` | `boolean` | disable hotplugging host block devices to guest VMs for container rootfs |
| `io.katacontainers.config.hypervisor.disable_block_device_use` | `boolean` | disallow a block device from being used |
| `io.katacontainers.config.hypervisor.disable_image_nvdimm` | `boolean` | specify if a `nvdimm` device should be used as rootfs for the guest (QEMU) |
| `io.katacontainers.config.hypervisor.disable_vhost_net` | `boolean` | specify if `vhost-net` is not available on the host |
| `io.katacontainers.config.hypervisor.enable_hugepages` | `boolean` | if the memory should be `pre-allocated` from huge pages |

View File

@@ -752,6 +752,15 @@ fn parse_mount(m: &Mount) -> (MsFlags, MsFlags, String) {
(flags, pgflags, data.join(","))
}
// This function constructs a canonicalized path by combining the `rootfs` and `unsafe_path` elements.
// The resulting path is guaranteed to be ("below" / "in a directory under") the `rootfs` directory.
//
// Parameters:
//
// - `rootfs` is the absolute path to the root of the containers root filesystem directory.
// - `unsafe_path` is path inside a container. It is unsafe since it may try to "escape" from the containers
// rootfs by using one or more "../" path elements or is its a symlink to path.
fn mount_from(
cfd_log: RawFd,
m: &Mount,

View File

@@ -4,7 +4,7 @@
// SPDX-License-Identifier: Apache-2.0
//
use std::collections::{BTreeMap, HashMap};
use std::collections::HashMap;
use std::fs;
use std::io::{self, Result};
use std::path::{Path, PathBuf};
@@ -206,8 +206,8 @@ impl TomlConfig {
}
/// Get agent-specfic kernel parameters for further Hypervisor config revision
pub fn get_agent_kernel_params(&self) -> Result<BTreeMap<String, String>> {
let mut kv = BTreeMap::new();
pub fn get_agent_kernel_params(&self) -> Result<HashMap<String, String>> {
let mut kv = HashMap::new();
if let Some(cfg) = self.agent.get(&self.runtime.agent_name) {
if cfg.debug {
kv.insert(LOG_LEVEL_OPTION.to_string(), LOG_LEVEL_DEBUG.to_string());

View File

@@ -22,7 +22,6 @@ cloud-hypervisor = ["runtimes/cloud-hypervisor"]
[dependencies]
anyhow = { workspace = true }
containerd-shim-protos = { workspace = true }
go-flag = { workspace = true }
nix = { workspace = true }
tokio = { workspace = true, features = ["rt", "rt-multi-thread"] }

View File

@@ -130,23 +130,8 @@ FCJAILERPATH = $(FCBINDIR)/$(FCJAILERCMD)
FCVALIDJAILERPATHS = [\"$(FCJAILERPATH)\"]
PKGLIBEXECDIR := $(LIBEXECDIR)/$(PROJECT_DIR)
# EDK2 firmware names per architecture
ifeq ($(ARCH), aarch64)
EDK2_NAME := aavmf
endif
# Set firmware paths from QEMUFW/QEMUFWVOL if defined
FIRMWAREPATH :=
FIRMWAREVOLUMEPATH :=
ifneq (,$(QEMUCMD))
ifneq (,$(QEMUFW))
FIRMWAREPATH := $(PREFIXDEPS)/share/$(EDK2_NAME)/$(QEMUFW)
endif
ifneq (,$(QEMUFWVOL))
FIRMWAREVOLUMEPATH := $(PREFIXDEPS)/share/$(EDK2_NAME)/$(QEMUFWVOL)
endif
endif
ROOTMEASURECONFIG ?= ""
KERNELTDXPARAMS += $(ROOTMEASURECONFIG)
@@ -389,11 +374,6 @@ ifneq (,$(QEMUCMD))
ifeq ($(ARCH), s390x)
VMROOTFSDRIVER_QEMU := virtio-blk-ccw
DEFBLOCKSTORAGEDRIVER_QEMU := virtio-blk-ccw
else ifeq ($(ARCH), aarch64)
# NVDIMM/virtio-pmem has issues on arm64 (cache coherency problems with DAX),
# so we use virtio-blk-pci instead.
VMROOTFSDRIVER_QEMU := virtio-blk-pci
DEFBLOCKSTORAGEDRIVER_QEMU := virtio-scsi
else
VMROOTFSDRIVER_QEMU := virtio-pmem
DEFBLOCKSTORAGEDRIVER_QEMU := virtio-scsi

View File

@@ -4,16 +4,12 @@
# SPDX-License-Identifier: Apache-2.0
#
# ARM 64 settings
MACHINETYPE := virt
MACHINETYPE :=
KERNELPARAMS := cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1
MACHINEACCELERATORS := usb=off,gic-version=host
MACHINEACCELERATORS :=
CPUFEATURES := pmu=off
QEMUCMD := qemu-system-aarch64
QEMUFW := AAVMF_CODE.fd
QEMUFWVOL := AAVMF_VARS.fd
# dragonball binary name
DBCMD := dragonball

View File

@@ -2296,14 +2296,6 @@ impl<'a> QemuCmdLine<'a> {
}
fn add_iommu(&mut self) {
// vIOMMU (Intel IOMMU) is not supported on the "virt" machine type (arm64)
if self.machine.r#type == "virt" {
self.kernel
.params
.append(&mut KernelParams::from_string("iommu.passthrough=0"));
return;
}
let dev_iommu = DeviceIntelIommu::new();
self.devices.push(Box::new(dev_iommu));

View File

@@ -28,13 +28,8 @@ use std::str::FromStr;
use std::time::Duration;
use qapi_spec::Dictionary;
use std::thread;
use std::time::Instant;
/// default qmp connection read timeout
const DEFAULT_QMP_READ_TIMEOUT: u64 = 250;
const DEFAULT_QMP_CONNECT_DEADLINE_MS: u64 = 5000;
const DEFAULT_QMP_RETRY_SLEEP_MS: u64 = 50;
pub struct Qmp {
qmp: qapi::Qmp<qapi::Stream<BufReader<UnixStream>, UnixStream>>,
@@ -63,43 +58,29 @@ impl Debug for Qmp {
impl Qmp {
pub fn new(qmp_sock_path: &str) -> Result<Self> {
let try_new_once_fn = || -> Result<Qmp> {
let stream = UnixStream::connect(qmp_sock_path)?;
let stream = UnixStream::connect(qmp_sock_path)?;
stream
.set_read_timeout(Some(Duration::from_millis(DEFAULT_QMP_READ_TIMEOUT)))
.context("set qmp read timeout")?;
// Set the read timeout to protect runtime-rs from blocking forever
// trying to set up QMP connection if qemu fails to launch. The exact
// value is a matter of judegement. Setting it too long would risk
// being ineffective since container runtime would timeout first anyway
// (containerd's task creation timeout is 2 s by default). OTOH
// setting it too short would risk interfering with a normal launch,
// perhaps just seeing some delay due to a heavily loaded host.
stream.set_read_timeout(Some(Duration::from_millis(DEFAULT_QMP_READ_TIMEOUT)))?;
let mut qmp = Qmp {
qmp: qapi::Qmp::new(qapi::Stream::new(
BufReader::new(stream.try_clone()?),
stream,
)),
guest_memory_block_size: 0,
};
let info = qmp.qmp.handshake().context("qmp handshake failed")?;
info!(sl!(), "QMP initialized: {:#?}", info);
Ok(qmp)
let mut qmp = Qmp {
qmp: qapi::Qmp::new(qapi::Stream::new(
BufReader::new(stream.try_clone()?),
stream,
)),
guest_memory_block_size: 0,
};
let deadline = Instant::now() + Duration::from_millis(DEFAULT_QMP_CONNECT_DEADLINE_MS);
let mut last_err: Option<anyhow::Error> = None;
let info = qmp.qmp.handshake()?;
info!(sl!(), "QMP initialized: {:#?}", info);
while Instant::now() < deadline {
match try_new_once_fn() {
Ok(qmp) => return Ok(qmp),
Err(e) => {
debug!(sl!(), "QMP not ready yet: {}", e);
last_err = Some(e);
thread::sleep(Duration::from_millis(DEFAULT_QMP_RETRY_SLEEP_MS));
}
}
}
Err(last_err.unwrap_or_else(|| anyhow!("QMP init timed out")))
.with_context(|| format!("timed out waiting for QMP ready: {}", qmp_sock_path))
Ok(qmp)
}
pub fn set_ignore_shared_memory_capability(&mut self) -> Result<()> {

View File

@@ -6,54 +6,39 @@
use std::{
io,
os::unix::{
fs::{FileTypeExt, OpenOptionsExt},
io::RawFd,
prelude::AsRawFd,
os::{
fd::IntoRawFd,
unix::{
fs::OpenOptionsExt,
io::{FromRawFd, RawFd},
net::UnixStream as StdUnixStream,
prelude::AsRawFd,
},
},
pin::Pin,
task::{Context as TaskContext, Poll},
};
use anyhow::{Context, Result};
use anyhow::{anyhow, Context, Result};
use tokio::{
fs::{File, OpenOptions},
fs::OpenOptions,
io::{AsyncRead, AsyncWrite},
net::UnixStream as AsyncUnixStream,
};
use url::Url;
/// Clear O_NONBLOCK for an fd (turn it into blocking mode).
fn set_flag_with_blocking(fd: RawFd) {
let flag = unsafe { libc::fcntl(fd, libc::F_GETFL) };
if flag < 0 {
error!(sl!(), "failed to fcntl(F_GETFL) fd {} ret {}", fd, flag);
return;
}
let ret = unsafe { libc::fcntl(fd, libc::F_SETFL, flag & !libc::O_NONBLOCK) };
if ret < 0 {
error!(sl!(), "failed to fcntl(F_SETFL) fd {} ret {}", fd, ret);
}
}
fn open_fifo_write(path: &str) -> Result<File> {
fn open_fifo_write(path: &str) -> Result<AsyncUnixStream> {
let std_file = std::fs::OpenOptions::new()
.write(true)
// It's not for non-block openning FIFO but for non-block stream which
// will be add into tokio runtime.
.custom_flags(libc::O_NONBLOCK)
.open(path)
.with_context(|| format!("open fifo for write: {path}"))?;
.with_context(|| format!("open {path} with write"))?;
let fd = std_file.into_raw_fd();
let std_stream = unsafe { StdUnixStream::from_raw_fd(fd) };
// Debug
let meta = std_file.metadata()?;
if !meta.file_type().is_fifo() {
debug!(sl!(), "[DEBUG]{} is not a fifo (type mismatch)", path);
}
set_flag_with_blocking(std_file.as_raw_fd());
Ok(File::from_std(std_file))
AsyncUnixStream::from_std(std_stream).map_err(|e| anyhow!(e))
}
pub struct ShimIo {
@@ -73,6 +58,14 @@ impl ShimIo {
"new shim io stdin {:?} stdout {:?} stderr {:?}", stdin, stdout, stderr
);
let set_flag_with_blocking = |fd: RawFd| {
let flag = unsafe { libc::fcntl(fd, libc::F_GETFL) };
let ret = unsafe { libc::fcntl(fd, libc::F_SETFL, flag & !libc::O_NONBLOCK) };
if ret < 0 {
error!(sl!(), "failed to set fcntl for fd {} error {}", fd, ret);
}
};
let stdin_fd: Option<Box<dyn AsyncRead + Send + Unpin>> = if let Some(stdin) = stdin {
info!(sl!(), "open stdin {:?}", &stdin);
@@ -105,7 +98,9 @@ impl ShimIo {
None => None,
Some(out) => match Url::parse(out.as_str()) {
Err(url::ParseError::RelativeUrlWithoutBase) => {
Url::parse(&format!("fifo://{}", out)).ok()
let out = "fifo://".to_owned() + out.as_str();
let u = Url::parse(out.as_str()).unwrap();
Some(u)
}
Err(err) => {
warn!(sl!(), "unable to parse stdout uri: {}", err);
@@ -116,25 +111,26 @@ impl ShimIo {
}
};
let stdout_url = get_url(stdout);
let get_fd = |url: &Option<Url>| -> Option<Box<dyn AsyncWrite + Send + Unpin>> {
info!(sl!(), "get fd for {:?}", &url);
if let Some(url) = url {
if url.scheme() == "fifo" {
let path = url.path();
match open_fifo_write(path) {
Ok(f) => return Some(Box::new(ShimIoWrite::File(f))),
Err(err) => error!(sl!(), "failed to open fifo {} error {:?}", path, err),
Ok(s) => {
return Some(Box::new(ShimIoWrite::Stream(s)));
}
Err(err) => {
error!(sl!(), "failed to open file {} error {:?}", url.path(), err);
}
}
} else {
warn!(sl!(), "unsupported io scheme {}", url.scheme());
}
}
None
};
let stdout_url = get_url(stdout);
let stderr_url = get_url(stderr);
Ok(Self {
stdin: stdin_fd,
stdout: get_fd(&stdout_url),
@@ -145,7 +141,7 @@ impl ShimIo {
#[derive(Debug)]
enum ShimIoWrite {
File(File),
Stream(AsyncUnixStream),
// TODO: support other type
}
@@ -155,20 +151,20 @@ impl AsyncWrite for ShimIoWrite {
cx: &mut TaskContext<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
match &mut *self {
ShimIoWrite::File(f) => Pin::new(f).poll_write(cx, buf),
match *self {
ShimIoWrite::Stream(ref mut s) => Pin::new(s).poll_write(cx, buf),
}
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll<io::Result<()>> {
match &mut *self {
ShimIoWrite::File(f) => Pin::new(f).poll_flush(cx),
match *self {
ShimIoWrite::Stream(ref mut s) => Pin::new(s).poll_flush(cx),
}
}
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll<io::Result<()>> {
match &mut *self {
ShimIoWrite::File(f) => Pin::new(f).poll_shutdown(cx),
match *self {
ShimIoWrite::Stream(ref mut s) => Pin::new(s).poll_shutdown(cx),
}
}
}

View File

@@ -6,15 +6,10 @@
use std::{
ffi::{OsStr, OsString},
io::Write,
path::PathBuf,
};
use anyhow::{anyhow, Context, Result};
use containerd_shim_protos::{
protobuf::Message,
types::introspection::{RuntimeInfo, RuntimeVersion},
};
use nix::{
mount::{mount, MsFlags},
sched::{self, CloneFlags},
@@ -34,13 +29,11 @@ enum Action {
Delete(Args),
Help,
Version,
Info,
}
fn parse_args(args: &[OsString]) -> Result<Action> {
let mut help = false;
let mut version = false;
let mut info = false;
let mut shim_args = Args::default();
// Crate `go_flag` is used to keep compatible with go/flag package.
@@ -53,7 +46,6 @@ fn parse_args(args: &[OsString]) -> Result<Action> {
flags.add_flag("publish-binary", &mut shim_args.publish_binary);
flags.add_flag("help", &mut help);
flags.add_flag("version", &mut version);
flags.add_flag("info", &mut info);
})
.context(Error::ParseArgument(format!("{args:?}")))?;
@@ -61,8 +53,6 @@ fn parse_args(args: &[OsString]) -> Result<Action> {
Ok(Action::Help)
} else if version {
Ok(Action::Version)
} else if info {
Ok(Action::Info)
} else if rest_args.is_empty() {
Ok(Action::Run(shim_args))
} else if rest_args[0] == "start" {
@@ -93,8 +83,6 @@ fn show_help(cmd: &OsStr) {
enable debug output in logs
-id string
id of the task
-info
output the runtime info as protobuf (for containerd v2.0+)
-namespace string
namespace that owns the shim
-publish-binary string
@@ -126,25 +114,6 @@ fn show_version(err: Option<anyhow::Error>) {
}
}
fn show_info() -> Result<()> {
let mut version = RuntimeVersion::new();
version.version = config::RUNTIME_VERSION.to_string();
version.revision = config::RUNTIME_GIT_COMMIT.to_string();
let mut info = RuntimeInfo::new();
info.name = config::CONTAINERD_RUNTIME_NAME.to_string();
info.version = Some(version).into();
let data = info
.write_to_bytes()
.context("failed to marshal RuntimeInfo")?;
std::io::stdout()
.write_all(&data)
.context("failed to write RuntimeInfo to stdout")?;
Ok(())
}
fn get_tokio_runtime() -> Result<tokio::runtime::Runtime> {
let worker_threads = std::env::var(ENV_TOKIO_RUNTIME_WORKER_THREADS)
.unwrap_or_default()
@@ -186,7 +155,6 @@ fn real_main() -> Result<()> {
}
Action::Help => show_help(&args[0]),
Action::Version => show_version(None),
Action::Info => show_info().context("show info")?,
}
Ok(())
}

View File

@@ -174,6 +174,10 @@ HYPERVISORS := $(HYPERVISOR_FC) $(HYPERVISOR_QEMU) $(HYPERVISOR_CLH) $(HYPERVISO
QEMUPATH := $(QEMUBINDIR)/$(QEMUCMD)
QEMUVALIDHYPERVISORPATHS := [\"$(QEMUPATH)\"]
#QEMUTDXPATH := $(QEMUBINDIR)/$(QEMUTDXCMD)
QEMUTDXPATH := PLACEHOLDER_FOR_DISTRO_QEMU_WITH_TDX_SUPPORT
QEMUTDXVALIDHYPERVISORPATHS := [\"$(QEMUTDXPATH)\"]
QEMUTDXEXPERIMENTALPATH := $(QEMUBINDIR)/$(QEMUTDXEXPERIMENTALCMD)
QEMUTDXEXPERIMENTALVALIDHYPERVISORPATHS := [\"$(QEMUTDXEXPERIMENTALPATH)\"]
@@ -246,7 +250,7 @@ DEFSECCOMPSANDBOXPARAM :=
DEFENTROPYSOURCE := /dev/urandom
DEFVALIDENTROPYSOURCES := [\"/dev/urandom\",\"/dev/random\",\"\"]
DEFDISABLEBLOCK := true
DEFDISABLEBLOCK := false
DEFSHAREDFS_CLH_VIRTIOFS := virtio-fs
DEFSHAREDFS_QEMU_VIRTIOFS := virtio-fs
# Please keep DEFSHAREDFS_QEMU_COCO_DEV_VIRTIOFS in sync with TDX/SNP
@@ -698,15 +702,18 @@ USER_VARS += PROJECT_TYPE
USER_VARS += PROJECT_URL
USER_VARS += QEMUBINDIR
USER_VARS += QEMUCMD
USER_VARS += QEMUTDXCMD
USER_VARS += QEMUTDXEXPERIMENTALCMD
USER_VARS += QEMUCCAEXPERIMENTALCMD
USER_VARS += QEMUSNPCMD
USER_VARS += QEMUPATH
USER_VARS += QEMUTDXPATH
USER_VARS += QEMUTDXEXPERIMENTALPATH
USER_VARS += QEMUTDXQUOTEGENERATIONSERVICESOCKETPORT
USER_VARS += QEMUSNPPATH
USER_VARS += QEMUCCAEXPERIMENTALPATH
USER_VARS += QEMUVALIDHYPERVISORPATHS
USER_VARS += QEMUTDXVALIDHYPERVISORPATHS
USER_VARS += QEMUTDXEXPERIMENTALVALIDHYPERVISORPATHS
USER_VARS += QEMUCCAVALIDHYPERVISORPATHS
USER_VARS += QEMUCCAEXPERIMENTALVALIDHYPERVISORPATHS

View File

@@ -9,9 +9,7 @@ import (
"fmt"
"os"
containerdtypes "github.com/containerd/containerd/api/types"
shimapi "github.com/containerd/containerd/runtime/v2/shim"
"google.golang.org/protobuf/proto"
shim "github.com/kata-containers/kata-containers/src/runtime/pkg/containerd-shim-v2"
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
@@ -23,25 +21,6 @@ func shimConfig(config *shimapi.Config) {
config.NoSubreaper = true
}
func handleInfoFlag() {
info := &containerdtypes.RuntimeInfo{
Name: types.DefaultKataRuntimeName,
Version: &containerdtypes.RuntimeVersion{
Version: katautils.VERSION,
Revision: katautils.COMMIT,
},
}
data, err := proto.Marshal(info)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to marshal RuntimeInfo: %v\n", err)
os.Exit(1)
}
os.Stdout.Write(data)
os.Exit(0)
}
func main() {
if len(os.Args) == 2 && os.Args[1] == "--version" {
@@ -49,9 +28,5 @@ func main() {
os.Exit(0)
}
if len(os.Args) == 2 && os.Args[1] == "-info" {
handleInfoFlag()
}
shimapi.Run(types.DefaultKataRuntimeName, shim.New, shimConfig)
}

View File

@@ -109,20 +109,6 @@ memory_slots = @DEFMEMSLOTS@
# > amount of physical RAM --> will be set to the actual amount of physical RAM
default_maxmemory = @DEFMAXMEMSZ@
# Disable hotplugging host block devices to guest VMs for container rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:
# - virtio-fs (default)
# - virtio-fs-nydus

View File

@@ -159,18 +159,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -145,18 +145,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -185,18 +185,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -162,18 +162,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -144,18 +144,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -153,18 +153,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -184,18 +184,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -12,7 +12,7 @@
# XXX: Type: @PROJECT_TYPE@
[hypervisor.qemu]
path = "@QEMUPATH@"
path = "@QEMUTDXPATH@"
kernel = "@KERNELCONFIDENTIALPATH@"
image = "@IMAGECONFIDENTIALPATH@"
machine_type = "@MACHINETYPE@"
@@ -54,7 +54,7 @@ enable_annotations = @DEFENABLEANNOTATIONS_COCO@
# Each member of the list is a path pattern as described by glob(3).
# The default if not set is empty (all annotations rejected.)
# Your distribution recommends: @QEMUVALIDHYPERVISORPATHS@
valid_hypervisor_paths = @QEMUVALIDHYPERVISORPATHS@
valid_hypervisor_paths = @QEMUTDXVALIDHYPERVISORPATHS@
# Optional space-separated list of options to pass to the guest kernel.
# For example, use `kernel_params = "vsyscall=emulate"` if you are having
@@ -161,18 +161,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -144,18 +144,12 @@ memory_offset = 0
# Default false
enable_virtio_mem = false
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -103,18 +103,12 @@ default_maxmemory = @DEFMAXMEMSZ@
# Default 0
memory_offset = 0
# Disable hotplugging host block devices to guest VMs for container rootfs.
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
# root file system is backed by a block device, the block device is passed
# directly to the hypervisor for performance reasons.
# This flag prevents the block device from being passed to the hypervisor,
# virtio-fs is used instead to pass the rootfs.
# WARNING:
# Don't set this flag to false if you don't understand well the behavior of
# your container runtime and image snapshotter. Some snapshotters might use
# container image storage devices that are not meant to be hotplugged into a
# guest VM - e.g., because they contain files used by the host or by other
# guests.
disable_block_device_use = @DEFDISABLEBLOCK@
# Shared file system type:

View File

@@ -1,7 +1,7 @@
module github.com/kata-containers/kata-containers/src/runtime
// Keep in sync with version in versions.yaml
go 1.24.12
go 1.24.11
// WARNING: Do NOT use `replace` directives as those break dependabot:
// https://github.com/kata-containers/kata-containers/issues/11020

View File

@@ -861,10 +861,6 @@ func (q *qemu) createPCIeTopology(qemuConfig *govmmQemu.Config, hypervisorConfig
return fmt.Errorf("Cannot get VFIO device from IOMMUFD with device: %v err: %v", dev, err)
}
} else {
if q.config.ConfidentialGuest {
return fmt.Errorf("ConfidentialGuest needs IOMMUFD - cannot use %s", dev.HostPath)
}
vfioDevices, err = drivers.GetAllVFIODevicesFromIOMMUGroup(dev)
if err != nil {
return fmt.Errorf("Cannot get all VFIO devices from IOMMU group with device: %v err: %v", dev, err)

View File

@@ -1,7 +1,7 @@
module kata-containers/csi-kata-directvolume
// Keep in sync with version in versions.yaml
go 1.24.12
go 1.24.11
// WARNING: Do NOT use `replace` directives as those break dependabot:
// https://github.com/kata-containers/kata-containers/issues/11020

View File

@@ -1,7 +1,7 @@
module github.com/kata-containers/kata-containers/src/tools/log-parser
// Keep in sync with version in versions.yaml
go 1.24.12
go 1.24.11
require (
github.com/BurntSushi/toml v1.1.0

View File

@@ -602,60 +602,6 @@ function get_from_kata_deps() {
echo "$result"
}
# Download a file by trying multiple mirror URLs until one succeeds.
# This function is useful for downloading files from unreliable sources
# by providing fallback mirrors.
#
# $1 - path in versions.yaml to the urls array (e.g., ".externals.gperf.urls")
# $2 - filename to download (will be appended to each mirror URL)
# $3 - destination directory (defaults to current directory)
#
# Returns: 0 on success, 1 on failure
# Output: Prints the path to the downloaded file on success
function download_from_mirror_list() {
local urls_path="${1}"
local filename="${2}"
local dest_dir="${3:-.}"
local versions_file="${repo_root_dir}/versions.yaml"
command -v yq &>/dev/null || die 'yq command is not in your $PATH'
local urls
# Query yq to get URLs as clean lines (using .[] to iterate array elements)
local yq_version
yq_version=$(yq --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | cut -d. -f1)
if [ "$yq_version" -eq 3 ]; then
local dependency
dependency=$(echo "${urls_path}" | sed "s/^\.//g")
urls=$("yq" read -p p "$versions_file" "${dependency}.*")
else
urls=$("yq" "${urls_path} | .[]" "$versions_file")
fi
if [[ -z "${urls}" ]]; then
echo "Error: No URLs found at ${urls_path}" >&2
return 1
fi
# Iterate over each URL (one per line)
local url
while IFS= read -r url; do
# Skip empty lines
[[ -z "${url}" ]] && continue
local full_url="${url}${filename}"
echo "Trying to download from: ${full_url}" >&2
if curl -sfLo "${dest_dir}/${filename}" "${full_url}"; then
echo "Successfully downloaded ${filename}" >&2
echo "${dest_dir}/${filename}"
return 0
fi
echo "Failed to download from ${full_url}, trying next mirror..." >&2
done <<< "${urls}"
echo "Error: Failed to download ${filename} from all mirrors" >&2
return 1
}
# project: org/repo format
# base_version: ${major}.${minor}
# allow_unstable: Whether alpha / beta releases should be considered (default: false)

View File

@@ -1,366 +0,0 @@
#!/usr/bin/env bats
# Copyright (c) 2025 NVIDIA Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# End-to-end tests for kata-deploy custom runtimes feature
# These tests deploy kata-deploy with custom runtimes and verify pods can run
#
# Required environment variables:
# DOCKER_REGISTRY - Container registry for kata-deploy image
# DOCKER_REPO - Repository name for kata-deploy image
# DOCKER_TAG - Image tag to test
# KATA_HYPERVISOR - Hypervisor to test (qemu, clh, etc.)
# KUBERNETES - K8s distribution (microk8s, k3s, rke2, etc.)
load "${BATS_TEST_DIRNAME}/../../common.bash"
repo_root_dir="${BATS_TEST_DIRNAME}/../../../"
load "${repo_root_dir}/tests/gha-run-k8s-common.sh"
# Load shared helm deployment helpers
source "${BATS_TEST_DIRNAME}/lib/helm-deploy.bash"
# Test configuration
CUSTOM_RUNTIME_NAME="special-workload"
CUSTOM_RUNTIME_HANDLER="kata-my-custom-handler"
TEST_POD_NAME="kata-deploy-custom-verify"
CHART_PATH="$(get_chart_path)"
# =============================================================================
# Template Rendering Tests (no cluster required)
# =============================================================================
@test "Helm template: ConfigMap is created with custom runtime" {
helm template kata-deploy "${CHART_PATH}" \
-f "${CUSTOM_VALUES_FILE}" \
--set image.reference=quay.io/kata-containers/kata-deploy \
--set image.tag=latest \
> /tmp/rendered.yaml
# Check that ConfigMap exists
grep -q "kind: ConfigMap" /tmp/rendered.yaml
grep -q "kata-deploy-custom-configs" /tmp/rendered.yaml
grep -q "${CUSTOM_RUNTIME_HANDLER}" /tmp/rendered.yaml
}
@test "Helm template: RuntimeClass is created with correct handler" {
helm template kata-deploy "${CHART_PATH}" \
-f "${CUSTOM_VALUES_FILE}" \
--set image.reference=quay.io/kata-containers/kata-deploy \
--set image.tag=latest \
> /tmp/rendered.yaml
grep -q "kind: RuntimeClass" /tmp/rendered.yaml
grep -q "handler: ${CUSTOM_RUNTIME_HANDLER}" /tmp/rendered.yaml
}
@test "Helm template: Drop-in file is included in ConfigMap" {
helm template kata-deploy "${CHART_PATH}" \
-f "${CUSTOM_VALUES_FILE}" \
--set image.reference=quay.io/kata-containers/kata-deploy \
--set image.tag=latest \
> /tmp/rendered.yaml
grep -q "dropin-${CUSTOM_RUNTIME_HANDLER}.toml" /tmp/rendered.yaml
grep -q "dial_timeout = 999" /tmp/rendered.yaml
}
@test "Helm template: CUSTOM_RUNTIMES_ENABLED env var is set" {
helm template kata-deploy "${CHART_PATH}" \
-f "${CUSTOM_VALUES_FILE}" \
--set image.reference=quay.io/kata-containers/kata-deploy \
--set image.tag=latest \
> /tmp/rendered.yaml
grep -q "CUSTOM_RUNTIMES_ENABLED" /tmp/rendered.yaml
grep -A1 "CUSTOM_RUNTIMES_ENABLED" /tmp/rendered.yaml | grep -q '"true"'
}
@test "Helm template: custom-configs volume is mounted" {
helm template kata-deploy "${CHART_PATH}" \
-f "${CUSTOM_VALUES_FILE}" \
--set image.reference=quay.io/kata-containers/kata-deploy \
--set image.tag=latest \
> /tmp/rendered.yaml
grep -q "mountPath: /custom-configs/" /tmp/rendered.yaml
grep -q "name: custom-configs" /tmp/rendered.yaml
}
@test "Helm template: No custom runtime resources when disabled" {
helm template kata-deploy "${CHART_PATH}" \
--set image.reference=quay.io/kata-containers/kata-deploy \
--set image.tag=latest \
--set customRuntimes.enabled=false \
> /tmp/rendered.yaml
! grep -q "kata-deploy-custom-configs" /tmp/rendered.yaml
! grep -q "CUSTOM_RUNTIMES_ENABLED" /tmp/rendered.yaml
}
@test "Helm template: Custom runtimes only mode (no standard shims)" {
# Test that Helm chart renders correctly when all standard shims are disabled
# using shims.disableAll and only custom runtimes are enabled
local values_file
values_file=$(mktemp)
cat > "${values_file}" <<EOF
image:
reference: quay.io/kata-containers/kata-deploy
tag: latest
# Disable all standard shims at once
shims:
disableAll: true
# Enable only custom runtimes
customRuntimes:
enabled: true
runtimes:
my-only-runtime:
baseConfig: "qemu"
dropIn: |
[hypervisor.qemu]
enable_debug = true
runtimeClass: |
kind: RuntimeClass
apiVersion: node.k8s.io/v1
metadata:
name: kata-my-only-runtime
handler: kata-my-only-runtime
scheduling:
nodeSelector:
katacontainers.io/kata-runtime: "true"
containerd:
snapshotter: ""
crio:
pullType: ""
EOF
helm template kata-deploy "${CHART_PATH}" -f "${values_file}" > /tmp/rendered.yaml
rm -f "${values_file}"
# Verify custom runtime resources are created
grep -q "kata-deploy-custom-configs" /tmp/rendered.yaml
grep -q "CUSTOM_RUNTIMES_ENABLED" /tmp/rendered.yaml
grep -q "kata-my-only-runtime" /tmp/rendered.yaml
# Verify SHIMS env var is empty (no standard shims)
local shims_value
shims_value=$(grep -A1 'name: SHIMS$' /tmp/rendered.yaml | grep 'value:' | head -1 || echo "")
echo "# SHIMS env value: ${shims_value}" >&3
}
# =============================================================================
# End-to-End Tests (require cluster with kata-deploy)
# =============================================================================
@test "E2E: Custom RuntimeClass exists and can run a pod" {
# Check RuntimeClass exists
run kubectl get runtimeclass "${CUSTOM_RUNTIME_HANDLER}" -o name
if [[ "${status}" -ne 0 ]]; then
echo "# RuntimeClass not found. kata-deploy logs:" >&3
kubectl -n kube-system logs -l name=kata-deploy --tail=50 2>/dev/null || true
die "Custom RuntimeClass ${CUSTOM_RUNTIME_HANDLER} not found"
fi
echo "# RuntimeClass ${CUSTOM_RUNTIME_HANDLER} exists" >&3
# Verify handler is correct
local handler
handler=$(kubectl get runtimeclass "${CUSTOM_RUNTIME_HANDLER}" -o jsonpath='{.handler}')
echo "# Handler: ${handler}" >&3
[[ "${handler}" == "${CUSTOM_RUNTIME_HANDLER}" ]]
# Verify overhead is set
local overhead_memory
overhead_memory=$(kubectl get runtimeclass "${CUSTOM_RUNTIME_HANDLER}" -o jsonpath='{.overhead.podFixed.memory}')
echo "# Overhead memory: ${overhead_memory}" >&3
[[ "${overhead_memory}" == "640Mi" ]]
local overhead_cpu
overhead_cpu=$(kubectl get runtimeclass "${CUSTOM_RUNTIME_HANDLER}" -o jsonpath='{.overhead.podFixed.cpu}')
echo "# Overhead CPU: ${overhead_cpu}" >&3
[[ "${overhead_cpu}" == "500m" ]]
# Verify nodeSelector is set
local node_selector
node_selector=$(kubectl get runtimeclass "${CUSTOM_RUNTIME_HANDLER}" -o jsonpath='{.scheduling.nodeSelector.katacontainers\.io/kata-runtime}')
echo "# Node selector: ${node_selector}" >&3
[[ "${node_selector}" == "true" ]]
# Verify label is set (Helm sets this to "Helm" when it manages the resource)
local label
label=$(kubectl get runtimeclass "${CUSTOM_RUNTIME_HANDLER}" -o jsonpath='{.metadata.labels.app\.kubernetes\.io/managed-by}')
echo "# Label app.kubernetes.io/managed-by: ${label}" >&3
[[ "${label}" == "Helm" ]]
# Create a test pod using the custom runtime
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: ${TEST_POD_NAME}
spec:
runtimeClassName: ${CUSTOM_RUNTIME_HANDLER}
restartPolicy: Never
nodeSelector:
katacontainers.io/kata-runtime: "true"
containers:
- name: test
image: quay.io/kata-containers/alpine-bash-curl:latest
command: ["echo", "OK"]
EOF
# Wait for pod to complete or become ready
echo "# Waiting for pod to be ready..." >&3
local timeout=120
local start_time
start_time=$(date +%s)
while true; do
local phase
phase=$(kubectl get pod "${TEST_POD_NAME}" -o jsonpath='{.status.phase}' 2>/dev/null || echo "Unknown")
case "${phase}" in
Succeeded|Running)
echo "# Pod reached phase: ${phase}" >&3
break
;;
Failed)
echo "# Pod failed" >&3
kubectl describe pod "${TEST_POD_NAME}" >&3
die "Pod failed to run with custom runtime"
;;
*)
local current_time
current_time=$(date +%s)
if (( current_time - start_time > timeout )); then
echo "# Timeout waiting for pod" >&3
kubectl describe pod "${TEST_POD_NAME}" >&3
die "Timeout waiting for pod to be ready"
fi
sleep 5
;;
esac
done
# Verify pod ran successfully
local exit_code
exit_code=$(kubectl get pod "${TEST_POD_NAME}" -o jsonpath='{.status.containerStatuses[0].state.terminated.exitCode}' 2>/dev/null || echo "")
if [[ "${exit_code}" == "0" ]] || [[ "$(kubectl get pod "${TEST_POD_NAME}" -o jsonpath='{.status.phase}')" == "Running" ]]; then
echo "# Pod ran successfully with custom runtime" >&3
BATS_TEST_COMPLETED=1
else
die "Pod did not complete successfully (exit code: ${exit_code})"
fi
}
# =============================================================================
# Setup and Teardown
# =============================================================================
setup_file() {
ensure_helm
echo "# Using base config: ${KATA_HYPERVISOR}" >&3
echo "# Custom runtime handler: ${CUSTOM_RUNTIME_HANDLER}" >&3
echo "# Image: ${DOCKER_REGISTRY}/${DOCKER_REPO}:${DOCKER_TAG}" >&3
echo "# K8s distribution: ${KUBERNETES}" >&3
# Create values file for custom runtimes
export DEPLOY_VALUES_FILE=$(mktemp)
cat > "${DEPLOY_VALUES_FILE}" <<EOF
customRuntimes:
enabled: true
runtimes:
${CUSTOM_RUNTIME_NAME}:
baseConfig: "${KATA_HYPERVISOR}"
dropIn: |
[agent.kata]
dial_timeout = 999
runtimeClass: |
kind: RuntimeClass
apiVersion: node.k8s.io/v1
metadata:
name: ${CUSTOM_RUNTIME_HANDLER}
labels:
app.kubernetes.io/managed-by: kata-deploy
handler: ${CUSTOM_RUNTIME_HANDLER}
overhead:
podFixed:
memory: "640Mi"
cpu: "500m"
scheduling:
nodeSelector:
katacontainers.io/kata-runtime: "true"
containerd:
snapshotter: ""
crio:
pullType: ""
EOF
echo "# Deploying kata-deploy with custom runtimes..." >&3
deploy_kata "${DEPLOY_VALUES_FILE}"
echo "# kata-deploy deployed successfully" >&3
}
setup() {
# Create temporary values file for template tests
CUSTOM_VALUES_FILE=$(mktemp)
cat > "${CUSTOM_VALUES_FILE}" <<EOF
customRuntimes:
enabled: true
runtimes:
${CUSTOM_RUNTIME_NAME}:
baseConfig: "${KATA_HYPERVISOR:-qemu}"
dropIn: |
[agent.kata]
dial_timeout = 999
runtimeClass: |
kind: RuntimeClass
apiVersion: node.k8s.io/v1
metadata:
name: ${CUSTOM_RUNTIME_HANDLER}
labels:
app.kubernetes.io/managed-by: kata-deploy
handler: ${CUSTOM_RUNTIME_HANDLER}
overhead:
podFixed:
memory: "640Mi"
cpu: "500m"
scheduling:
nodeSelector:
katacontainers.io/kata-runtime: "true"
containerd:
snapshotter: ""
crio:
pullType: ""
EOF
}
teardown() {
# Show pod details for debugging if test failed
if [[ "${BATS_TEST_COMPLETED:-}" != "1" ]]; then
echo "# Test failed, gathering diagnostics..." >&3
kubectl describe pod "${TEST_POD_NAME}" 2>/dev/null || true
echo "# kata-deploy logs:" >&3
kubectl -n kube-system logs -l name=kata-deploy --tail=100 2>/dev/null || true
fi
# Clean up test pod
kubectl delete pod "${TEST_POD_NAME}" --ignore-not-found=true --wait=false 2>/dev/null || true
# Clean up temp file
[[ -f "${CUSTOM_VALUES_FILE:-}" ]] && rm -f "${CUSTOM_VALUES_FILE}"
}
teardown_file() {
echo "# Cleaning up..." >&3
kubectl delete pod "${TEST_POD_NAME}" --ignore-not-found=true --wait=true --timeout=60s 2>/dev/null || true
uninstall_kata
[[ -f "${DEPLOY_VALUES_FILE:-}" ]] && rm -f "${DEPLOY_VALUES_FILE}"
}

View File

@@ -31,9 +31,6 @@ load "${BATS_TEST_DIRNAME}/../../common.bash"
repo_root_dir="${BATS_TEST_DIRNAME}/../../../"
load "${repo_root_dir}/tests/gha-run-k8s-common.sh"
# Load shared helm deployment helpers
source "${BATS_TEST_DIRNAME}/lib/helm-deploy.bash"
setup() {
ensure_helm
@@ -82,6 +79,7 @@ EOF
# Install kata-deploy via Helm
echo "Installing kata-deploy with Helm..."
local helm_chart_dir="tools/packaging/kata-deploy/helm-chart/kata-deploy"
# Timeouts can be customized via environment variables:
# - KATA_DEPLOY_TIMEOUT: Overall helm timeout (includes all hooks)
@@ -99,11 +97,43 @@ EOF
echo " DaemonSet rollout: ${daemonset_timeout}s (includes image pull)"
echo " Verification pod: ${verification_timeout}s (pod execution)"
# Deploy kata-deploy using shared helper with verification options
HELM_TIMEOUT="${helm_timeout}" deploy_kata "" \
helm dependency build "${helm_chart_dir}"
# Disable all shims except the one being tested
helm upgrade --install kata-deploy "${helm_chart_dir}" \
--set image.reference="${DOCKER_REGISTRY}/${DOCKER_REPO}" \
--set image.tag="${DOCKER_TAG}" \
--set debug=true \
--set k8sDistribution="${KUBERNETES}" \
--set shims.clh.enabled=false \
--set shims.cloud-hypervisor.enabled=false \
--set shims.dragonball.enabled=false \
--set shims.fc.enabled=false \
--set shims.qemu.enabled=false \
--set shims.qemu-runtime-rs.enabled=false \
--set shims.qemu-cca.enabled=false \
--set shims.qemu-se.enabled=false \
--set shims.qemu-se-runtime-rs.enabled=false \
--set shims.qemu-nvidia-gpu.enabled=false \
--set shims.qemu-nvidia-gpu-snp.enabled=false \
--set shims.qemu-nvidia-gpu-tdx.enabled=false \
--set shims.qemu-sev.enabled=false \
--set shims.qemu-snp.enabled=false \
--set shims.qemu-snp-runtime-rs.enabled=false \
--set shims.qemu-tdx.enabled=false \
--set shims.qemu-tdx-runtime-rs.enabled=false \
--set shims.qemu-coco-dev.enabled=false \
--set shims.qemu-coco-dev-runtime-rs.enabled=false \
--set "shims.${KATA_HYPERVISOR}.enabled=true" \
--set "defaultShim.amd64=${KATA_HYPERVISOR}" \
--set "defaultShim.arm64=${KATA_HYPERVISOR}" \
--set runtimeClasses.enabled=true \
--set runtimeClasses.createDefault=true \
--set-file verification.pod="${verification_yaml}" \
--set verification.timeout="${verification_timeout}" \
--set verification.daemonsetTimeout="${daemonset_timeout}"
--set verification.daemonsetTimeout="${daemonset_timeout}" \
--namespace kube-system \
--wait --timeout "${helm_timeout}"
rm -f "${verification_yaml}"
@@ -149,5 +179,7 @@ EOF
}
teardown() {
uninstall_kata
pushd "${repo_root_dir}"
helm uninstall kata-deploy --ignore-not-found --wait --cascade foreground --timeout 10m --namespace kube-system --debug
popd
}

View File

@@ -1,127 +0,0 @@
#!/bin/bash
# Copyright (c) 2025 NVIDIA Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# Shared helm deployment helpers for kata-deploy tests
#
# Required environment variables:
# DOCKER_REGISTRY - Container registry for kata-deploy image
# DOCKER_REPO - Repository name for kata-deploy image
# DOCKER_TAG - Image tag to test
# KATA_HYPERVISOR - Hypervisor to test (qemu, clh, etc.)
# KUBERNETES - K8s distribution (microk8s, k3s, rke2, etc.)
HELM_RELEASE_NAME="${HELM_RELEASE_NAME:-kata-deploy}"
HELM_NAMESPACE="${HELM_NAMESPACE:-kube-system}"
# Get the path to the helm chart
get_chart_path() {
local script_dir
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "${script_dir}/../../../../tools/packaging/kata-deploy/helm-chart/kata-deploy"
}
# Generate base values YAML that disables all shims except the specified one
# Arguments:
# $1 - Output file path
# $2 - (Optional) Additional values file to merge
generate_base_values() {
local output_file="$1"
local extra_values_file="${2:-}"
cat > "${output_file}" <<EOF
image:
reference: ${DOCKER_REGISTRY}/${DOCKER_REPO}
tag: ${DOCKER_TAG}
k8sDistribution: "${KUBERNETES}"
debug: true
# Disable all shims at once, then enable only the one we need
shims:
disableAll: true
${KATA_HYPERVISOR}:
enabled: true
defaultShim:
amd64: ${KATA_HYPERVISOR}
arm64: ${KATA_HYPERVISOR}
runtimeClasses:
enabled: true
createDefault: true
EOF
}
# Deploy kata-deploy using helm
# Arguments:
# $1 - (Optional) Additional values file to merge with base values
# $@ - (Optional) Additional helm arguments (after the first positional arg)
deploy_kata() {
local extra_values_file="${1:-}"
shift || true
local extra_helm_args=("$@")
local chart_path
local values_yaml
chart_path="$(get_chart_path)"
values_yaml=$(mktemp)
# Generate base values
generate_base_values "${values_yaml}"
# Add required helm repos for dependencies
helm repo add node-feature-discovery https://kubernetes-sigs.github.io/node-feature-discovery/charts 2>/dev/null || true
helm repo update
# Build helm dependencies
helm dependency build "${chart_path}"
# Build helm command
local helm_cmd=(
helm upgrade --install "${HELM_RELEASE_NAME}" "${chart_path}"
-f "${values_yaml}"
)
# Add extra values file if provided
if [[ -n "${extra_values_file}" && -f "${extra_values_file}" ]]; then
helm_cmd+=(-f "${extra_values_file}")
fi
# Add any extra helm arguments
if [[ ${#extra_helm_args[@]} -gt 0 ]]; then
helm_cmd+=("${extra_helm_args[@]}")
fi
helm_cmd+=(
--namespace "${HELM_NAMESPACE}"
--wait --timeout "${HELM_TIMEOUT:-10m}"
)
# Run helm install
"${helm_cmd[@]}"
local ret=$?
rm -f "${values_yaml}"
if [[ ${ret} -ne 0 ]]; then
echo "Helm install failed with exit code ${ret}" >&2
return ${ret}
fi
# Wait for daemonset to be ready
kubectl -n "${HELM_NAMESPACE}" rollout status daemonset/kata-deploy --timeout=300s
# Give it a moment to configure runtimes
sleep 60
return 0
}
# Uninstall kata-deploy
uninstall_kata() {
helm uninstall "${HELM_RELEASE_NAME}" -n "${HELM_NAMESPACE}" \
--ignore-not-found --wait --cascade foreground --timeout 10m || true
}

View File

@@ -19,7 +19,6 @@ if [[ -n "${KATA_DEPLOY_TEST_UNION:-}" ]]; then
else
KATA_DEPLOY_TEST_UNION=( \
"kata-deploy.bats" \
"kata-deploy-custom-runtimes.bats" \
)
fi

View File

@@ -566,8 +566,11 @@ function helm_helper() {
[[ -n "${HELM_K8S_DISTRIBUTION}" ]] && yq -i ".k8sDistribution = \"${HELM_K8S_DISTRIBUTION}\"" "${values_yaml}"
if [[ "${HELM_DEFAULT_INSTALLATION}" = "false" ]]; then
# Disable all shims at once, then enable only the ones specified in HELM_SHIMS
yq -i ".shims.disableAll = true" "${values_yaml}"
# Disable all shims first (in case we started from an example file with shims enabled)
# Then we'll enable only the ones specified in HELM_SHIMS
for shim_key in $(yq '.shims | keys | .[]' "${values_yaml}" 2>/dev/null); do
yq -i ".shims.${shim_key}.enabled = false" "${values_yaml}"
done
# Use new structured format
if [[ -n "${HELM_DEBUG}" ]]; then
@@ -583,7 +586,7 @@ function helm_helper() {
# HELM_SHIMS is a space-separated list of shim names
# Enable each shim and set supported architectures
# TEE shims that need defaults unset (will be set based on env vars)
tee_shims="qemu-se qemu-se-runtime-rs qemu-cca qemu-snp qemu-snp-runtime-rs qemu-tdx qemu-tdx-runtime-rs qemu-coco-dev qemu-coco-dev-runtime-rs qemu-nvidia-gpu-snp qemu-nvidia-gpu-tdx"
tee_shims="qemu-se qemu-se-runtime-rs qemu-cca qemu-snp qemu-tdx qemu-coco-dev qemu-coco-dev-runtime-rs qemu-nvidia-gpu-snp qemu-nvidia-gpu-tdx"
for shim in ${HELM_SHIMS}; do
# Determine supported architectures based on shim name
@@ -601,11 +604,7 @@ function helm_helper() {
yq -i ".shims.${shim}.enabled = true" "${values_yaml}"
yq -i ".shims.${shim}.supportedArches = [\"amd64\"]" "${values_yaml}"
;;
qemu-runtime-rs)
yq -i ".shims.${shim}.enabled = true" "${values_yaml}"
yq -i ".shims.${shim}.supportedArches = [\"amd64\", \"arm64\", \"s390x\"]" "${values_yaml}"
;;
qemu-coco-dev|qemu-coco-dev-runtime-rs)
qemu-runtime-rs|qemu-coco-dev|qemu-coco-dev-runtime-rs)
yq -i ".shims.${shim}.enabled = true" "${values_yaml}"
yq -i ".shims.${shim}.supportedArches = [\"amd64\", \"s390x\"]" "${values_yaml}"
;;
@@ -679,7 +678,7 @@ function helm_helper() {
# HELM_ALLOWED_HYPERVISOR_ANNOTATIONS: if not in per-shim format (no colon), convert to per-shim format
# Output format: "qemu:foo,bar clh:foo" (space-separated entries, each with shim:annotations where annotations are comma-separated)
# Example: "foo bar" with shim "qemu-tdx" -> "qemu-tdx:foo,bar"
if [[ -n "${HELM_ALLOWED_HYPERVISOR_ANNOTATIONS}" && "${HELM_ALLOWED_HYPERVISOR_ANNOTATIONS}" != *:* ]]; then
if [[ "${HELM_ALLOWED_HYPERVISOR_ANNOTATIONS}" != *:* ]]; then
# Simple format: convert to per-shim format for all enabled shims
# "default_vcpus" -> "qemu-tdx:default_vcpus" (single shim)
# "image kernel default_vcpus" -> "qemu-tdx:image,kernel,default_vcpus" (single shim)
@@ -697,7 +696,7 @@ function helm_helper() {
fi
# HELM_AGENT_HTTPS_PROXY: if not in per-shim format (no equals), convert to per-shim format
if [[ -n "${HELM_AGENT_HTTPS_PROXY}" && "${HELM_AGENT_HTTPS_PROXY}" != *=* ]]; then
if [[ "${HELM_AGENT_HTTPS_PROXY}" != *=* ]]; then
# Simple format: convert to per-shim format for all enabled shims
# "http://proxy:8080" -> "qemu-tdx=http://proxy:8080;qemu-snp=http://proxy:8080"
local converted_proxy=""
@@ -711,7 +710,7 @@ function helm_helper() {
fi
# HELM_AGENT_NO_PROXY: if not in per-shim format (no equals), convert to per-shim format
if [[ -n "${HELM_AGENT_NO_PROXY}" && "${HELM_AGENT_NO_PROXY}" != *=* ]]; then
if [[ "${HELM_AGENT_NO_PROXY}" != *=* ]]; then
# Simple format: convert to per-shim format for all enabled shims
# "localhost,127.0.0.1" -> "qemu-tdx=localhost,127.0.0.1;qemu-snp=localhost,127.0.0.1"
local converted_noproxy=""

View File

@@ -1,7 +1,7 @@
module github.com/kata-containers/tests
// Keep in sync with version in versions.yaml
go 1.24.12
go 1.24.11
// WARNING: Do NOT use `replace` directives as those break dependabot:
// https://github.com/kata-containers/kata-containers/issues/11020

View File

@@ -218,6 +218,15 @@ kbs_set_resource_from_file() {
kbs-client --url "$(kbs_k8s_svc_http_addr)" config \
--auth-private-key "${KBS_PRIVATE_KEY}" set-resource \
--path "${path}" --resource-file "${file}"
kbs_pod=$(kubectl -n "${KBS_NS}" get pods -o NAME)
kbs_repo_path="/opt/confidential-containers/kbs/repository"
# Waiting for the resource to be created on the kbs pod
if ! kubectl -n "${KBS_NS}" exec -it "${kbs_pod}" -- bash -c "for i in {1..30}; do [ -e '${kbs_repo_path}/${path}' ] && exit 0; sleep 0.5; done; exit -1"; then
echo "ERROR: resource '${path}' not created in 15s"
kubectl -n "${KBS_NS}" exec -it "${kbs_pod}" -- bash -c "find ${kbs_repo_path}"
return 1
fi
}
# Build and install the kbs-client binary, unless it is already present.

View File

@@ -1,59 +0,0 @@
#!/usr/bin/env bats
#
# Copyright (c) 2025 NVIDIA Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
load "${BATS_TEST_DIRNAME}/../../common.bash"
load "${BATS_TEST_DIRNAME}/lib.sh"
load "${BATS_TEST_DIRNAME}/tests_common.sh"
setup() {
setup_common || die "setup_common failed"
pod_name="no-layer-image"
get_pod_config_dir
yaml_file="${pod_config_dir}/${pod_name}.yaml"
# genpolicy fails for this unusual container image, so use the allow_all policy.
add_allow_all_policy_to_yaml "${yaml_file}"
}
@test "Test image with no layers cannot run" {
# Error from run-k8s-tests (ubuntu, qemu, small):
#
# failed to create containerd task: failed to create shim task: the file sleep was not found
#
# Error from run-k8s-tests-on-tee (sev-snp, qemu-snp):
#
# failed to create containerd task: failed to create shim task: rpc status:
# Status { code: INTERNAL, message: "[CDH] [ERROR]: Image Pull error: Failed to pull image
# ghcr.io/kata-containers/no-layer-image:latest from all mirror/mapping locations or original location: image:
# ghcr.io/kata-containers/no-layer-image:latest, error: Internal error", details: [], special_fields:
# SpecialFields { unknown_fields: UnknownFields { fields: None }, cached_size: CachedSize { size: 0 } } }
#
# Error from run-k8s-tests-coco-nontee-with-erofs-snapshotter (qemu-coco-dev, erofs, default):
#
# failed to create containerd task: failed to create shim task: failed to mount
# /run/kata-containers/shared/containers/fadd1af7ea2a7bfc6caf26471f70e9a913a2989fd4a1be9d001b59e48c0781aa/rootfs
# to /run/kata-containers/fadd1af7ea2a7bfc6caf26471f70e9a913a2989fd4a1be9d001b59e48c0781aa/rootfs, with error:
# ENOENT: No such file or directory
kubectl create -f "${yaml_file}"
local -r command="kubectl describe "pod/${pod_name}" | grep -E \
'the file sleep was not found|\[CDH\] \[ERROR\]: Image Pull error|ENOENT: No such file or directory'"
info "Waiting ${wait_time} seconds for: ${command}"
waitForProcess "${wait_time}" "${sleep_time}" "${command}" >/dev/null 2>/dev/null
}
teardown() {
# Debugging information
kubectl describe "pod/${pod_name}"
kubectl get "pod/${pod_name}" -o yaml
kubectl delete pod "${pod_name}"
teardown_common "${node}" "${node_start_time:-}"
}

View File

@@ -48,59 +48,12 @@ KBS_AUTH_CONFIG_JSON=$(
)
export KBS_AUTH_CONFIG_JSON
# Base64 encoding for use as Kubernetes Secret in pod manifests (non-TEE)
# Base64 encoding for use as Kubernetes Secret in pod manifests
NGC_API_KEY_BASE64=$(
echo -n "${NGC_API_KEY}" | base64 -w0
)
export NGC_API_KEY_BASE64
# Sealed secret format for TEE pods (vault type pointing to KBS resource)
# Format: sealed.<base64url JWS header>.<base64url payload>.<base64url signature>
# IMPORTANT: JWS uses base64url encoding WITHOUT padding (no trailing '=')
# We use tr to convert standard base64 (+/) to base64url (-_) and remove padding (=)
# For vault type, header and signature can be placeholders since the payload
# contains the KBS resource path where the actual secret is stored.
#
# Vault type sealed secret payload for instruct pod:
# {
# "version": "0.1.0",
# "type": "vault",
# "name": "kbs:///default/ngc-api-key/instruct",
# "provider": "kbs",
# "provider_settings": {},
# "annotations": {}
# }
NGC_API_KEY_SEALED_SECRET_INSTRUCT_PAYLOAD=$(
echo -n '{"version":"0.1.0","type":"vault","name":"kbs:///default/ngc-api-key/instruct","provider":"kbs","provider_settings":{},"annotations":{}}' |
base64 -w0 | tr '+/' '-_' | tr -d '='
)
NGC_API_KEY_SEALED_SECRET_INSTRUCT="sealed.fakejwsheader.${NGC_API_KEY_SEALED_SECRET_INSTRUCT_PAYLOAD}.fakesignature"
export NGC_API_KEY_SEALED_SECRET_INSTRUCT
# Base64 encode the sealed secret for use in Kubernetes Secret data field
# (genpolicy only supports the 'data' field which expects base64 values)
NGC_API_KEY_SEALED_SECRET_INSTRUCT_BASE64=$(echo -n "${NGC_API_KEY_SEALED_SECRET_INSTRUCT}" | base64 -w0)
export NGC_API_KEY_SEALED_SECRET_INSTRUCT_BASE64
# Vault type sealed secret payload for embedqa pod:
# {
# "version": "0.1.0",
# "type": "vault",
# "name": "kbs:///default/ngc-api-key/embedqa",
# "provider": "kbs",
# "provider_settings": {},
# "annotations": {}
# }
NGC_API_KEY_SEALED_SECRET_EMBEDQA_PAYLOAD=$(
echo -n '{"version":"0.1.0","type":"vault","name":"kbs:///default/ngc-api-key/embedqa","provider":"kbs","provider_settings":{},"annotations":{}}' |
base64 -w0 | tr '+/' '-_' | tr -d '='
)
NGC_API_KEY_SEALED_SECRET_EMBEDQA="sealed.fakejwsheader.${NGC_API_KEY_SEALED_SECRET_EMBEDQA_PAYLOAD}.fakesignature"
export NGC_API_KEY_SEALED_SECRET_EMBEDQA
NGC_API_KEY_SEALED_SECRET_EMBEDQA_BASE64=$(echo -n "${NGC_API_KEY_SEALED_SECRET_EMBEDQA}" | base64 -w0)
export NGC_API_KEY_SEALED_SECRET_EMBEDQA_BASE64
setup_langchain_flow() {
# shellcheck disable=SC1091 # Sourcing virtual environment activation script
source "${HOME}"/.cicd/venv/bin/activate
@@ -113,56 +66,18 @@ setup_langchain_flow() {
[[ "$(pip show beautifulsoup4 2>/dev/null | awk '/^Version:/{print $2}')" = "4.13.4" ]] || pip install beautifulsoup4==4.13.4
}
# Create initdata TOML file for genpolicy with CDH configuration.
# This file is used by genpolicy via --initdata-path. Genpolicy will add the
# generated policy.rego to it and set it as the cc_init_data annotation.
# We must overwrite the default empty file AFTER create_tmp_policy_settings_dir()
# copies it to the temp directory.
create_nim_initdata_file() {
local output_file="$1"
local cc_kbs_address
cc_kbs_address=$(kbs_k8s_svc_http_addr)
cat > "${output_file}" << EOF
version = "0.1.0"
algorithm = "sha256"
[data]
"aa.toml" = '''
[token_configs]
[token_configs.kbs]
url = "${cc_kbs_address}"
'''
"cdh.toml" = '''
[kbc]
name = "cc_kbc"
url = "${cc_kbs_address}"
[image]
authenticated_registry_credentials_uri = "kbs:///default/credentials/nvcr"
'''
EOF
}
setup_kbs_credentials() {
# Export KBS address for use in pod YAML templates (aa_kbc_params)
CC_KBS_ADDR=$(kbs_k8s_svc_http_addr)
export CC_KBS_ADDR
# Get KBS address and export it for pod template substitution
export CC_KBS_ADDR="$(kbs_k8s_svc_http_addr)"
kbs_set_gpu0_resource_policy
# Set up Kubernetes secret for the containerd metadata pull
kubectl delete secret ngc-secret-instruct --ignore-not-found
kubectl create secret docker-registry ngc-secret-instruct --docker-server="nvcr.io" --docker-username="\$oauthtoken" --docker-password="${NGC_API_KEY}"
kbs_set_gpu0_resource_policy
# KBS_AUTH_CONFIG_JSON is already base64 encoded
kbs_set_resource_base64 "default" "credentials" "nvcr" "${KBS_AUTH_CONFIG_JSON}"
# Store the actual NGC_API_KEY in KBS for sealed secret unsealing.
# The sealed secrets in the pod YAML point to these KBS resource paths.
kbs_set_resource "default" "ngc-api-key" "instruct" "${NGC_API_KEY}"
kbs_set_resource "default" "ngc-api-key" "embedqa" "${NGC_API_KEY}"
}
create_inference_pod() {
@@ -207,6 +122,10 @@ setup_file() {
export POD_EMBEDQA_YAML_IN="${pod_config_dir}/${POD_NAME_EMBEDQA}.yaml.in"
export POD_EMBEDQA_YAML="${pod_config_dir}/${POD_NAME_EMBEDQA}.yaml"
if [ "${TEE}" = "true" ]; then
setup_kbs_credentials
fi
dpkg -s jq >/dev/null 2>&1 || sudo apt -y install jq
export PYENV_ROOT="${HOME}/.pyenv"
@@ -221,14 +140,6 @@ setup_file() {
policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")"
add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest"
if [ "${TEE}" = "true" ]; then
setup_kbs_credentials
# Overwrite the empty default-initdata.toml with our CDH configuration.
# This must happen AFTER create_tmp_policy_settings_dir() copies the empty
# file and BEFORE auto_generate_policy() runs.
create_nim_initdata_file "${policy_settings_dir}/default-initdata.toml"
fi
create_inference_pod
if [ "${SKIP_MULTI_GPU_TESTS}" != "true" ]; then

View File

@@ -282,7 +282,7 @@ teardown() {
# Debugging information. Don't print the "Message:" line because it contains a truncated policy log.
kubectl describe pod "${pod_name}" | grep -v "Message:"
teardown_common "${node}" "${node_start_time:-}"
# Clean-up
kubectl delete pod "${pod_name}"
kubectl delete configmap "${configmap_name}"
@@ -291,6 +291,4 @@ teardown() {
rm -f "${incorrect_configmap_yaml}"
rm -f "${testcase_pre_generate_pod_yaml}"
rm -f "${testcase_pre_generate_configmap_yaml}"
teardown_common "${node}" "${node_start_time:-}"
}

View File

@@ -62,11 +62,9 @@ teardown() {
# Debugging information. Don't print the "Message:" line because it contains a truncated policy log.
kubectl describe pod "${pod_name}" | grep -v "Message:"
teardown_common "${node}" "${node_start_time:-}"
# Clean-up
kubectl delete -f "${correct_pod_yaml}"
kubectl delete -f "${pvc_yaml}"
rm -f "${incorrect_pod_yaml}"
teardown_common "${node}" "${node_start_time:-}"
}

View File

@@ -42,7 +42,6 @@ else
)
K8S_TEST_SMALL_HOST_UNION=( \
"k8s-empty-image.bats" \
"k8s-guest-pull-image.bats" \
"k8s-confidential.bats" \
"k8s-sealed-secret.bats" \

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: busybox
spec:
terminationGracePeriodSeconds: 0
shareProcessNamespace: true
runtimeClassName: kata
containers:

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: POD_NAME
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
shareProcessNamespace: true
containers:

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: initcontainer-shared-volume
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
initContainers:
- name: first

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: busybox
spec:
terminationGracePeriodSeconds: 0
shareProcessNamespace: true
runtimeClassName: kata
initContainers:

View File

@@ -16,6 +16,7 @@ spec:
labels:
jobgroup: jobtest
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test

View File

@@ -10,6 +10,7 @@ metadata:
spec:
template:
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: pi

View File

@@ -23,6 +23,7 @@ spec:
role: master
tier: backend
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
securityContext:
runAsUser: 2000

View File

@@ -23,6 +23,7 @@ spec:
role: master
tier: backend
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
securityContext:
runAsUser: 2000

View File

@@ -23,6 +23,7 @@ spec:
role: master
tier: backend
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
securityContext:
runAsUser: 65534

View File

@@ -23,6 +23,7 @@ spec:
role: master
tier: backend
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
securityContext:
runAsUser: 2000

View File

@@ -23,6 +23,7 @@ spec:
role: master
tier: backend
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
securityContext:
runAsUser: 1000

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: hard-coded-policy-pod
spec:
terminationGracePeriodSeconds: 0
shareProcessNamespace: true
runtimeClassName: kata
containers:

View File

@@ -10,6 +10,7 @@ metadata:
spec:
template:
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: hello

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: policy-pod-pvc
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: busybox

View File

@@ -9,6 +9,7 @@ metadata:
name: policy-pod
uid: policy-pod-uid
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: prometheus

View File

@@ -17,6 +17,7 @@ spec:
labels:
app: policy-nginx-rc
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: nginxtest

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: set-keys-test
spec:
terminationGracePeriodSeconds: 0
shareProcessNamespace: true
runtimeClassName: kata
containers:

View File

@@ -9,6 +9,7 @@ kind: Pod
metadata:
name: handlers
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: handlers-container

View File

@@ -17,6 +17,7 @@ spec:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: nginx

View File

@@ -1,13 +0,0 @@
apiVersion: v1
kind: Pod
metadata:
name: no-layer-image
spec:
runtimeClassName: kata
containers:
- name: no-layer-image
image: ghcr.io/kata-containers/no-layer-image:latest
resources: {}
command:
- sleep
- infinity

View File

@@ -10,11 +10,7 @@ metadata:
labels:
app: ${POD_NAME_INSTRUCT}
annotations:
# Start CDH process and configure AA for KBS communication
# aa_kbc_params tells the Attestation Agent where KBS is located
io.katacontainers.config.hypervisor.kernel_params: "agent.guest_components_procs=confidential-data-hub agent.aa_kbc_params=cc_kbc::${CC_KBS_ADDR}"
# cc_init_data annotation will be added by genpolicy with CDH configuration
# from the custom default-initdata.toml created by create_nim_initdata_file()
io.katacontainers.config.hypervisor.kernel_params: "agent.image_registry_auth=kbs:///default/credentials/nvcr agent.aa_kbc_params=cc_kbc::${CC_KBS_ADDR}"
spec:
restartPolicy: Never
runtimeClassName: kata
@@ -62,7 +58,7 @@ spec:
- name: NGC_API_KEY
valueFrom:
secretKeyRef:
name: ngc-api-key-sealed-instruct
name: ngc-api-key-instruct
key: api-key
# GPU resource limit (for NVIDIA GPU)
resources:
@@ -82,9 +78,7 @@ data:
apiVersion: v1
kind: Secret
metadata:
name: ngc-api-key-sealed-instruct
name: ngc-api-key-instruct
type: Opaque
data:
# Sealed secret pointing to kbs:///default/ngc-api-key/instruct
# CDH will unseal this by fetching the actual key from KBS
api-key: "${NGC_API_KEY_SEALED_SECRET_INSTRUCT_BASE64}"
api-key: "${NGC_API_KEY_BASE64}"

View File

@@ -10,11 +10,7 @@ metadata:
labels:
app: ${POD_NAME_EMBEDQA}
annotations:
# Start CDH process and configure AA for KBS communication
# aa_kbc_params tells the Attestation Agent where KBS is located
io.katacontainers.config.hypervisor.kernel_params: "agent.guest_components_procs=confidential-data-hub agent.aa_kbc_params=cc_kbc::${CC_KBS_ADDR}"
# cc_init_data annotation will be added by genpolicy with CDH configuration
# from the custom default-initdata.toml created by create_nim_initdata_file()
io.katacontainers.config.hypervisor.kernel_params: "agent.image_registry_auth=kbs:///default/credentials/nvcr agent.aa_kbc_params=cc_kbc::${CC_KBS_ADDR}"
spec:
restartPolicy: Always
runtimeClassName: kata
@@ -33,7 +29,7 @@ spec:
- name: NGC_API_KEY
valueFrom:
secretKeyRef:
name: ngc-api-key-sealed-embedqa
name: ngc-api-key-embedqa
key: api-key
- name: NIM_HTTP_API_PORT
value: "8000"
@@ -92,9 +88,7 @@ data:
apiVersion: v1
kind: Secret
metadata:
name: ngc-api-key-sealed-embedqa
name: ngc-api-key-embedqa
type: Opaque
data:
# Sealed secret pointing to kbs:///default/ngc-api-key/embedqa
# CDH will unseal this by fetching the actual key from KBS
api-key: "${NGC_API_KEY_SEALED_SECRET_EMBEDQA_BASE64}"
api-key: "${NGC_API_KEY_BASE64}"

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: besteffort-test
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: qos-besteffort

View File

@@ -3,6 +3,7 @@ kind: Pod
metadata:
name: pod-block-pv
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: my-container

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: burstable-test
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: qos-burstable

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: pod-caps
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test-container

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: config-env-test-pod
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test-container

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: default-cpu-test
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: default-cpu-demo-ctr

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: constraints-cpu-test
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: first-cpu-container

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: custom-dns-test
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: sharevol-kata
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: test-env
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test-container

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: test-file-volume
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
restartPolicy: Never
nodeName: NODE

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: footubuntu
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
volumes:
- name: runv

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: qos-test
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: qos-guaranteed

View File

@@ -9,6 +9,7 @@ kind: Pod
metadata:
name: test-pod-hostname
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
restartPolicy: Never
containers:

View File

@@ -9,6 +9,7 @@ kind: Pod
metadata:
name: hostpath-kmsg
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
restartPolicy: Never
volumes:

View File

@@ -10,6 +10,7 @@ metadata:
test: liveness-test
name: liveness-http
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: liveness

View File

@@ -10,6 +10,7 @@ metadata:
test: liveness
name: liveness-exec
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: liveness

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: memory-test
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: memory-test-ctr

View File

@@ -23,6 +23,7 @@ kind: Pod
metadata:
name: nested-configmap-secret-pod
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test-container

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: cpu-test
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: c1

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: optional-empty-config-test-pod
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test-container

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: optional-empty-secret-test-pod
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test-container

View File

@@ -9,6 +9,7 @@ kind: Pod
metadata:
name: privileged
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
restartPolicy: Never
containers:

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: test-projected-volume
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: test-projected-volume

View File

@@ -17,6 +17,7 @@ spec:
labels:
purpose: quota-demo
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
containers:
- name: pod-quota-demo

View File

@@ -8,6 +8,7 @@ kind: Pod
metadata:
name: test-readonly-volume
spec:
terminationGracePeriodSeconds: 0
runtimeClassName: kata
restartPolicy: Never
volumes:

View File

@@ -11,6 +11,7 @@ metadata:
io.katacontainers.config.runtime.disable_guest_seccomp: "false"
spec:
runtimeClassName: kata
terminationGracePeriodSeconds: 0
restartPolicy: Never
containers:
- name: busybox

Some files were not shown because too many files have changed in this diff Show More