Compare commits

...

28 Commits

Author SHA1 Message Date
Fabiano Fidêncio
bd6377a038 Merge pull request #12614 from manuelh-dev/mahuber/image-signing-nim
tests: nvidia: Enforce image signing for NIM test
2026-04-11 14:48:04 +02:00
Fabiano Fidêncio
5eb7844183 Merge pull request #12430 from stevenhorsman/cargo-deny-static-checks
static-checks: Rework cargo deny check
2026-04-11 12:05:53 +02:00
stevenhorsman
8be3a24112 ci: Update cargo-deny in gatekeeper
Update the name and move it to the static checks as we don't
need to ensure it's running for none code changes.

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-04-11 08:46:32 +01:00
stevenhorsman
9448988783 workflow: Update cargo deny check
The cargo deny generated action doesn't seem to work
and seems unnecessarily complex, so try using
EmbarkStudios/cargo-deny-action instead

Fixes: #11218
Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-04-11 08:46:32 +01:00
stevenhorsman
a0410e0d5c static-checks: Update cargo deny config
The previous config is not valid, so update it based on information
from https://embarkstudios.github.io/cargo-deny/checks/cfg.html

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-04-11 08:46:32 +01:00
stevenhorsman
a32c6fd9ff mem-agent: Add package metadata
Make the authors, edition and license be inherited from the
workspace

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-04-11 08:46:32 +01:00
stevenhorsman
5bcc006447 runtime-rs: Add missing license
The ch-config crate was missing a license

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-04-11 08:46:32 +01:00
Manuel Huber
7daeb78b67 tests: nvidia: Enforce image signing for NIM test
Validate container image signatures for the NIM test using NVIDIA's
public signing key.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-04-11 09:22:50 +02:00
Fabiano Fidêncio
3ce3644c3c Merge pull request #12807 from PiotrProkop/blk-sector-rust
runtime-rs: allow specifying logical/physical sector size for block devices
2026-04-11 00:42:45 +02:00
Fabiano Fidêncio
6f3c11aec4 Merge pull request #12808 from fidencio/topic/agent-allow-configuring-launch-process-timeout
agent: Make launch_process_timeout configurable
2026-04-11 00:36:01 +02:00
Fabiano Fidêncio
d4a042a155 Merge pull request #12813 from fitzthum/bump-gc-ma-sigs
Bump guest components to pickup additional signature support
2026-04-10 23:57:19 +02:00
Fabiano Fidêncio
78fa4c88e2 Merge pull request #12814 from fidencio/topic/nvidia-always-do-vcpu-pinning
runtime: Set `enable_vcpus_pinning = true` for NVIDIA configs
2026-04-10 23:47:44 +02:00
Fabiano Fidêncio
7244389ad4 runtime: Set enable_vcpus_pinning = true for NVIDIA configs
So we can have a better performance by default.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-10 16:41:34 +02:00
Fabiano Fidêncio
1d77c4e60f Merge pull request #12752 from LizZhang315/add-overheadEnabled
helm: add overheadEnabled switch for runtimeclass
2026-04-10 16:40:42 +02:00
Tobin Feldman-Fitzthum
ff26a6b876 versions: update image-rs to pickup signature fixes
The new version of image-rs supports more types of signed images. First,
we added supported for a few more key types. Second, we added support
for multi-arch images where the manifest digest is signed but the
individual arch manifest is not. These images are relatively common, so
let's pickup the fix asap.

Signed-off-by: Tobin Feldman-Fitzthum <tfeldmanfitz@nvidia.com>
2026-04-10 06:54:58 -07:00
Tobin Feldman-Fitzthum
2588a0e5a5 agent-ctl: bump image-rs version
I don't think agent-ctl will benefit from the new image-rs features, but
let's update it to be complete.

Signed-off-by: Tobin Feldman-Fitzthum <tfeldmanfitz@nvidia.com>
2026-04-10 06:52:53 -07:00
Fabiano Fidêncio
e8f34a2b26 agent: Update protocol
This is not related to this PR, but rather to #12734, which ended up not
running the `make src/agent generate-protocols`.

While here, let's also fix it.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-10 14:47:01 +02:00
Fabiano Fidêncio
36a2d8e7f2 agent: Make launch_process_timeout configurable
The hardcoded DEFAULT_LAUNCH_PROCESS_TIMEOUT of 6 seconds in the kata
agent is insufficient for environments with NVIDIA GPUs and NVSwitches,
where the attestation-agent needs significantly more time to collect
evidence during initialization (e.g. ~2 seconds per NVSwitch).

When the timeout expires, the agent (PID 1) exits with an error, causing
the guest kernel to perform an orderly shutdown before the
attestation-agent has finished starting.

Make this timeout configurable via the kernel parameter
agent.launch_process_timeout (in seconds), preserving the 6-second
default for backward compatibility. The Go runtime is wired up to pass
this value from the TOML config's [agent.kata] section through to the
kernel command line.

The NVIDIA GPU configs set the new default to 15 seconds.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Made-with: Cursor
2026-04-10 14:47:01 +02:00
PiotrProkop
82de35c720 runtime-rs: allow specifying logical/physical sector size for block devices
Add two new configuration knobs that control the logical and physical
sector sizes advertised by virtio-blk devices to the guest:

  block_device_logical_sector_size  (config file)
  block_device_physical_sector_size (config file)

  io.katacontainers.config.hypervisor.blk_logical_sector_size  (annotation)
  io.katacontainers.config.hypervisor.blk_physical_sector_size (annotation)

The annotation names are abbreviated relative to the config file keys
because Kubernetes enforces a 63-character limit on annotation name
segments, and the full names would exceed it.

Both settings default to 0 (let QEMU decide). When set, they are passed
as logical_block_size and physical_block_size in the QMP device_add
command during block device hotplug.

Setting logical_sector_size smaller then container filesystem
block size will cause EINVAL on mount. The physical_sector_size can
always be set independently.

Values must be 0 or a power of 2 in the range [512, 65536]; other
values are rejected with an error at sandbox creation time.

Signed-off-by: PiotrProkop <pprokop@nvidia.com>
2026-04-10 11:14:51 +02:00
Fabiano Fidêncio
fd6375d8d5 Merge pull request #12806 from kata-containers/topic/ci-run-runtime-rs-on-SNP
ci: Run qemu-snp-runtime-rs tests in the CI
2026-04-10 11:01:20 +02:00
LizZhang315
2312f67c9b helm: add overheadEnabled switch for runtimeclass
Add a global and per-shim configurable switch to enable/disable
the overhead section in generated RuntimeClasses. This allows users
to omit overhead when it's not needed or managed externally.

Priority: per-shim > global > default(true).

Signed-off-by: LizZhang315 <123134987@qq.com>
2026-04-10 10:26:11 +02:00
Fabiano Fidêncio
218077506b Merge pull request #12769 from RuoqingHe/runtime-rs-allow-install-on-riscv
runtime-rs: Allow installation on RISC-V platforms
2026-04-10 10:24:40 +02:00
Fabiano Fidêncio
dca89485f0 Merge pull request #12802 from stevenhorsman/bump-golang-1.25.9
versions: bump golang to 1.25.9
2026-04-10 06:50:35 +02:00
Fabiano Fidêncio
5e1ab0aa7d tests: Support runtime-rs QEMU cmdline format in attestation test
The k8s-confidential-attestation test extracts the QEMU command line
from journal logs to compute the SNP launch measurement. It only
matched the Go runtime's log format ("launching <path> with: [<args>]"),
but runtime-rs logs differently ("qemu args: <args>").

Handle both formats so the test works with qemu-snp-runtime-rs.

Made-with: Cursor
Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-09 16:35:08 +02:00
Fabiano Fidêncio
3b155ab0b1 ci: Run runtime-rs tests for SNP
As we're in the process to stabilise runtime-rs for the coming 4.0.0
release, we better start running as many tests as possible with that.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-09 16:35:08 +02:00
stevenhorsman
31f9a5461b versions: bump golang to 1.25.9
Bump the go version to resolve CVEs:
- GO-2026-4947
- GO-2026-4946
- GO-2026-4870
- GO-2026-4869
- GO-2026-4865
- GO-2026-4864

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-04-09 08:59:40 +01:00
Ruoqing He
98ee385220 runtime-rs: Consolidate unsupported arch
Consolidate arch we don't support at the moment, and avoid hard coding
error messages per arch.

Signed-off-by: Ruoqing He <ruoqing.he@lingcage.com>
2026-04-09 04:18:50 +00:00
Ruoqing He
26ffe1223b runtime-rs: Allow install on riscv64 platform
runtime-rs works with QEMU on RISC-V platforms, let's enable
installation on RISC-V.

Signed-off-by: Ruoqing He <ruoqing.he@lingcage.com>
2026-04-09 04:18:50 +00:00
64 changed files with 2130 additions and 1124 deletions

View File

@@ -1,40 +0,0 @@
#!/bin/bash
#
# Copyright (c) 2022 Red Hat
#
# SPDX-License-Identifier: Apache-2.0
#
script_dir=$(dirname "$(readlink -f "$0")")
parent_dir=$(realpath "${script_dir}/../..")
cidir="${parent_dir}/ci"
source "${cidir}/../tests/common.bash"
cargo_deny_file="${script_dir}/action.yaml"
cat cargo-deny-skeleton.yaml.in > "${cargo_deny_file}"
changed_files_status=$(run_get_pr_changed_file_details)
changed_files_status=$(echo "$changed_files_status" | grep "Cargo\.toml$" || true)
changed_files=$(echo "$changed_files_status" | awk '{print $NF}' || true)
if [ -z "$changed_files" ]; then
cat >> "${cargo_deny_file}" << EOF
- run: echo "No Cargo.toml files to check"
shell: bash
EOF
fi
for path in $changed_files
do
cat >> "${cargo_deny_file}" << EOF
- name: ${path}
continue-on-error: true
shell: bash
run: |
pushd $(dirname ${path})
cargo deny check
popd
EOF
done

View File

@@ -1,30 +0,0 @@
#
# Copyright (c) 2022 Red Hat
#
# SPDX-License-Identifier: Apache-2.0
#
name: 'Cargo Crates Check'
description: 'Checks every Cargo.toml file using cargo-deny'
env:
CARGO_TERM_COLOR: always
runs:
using: "composite"
steps:
- name: Install Rust
uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f # v1.0.6
with:
profile: minimal
toolchain: nightly
override: true
- name: Cache
uses: Swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2.7.7
- name: Install Cargo deny
shell: bash
run: |
which cargo
cargo install --locked cargo-deny || true

View File

@@ -1,32 +0,0 @@
name: Cargo Crates Check Runner
on:
pull_request:
types:
- opened
- edited
- reopened
- synchronize
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
cargo-deny-runner:
name: cargo-deny-runner
runs-on: ubuntu-22.04
steps:
- name: Checkout Code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Generate Action
run: bash cargo-deny-generator.sh
working-directory: ./.github/cargo-deny-composite-action/
env:
GOPATH: ${{ github.workspace }}/kata-containers
- name: Run Action
uses: ./.github/cargo-deny-composite-action

38
.github/workflows/cargo-deny.yaml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: Cargo Deny Check
on:
workflow_dispatch:
pull_request:
types:
- opened
- edited
- reopened
- synchronize
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
cargo-deny:
name: cargo-deny
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
checks:
# Note: advisories checks are currently covered in OSV-scanner instead
- bans licenses sources
steps:
- name: Checkout the code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
- name: Run the cargo deny check ( ${{ matrix.checks }})
uses: EmbarkStudios/cargo-deny-action@3fd3802e88374d3fe9159b834c7714ec57d6c979 #2.0.15
with:
command: check ${{ matrix.checks }}

View File

@@ -53,6 +53,8 @@ jobs:
vmm: qemu-tdx
- runner: sev-snp
vmm: qemu-snp
- runner: sev-snp
vmm: qemu-snp-runtime-rs
runs-on: ${{ matrix.runner }}
env:
DOCKER_REGISTRY: ${{ inputs.registry }}

View File

@@ -1,32 +1,38 @@
[graph]
targets = [
{ triple = "x86_64-apple-darwin" },
{ triple = "x86_64-unknown-linux-gnu" },
{ triple = "x86_64-unknown-linux-musl" },
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
"aarch64-apple-darwin",
"x86_64-apple-darwin",
]
[advisories]
vulnerability = "deny"
unsound = "deny"
unmaintained = "deny"
ignore = ["RUSTSEC-2020-0071"]
unmaintained = "workspace"
unsound = "workspace"
ignore = []
[bans]
multiple-versions = "allow"
deny = [
{ name = "cmake" },
{ name = "openssl-sys" },
]
deny = []
[licenses]
unlicensed = "deny"
allow-osi-fsf-free = "neither"
copyleft = "allow"
# We want really high confidence when inferring licenses from text
confidence-threshold = 0.93
allow = ["0BSD", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "CC0-1.0", "ISC", "MIT", "MPL-2.0"]
private = { ignore = true}
exceptions = []
allow = [
"0BSD",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"CC0-1.0",
"ISC",
"MIT",
"MIT-0",
"MPL-2.0",
"Unicode-3.0",
"Zlib",
]
private = { ignore = true }
[sources]
unknown-registry = "allow"

View File

@@ -25,6 +25,7 @@ const HOTPLUG_TIMOUT_OPTION: &str = "agent.hotplug_timeout";
const CDH_API_TIMOUT_OPTION: &str = "agent.cdh_api_timeout";
const CDH_IMAGE_PULL_TIMEOUT_OPTION: &str = "agent.image_pull_timeout";
const CDI_TIMEOUT_OPTION: &str = "agent.cdi_timeout";
const LAUNCH_PROCESS_TIMEOUT_OPTION: &str = "agent.launch_process_timeout";
const DEBUG_CONSOLE_VPORT_OPTION: &str = "agent.debug_console_vport";
const LOG_VPORT_OPTION: &str = "agent.log_vport";
const CONTAINER_PIPE_SIZE_OPTION: &str = "agent.container_pipe_size";
@@ -66,6 +67,7 @@ const DEFAULT_HOTPLUG_TIMEOUT: time::Duration = time::Duration::from_secs(3);
const DEFAULT_CDH_API_TIMEOUT: time::Duration = time::Duration::from_secs(50);
const DEFAULT_IMAGE_PULL_TIMEOUT: time::Duration = time::Duration::from_secs(1200);
const DEFAULT_CDI_TIMEOUT: time::Duration = time::Duration::from_secs(100);
const DEFAULT_LAUNCH_PROCESS_TIMEOUT: time::Duration = time::Duration::from_secs(6);
const DEFAULT_CONTAINER_PIPE_SIZE: i32 = 0;
const VSOCK_ADDR: &str = "vsock://-1";
@@ -130,6 +132,7 @@ pub struct AgentConfig {
pub cdh_api_timeout: time::Duration,
pub image_pull_timeout: time::Duration,
pub cdi_timeout: time::Duration,
pub launch_process_timeout: time::Duration,
pub debug_console_vport: i32,
pub log_vport: i32,
pub container_pipe_size: i32,
@@ -163,6 +166,7 @@ pub struct AgentConfigBuilder {
pub cdh_api_timeout: Option<time::Duration>,
pub image_pull_timeout: Option<time::Duration>,
pub cdi_timeout: Option<time::Duration>,
pub launch_process_timeout: Option<time::Duration>,
pub debug_console_vport: Option<i32>,
pub log_vport: Option<i32>,
pub container_pipe_size: Option<i32>,
@@ -257,6 +261,7 @@ impl Default for AgentConfig {
cdh_api_timeout: DEFAULT_CDH_API_TIMEOUT,
image_pull_timeout: DEFAULT_IMAGE_PULL_TIMEOUT,
cdi_timeout: DEFAULT_CDI_TIMEOUT,
launch_process_timeout: DEFAULT_LAUNCH_PROCESS_TIMEOUT,
debug_console_vport: 0,
log_vport: 0,
container_pipe_size: DEFAULT_CONTAINER_PIPE_SIZE,
@@ -298,6 +303,7 @@ impl FromStr for AgentConfig {
config_override!(agent_config_builder, agent_config, cdh_api_timeout);
config_override!(agent_config_builder, agent_config, image_pull_timeout);
config_override!(agent_config_builder, agent_config, cdi_timeout);
config_override!(agent_config_builder, agent_config, launch_process_timeout);
config_override!(agent_config_builder, agent_config, debug_console_vport);
config_override!(agent_config_builder, agent_config, log_vport);
config_override!(agent_config_builder, agent_config, container_pipe_size);
@@ -481,6 +487,14 @@ impl AgentConfig {
|cdi_timeout: &time::Duration| cdi_timeout.as_secs() > 0
);
parse_cmdline_param!(
param,
LAUNCH_PROCESS_TIMEOUT_OPTION,
config.launch_process_timeout,
get_timeout,
|launch_process_timeout: &time::Duration| launch_process_timeout.as_secs() > 0
);
// vsock port should be positive values
parse_cmdline_param!(
param,
@@ -742,6 +756,7 @@ fn get_timeout(param: &str) -> Result<time::Duration> {
| CDH_API_TIMOUT_OPTION
| CDH_IMAGE_PULL_TIMEOUT_OPTION
| CDI_TIMEOUT_OPTION
| LAUNCH_PROCESS_TIMEOUT_OPTION
),
ERR_INVALID_TIMEOUT_KEY
);
@@ -1630,6 +1645,7 @@ Caused by:
#[case("agent.cdh_api_timeout=600", Ok(time::Duration::from_secs(600)))]
#[case("agent.image_pull_timeout=1200", Ok(time::Duration::from_secs(1200)))]
#[case("agent.cdi_timeout=320", Ok(time::Duration::from_secs(320)))]
#[case("agent.launch_process_timeout=60", Ok(time::Duration::from_secs(60)))]
fn test_timeout(#[case] param: &str, #[case] expected: Result<time::Duration>) {
let result = get_timeout(param);
let msg = format!("expected: {expected:?}, result: {result:?}");

View File

@@ -111,8 +111,6 @@ const API_SERVER_PATH: &str = "/usr/local/bin/api-server-rest";
/// TODO: remove this when we move the launch of CDH out of the kata-agent.
const OCICRYPT_CONFIG_PATH: &str = "/etc/ocicrypt_config.json";
const DEFAULT_LAUNCH_PROCESS_TIMEOUT: i32 = 6;
lazy_static! {
static ref AGENT_CONFIG: AgentConfig =
// Note: We can't do AgentOpts.parse() here to send through the processed arguments to AgentConfig
@@ -505,7 +503,7 @@ async fn launch_guest_component_procs(
aa_args,
Some(AA_CONFIG_PATH),
AA_ATTESTATION_SOCKET,
DEFAULT_LAUNCH_PROCESS_TIMEOUT,
config.launch_process_timeout.as_secs(),
&[],
)
.await
@@ -527,7 +525,7 @@ async fn launch_guest_component_procs(
vec![],
Some(CDH_CONFIG_PATH),
CDH_SOCKET,
DEFAULT_LAUNCH_PROCESS_TIMEOUT,
config.launch_process_timeout.as_secs(),
&[("OCICRYPT_KEYPROVIDER_CONFIG", OCICRYPT_CONFIG_PATH)],
)
.await
@@ -587,7 +585,7 @@ async fn init_attestation_components(
Ok(())
}
async fn wait_for_path_to_exist(logger: &Logger, path: &str, timeout_secs: i32) -> Result<()> {
async fn wait_for_path_to_exist(logger: &Logger, path: &str, timeout_secs: u64) -> Result<()> {
let p = Path::new(path);
let mut attempts = 0;
loop {
@@ -614,7 +612,7 @@ async fn launch_process(
mut args: Vec<&str>,
config: Option<&str>,
unix_socket_path: &str,
timeout_secs: i32,
timeout_secs: u64,
envs: &[(&str, &str)],
) -> Result<()> {
if !Path::new(path).exists() {

View File

@@ -284,6 +284,20 @@ pub const KATA_ANNO_CFG_HYPERVISOR_DEFAULT_GPUS: &str =
pub const KATA_ANNO_CFG_HYPERVISOR_DEFAULT_GPU_MODEL: &str =
"io.katacontainers.config.hypervisor.default_gpu_model";
/// A sandbox annotation that specifies the logical sector size reported by block devices to the
/// guest, in bytes. Common values are 512 and 4096. Set to 0 to use the hypervisor default.
/// NOTE: the annotation key uses "blk_logical_sector_size" rather than
/// "block_device_logical_sector_size" because Kubernetes enforces a 63-character limit on
/// annotation name segments.
pub const KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE: &str =
"io.katacontainers.config.hypervisor.blk_logical_sector_size";
/// A sandbox annotation that specifies the physical sector size reported by block devices to the
/// guest, in bytes. Common values are 512 and 4096. Set to 0 to use the hypervisor default.
/// NOTE: the annotation key uses "blk_physical_sector_size" rather than
/// "block_device_physical_sector_size" because Kubernetes enforces a 63-character limit on
/// annotation name segments.
pub const KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE: &str =
"io.katacontainers.config.hypervisor.blk_physical_sector_size";
/// Block device specific annotation for num_queues
pub const KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_NUM_QUEUES: &str =
"io.katacontainers.config.hypervisor.block_device_num_queues";
@@ -973,6 +987,48 @@ impl Annotation {
hv.shared_fs.virtio_fs_extra_args.push(arg.to_string());
}
}
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE => {
match self.get_value::<u32>(key) {
Ok(v) => {
let size = v.unwrap_or_default();
if let Err(e) =
crate::config::hypervisor::validate_block_device_sector_size(
size,
)
{
return Err(io::Error::new(
io::ErrorKind::InvalidData,
e.to_string(),
));
}
hv.blockdev_info.block_device_logical_sector_size = size;
}
Err(_e) => {
return Err(u32_err);
}
}
}
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE => {
match self.get_value::<u32>(key) {
Ok(v) => {
let size = v.unwrap_or_default();
if let Err(e) =
crate::config::hypervisor::validate_block_device_sector_size(
size,
)
{
return Err(io::Error::new(
io::ErrorKind::InvalidData,
e.to_string(),
));
}
hv.blockdev_info.block_device_physical_sector_size = size;
}
Err(_e) => {
return Err(u32_err);
}
}
}
KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_NUM_QUEUES => {
match self.get_value::<usize>(key) {
Ok(v) => {
@@ -1123,6 +1179,18 @@ impl Annotation {
}
}
// Validate cross-field constraint: logical sector size must not exceed physical.
// Individual sizes are validated inside the loop, but the cross-field check must
// run after both annotations have been applied.
let logical = hv.blockdev_info.block_device_logical_sector_size;
let physical = hv.blockdev_info.block_device_physical_sector_size;
if logical != 0 && physical != 0 && logical > physical {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("invalid sector sizes: logical ({logical}) must not be larger than physical ({physical})"),
));
}
config.adjust_config()?;
Ok(())

View File

@@ -146,6 +146,11 @@ pub struct Agent {
#[serde(default)]
pub container_pipe_size: u32,
/// Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
/// to create their Unix sockets after being spawned by the agent.
#[serde(default)]
pub launch_process_timeout: u32,
/// Memory agent configuration
#[serde(default)]
pub mem_agent: MemAgent,
@@ -180,6 +185,7 @@ impl std::default::Default for Agent {
health_check_request_timeout_ms: 90_000,
kernel_modules: Default::default(),
container_pipe_size: 0,
launch_process_timeout: 0,
mem_agent: MemAgent::default(),
policy: Default::default(),
}

View File

@@ -271,6 +271,18 @@ pub struct BlockDeviceInfo {
#[serde(default)]
pub block_device_cache_noflush: bool,
/// Specifies the logical sector size, in bytes, reported by block devices to the guest.
/// Common values are 512 and 4096. Set to 0 to use the hypervisor default.
/// Must be 0 or a power of 2 between 512 and 65536.
#[serde(default)]
pub block_device_logical_sector_size: u32,
/// Specifies the physical sector size, in bytes, reported by block devices to the guest.
/// Common values are 512 and 4096. Set to 0 to use the hypervisor default.
/// Must be 0 or a power of 2 between 512 and 65536.
#[serde(default)]
pub block_device_physical_sector_size: u32,
/// If false and nvdimm is supported, use nvdimm device to plug guest image.
#[serde(default)]
pub disable_image_nvdimm: bool,
@@ -400,6 +412,16 @@ impl BlockDeviceInfo {
"Invalid vhost-user-store-path {}: {}"
)?;
validate_block_device_sector_size(self.block_device_logical_sector_size)?;
validate_block_device_sector_size(self.block_device_physical_sector_size)?;
let logical = self.block_device_logical_sector_size;
let physical = self.block_device_physical_sector_size;
if logical != 0 && physical != 0 && logical > physical {
return Err(std::io::Error::other(format!(
"invalid sector sizes: logical ({logical}) must not be larger than physical ({physical})"
)));
}
Ok(())
}
@@ -409,6 +431,19 @@ impl BlockDeviceInfo {
}
}
/// Validate that a block device sector size is 0 or a power of 2 in [512, 65536].
pub fn validate_block_device_sector_size(size: u32) -> Result<()> {
if size == 0 {
return Ok(());
}
if !(512..=65536).contains(&size) || (size & (size - 1)) != 0 {
return Err(std::io::Error::other(format!(
"invalid sector size {size}: must be 0 or a power of 2 between 512 and 65536"
)));
}
Ok(())
}
/// Guest kernel boot information.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct BootInfo {
@@ -2072,4 +2107,83 @@ mod tests {
expected_error_msg
);
}
#[test]
fn test_validate_block_device_sector_size_valid() {
for size in [0, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536] {
assert!(
validate_block_device_sector_size(size).is_ok(),
"expected size {} to be accepted",
size
);
}
}
#[test]
fn test_validate_block_device_sector_size_not_power_of_two() {
for size in [3, 100, 1000, 3000, 5000] {
assert!(
validate_block_device_sector_size(size).is_err(),
"expected non-power-of-2 size {} to be rejected",
size
);
}
}
#[test]
fn test_validate_block_device_sector_size_below_minimum() {
for size in [1, 256] {
assert!(
validate_block_device_sector_size(size).is_err(),
"expected below-minimum size {} to be rejected",
size
);
}
}
#[test]
fn test_validate_block_device_sector_size_above_maximum() {
for size in [131072, 1048576] {
assert!(
validate_block_device_sector_size(size).is_err(),
"expected above-maximum size {} to be rejected",
size
);
}
}
fn blockdev_info_with_sectors(logical: u32, physical: u32) -> BlockDeviceInfo {
BlockDeviceInfo {
block_device_driver: VIRTIO_BLK_PCI.to_string(),
block_device_logical_sector_size: logical,
block_device_physical_sector_size: physical,
..Default::default()
}
}
#[test]
fn test_validate_block_device_sector_sizes_valid() {
assert!(blockdev_info_with_sectors(0, 0).validate().is_ok());
assert!(blockdev_info_with_sectors(512, 0).validate().is_ok());
assert!(blockdev_info_with_sectors(0, 4096).validate().is_ok());
assert!(blockdev_info_with_sectors(512, 4096).validate().is_ok());
assert!(blockdev_info_with_sectors(4096, 4096).validate().is_ok());
assert!(blockdev_info_with_sectors(512, 512).validate().is_ok());
}
#[test]
fn test_validate_block_device_sector_sizes_logical_exceeds_physical() {
assert!(
blockdev_info_with_sectors(4096, 512).validate().is_err(),
"logical > physical should be rejected"
);
assert!(
blockdev_info_with_sectors(4096, 1024).validate().is_err(),
"logical > physical should be rejected"
);
assert!(
blockdev_info_with_sectors(65536, 512).validate().is_err(),
"logical > physical should be rejected"
);
}
}

View File

@@ -54,6 +54,8 @@ pub const DEBUG_CONSOLE_VPORT_OPTION: &str = "agent.debug_console_vport";
pub const LOG_VPORT_OPTION: &str = "agent.log_vport";
/// Option of setting the container's pipe size
pub const CONTAINER_PIPE_SIZE_OPTION: &str = "agent.container_pipe_size";
/// Option of setting the guest component launch process timeout
pub const LAUNCH_PROCESS_TIMEOUT_OPTION: &str = "agent.launch_process_timeout";
/// Option of setting the fd passthrough io listener port
pub const PASSFD_LISTENER_PORT: &str = "agent.passfd_listener_port";
@@ -219,6 +221,13 @@ impl TomlConfig {
let container_pipe_size = cfg.container_pipe_size.to_string();
kv.insert(CONTAINER_PIPE_SIZE_OPTION.to_string(), container_pipe_size);
}
if cfg.launch_process_timeout > 0 {
let launch_process_timeout = cfg.launch_process_timeout.to_string();
kv.insert(
LAUNCH_PROCESS_TIMEOUT_OPTION.to_string(),
launch_process_timeout,
);
}
if cfg.debug_console_enabled {
kv.insert(DEBUG_CONSOLE_FLAG.to_string(), "".to_string());
kv.insert(
@@ -479,6 +488,7 @@ mod tests {
enable_tracing: true,
container_pipe_size: 20,
debug_console_enabled: true,
launch_process_timeout: 60,
..Default::default()
};
let agent_name = "test_agent";
@@ -491,5 +501,6 @@ mod tests {
assert_eq!(kv.get("agent.container_pipe_size").unwrap(), "20");
kv.get("agent.debug_console").unwrap();
assert_eq!(kv.get("agent.debug_console_vport").unwrap(), "1026"); // 1026 is the default port
assert_eq!(kv.get("agent.launch_process_timeout").unwrap(), "60");
}
}

View File

@@ -7,7 +7,9 @@ mod tests {
use kata_types::annotations::{
Annotation, KATA_ANNO_CFG_AGENT_CONTAINER_PIPE_SIZE, KATA_ANNO_CFG_AGENT_TRACE,
KATA_ANNO_CFG_DISABLE_GUEST_SECCOMP, KATA_ANNO_CFG_ENABLE_PPROF,
KATA_ANNO_CFG_EXPERIMENTAL, KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_CACHE_NOFLUSH,
KATA_ANNO_CFG_EXPERIMENTAL, KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE,
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE,
KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_CACHE_NOFLUSH,
KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_DRIVER, KATA_ANNO_CFG_HYPERVISOR_DEFAULT_MEMORY,
KATA_ANNO_CFG_HYPERVISOR_DEFAULT_VCPUS, KATA_ANNO_CFG_HYPERVISOR_ENABLE_GUEST_SWAP,
KATA_ANNO_CFG_HYPERVISOR_ENABLE_HUGEPAGES, KATA_ANNO_CFG_HYPERVISOR_ENABLE_IO_THREADS,
@@ -479,4 +481,111 @@ mod tests {
let mut config = TomlConfig::load(content).unwrap();
assert!(anno.update_config_by_annotation(&mut config).is_err());
}
#[test]
fn test_block_device_sector_size_annotations_valid() {
let content = include_str!("texture/configuration-anno-0.toml");
let qemu = QemuConfig::new();
qemu.register();
// Valid: 512 logical, 4096 physical
let config = TomlConfig::load(content).unwrap();
KataConfig::set_active_config(Some(config), "qemu", "agent0");
let mut anno_hash = HashMap::new();
anno_hash.insert(
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE.to_string(),
"512".to_string(),
);
anno_hash.insert(
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE.to_string(),
"4096".to_string(),
);
let anno = Annotation::new(anno_hash);
let mut config = TomlConfig::load(content).unwrap();
assert!(anno.update_config_by_annotation(&mut config).is_ok());
if let Some(hv) = config.hypervisor.get("qemu") {
assert_eq!(hv.blockdev_info.block_device_logical_sector_size, 512);
assert_eq!(hv.blockdev_info.block_device_physical_sector_size, 4096);
}
// Valid: 0 means hypervisor default
let mut anno_hash = HashMap::new();
anno_hash.insert(
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE.to_string(),
"0".to_string(),
);
anno_hash.insert(
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE.to_string(),
"0".to_string(),
);
let anno = Annotation::new(anno_hash);
let mut config = TomlConfig::load(content).unwrap();
assert!(anno.update_config_by_annotation(&mut config).is_ok());
if let Some(hv) = config.hypervisor.get("qemu") {
assert_eq!(hv.blockdev_info.block_device_logical_sector_size, 0);
assert_eq!(hv.blockdev_info.block_device_physical_sector_size, 0);
}
}
#[test]
fn test_block_device_sector_size_annotation_invalid_not_power_of_two() {
let content = include_str!("texture/configuration-anno-0.toml");
let qemu = QemuConfig::new();
qemu.register();
let config = TomlConfig::load(content).unwrap();
KataConfig::set_active_config(Some(config), "qemu", "agent0");
let mut anno_hash = HashMap::new();
anno_hash.insert(
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE.to_string(),
"1000".to_string(),
);
let anno = Annotation::new(anno_hash);
let mut config = TomlConfig::load(content).unwrap();
assert!(anno.update_config_by_annotation(&mut config).is_err());
}
#[test]
fn test_block_device_sector_size_annotation_invalid_below_minimum() {
let content = include_str!("texture/configuration-anno-0.toml");
let qemu = QemuConfig::new();
qemu.register();
let config = TomlConfig::load(content).unwrap();
KataConfig::set_active_config(Some(config), "qemu", "agent0");
let mut anno_hash = HashMap::new();
anno_hash.insert(
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE.to_string(),
"256".to_string(),
);
let anno = Annotation::new(anno_hash);
let mut config = TomlConfig::load(content).unwrap();
assert!(anno.update_config_by_annotation(&mut config).is_err());
}
#[test]
fn test_block_device_sector_size_annotation_invalid_above_maximum() {
let content = include_str!("texture/configuration-anno-0.toml");
let qemu = QemuConfig::new();
qemu.register();
let config = TomlConfig::load(content).unwrap();
KataConfig::set_active_config(Some(config), "qemu", "agent0");
let mut anno_hash = HashMap::new();
anno_hash.insert(
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE.to_string(),
"131072".to_string(),
);
let anno = Annotation::new(anno_hash);
let mut config = TomlConfig::load(content).unwrap();
assert!(anno.update_config_by_annotation(&mut config).is_err());
}
}

View File

@@ -19,7 +19,7 @@ default_maxvcpus = 64
machine_type = "q35"
confidential_guest = true
rootless = true
enable_annotations = ["shared_fs","path", "ctlpath","jailer_path","enable_iothreads","default_memory","memory_slots","enable_mem_prealloc","enable_hugepages","file_mem_backend","enable_virtio_mem","enable_guest_swap","default_vcpus","virtio_fs_extra_args","block_device_driver","vhost_user_store_path","kernel","guest_hook_path","block_device_cache_noflush","virtio_fs_daemon"]
enable_annotations = ["shared_fs","path", "ctlpath","jailer_path","enable_iothreads","default_memory","memory_slots","enable_mem_prealloc","enable_hugepages","file_mem_backend","enable_virtio_mem","enable_guest_swap","default_vcpus","virtio_fs_extra_args","block_device_driver","vhost_user_store_path","kernel","guest_hook_path","block_device_cache_noflush","virtio_fs_daemon","blk_logical_sector_size","blk_physical_sector_size"]
machine_accelerators="noapic"
default_bridges = 2
default_memory = 128

View File

@@ -1,7 +1,9 @@
[package]
name = "mem-agent"
version = "0.2.0"
edition = "2021"
authors.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
slog = "2.5.2"

View File

@@ -26,23 +26,14 @@ ARCH_DIR = arch
ARCH_FILE_SUFFIX = -options.mk
ARCH_FILE = $(ARCH_DIR)/$(ARCH)$(ARCH_FILE_SUFFIX)
ifeq ($(ARCH), s390x)
UNSUPPORTED_ARCHS := s390x powerpc64le riscv64gc
ifeq ($(filter $(ARCH), $(UNSUPPORTED_ARCHS)),$(ARCH))
default: runtime show-header
test:
@echo "s390x is not currently supported"
@echo "$(ARCH) is not currently supported"
exit 0
install: install-runtime install-configs
else ifeq ($(ARCH), powerpc64le)
default: runtime show-header
test:
@echo "powerpc64le is not currently supported"
exit 0
install: install-runtime install-configs
else ifeq ($(ARCH), riscv64gc)
default: runtime show-header
test:
@echo "RISC-V 64 is not currently supported"
exit 0
else
##TARGET default: build code
default: runtime show-header

View File

@@ -255,6 +255,16 @@ block_device_cache_direct = false
# Default false
block_device_cache_noflush = false
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_logical_sector_size = 0
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_physical_sector_size = 0
# Enable iothreads (data-plane) to be used. This causes IO to be
# handled in a separate IO thread. This is currently only implemented
# for SCSI.
@@ -541,6 +551,11 @@ dial_timeout_ms = 10
# (default: 3000)
reconnect_timeout_ms = 3000
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
# Create Container Request Timeout
# This timeout value is used to set the maximum duration for the agent to process a CreateContainerRequest.
# It's also used to ensure that workloads, especially those involving large image pulls within the guest,

View File

@@ -245,6 +245,16 @@ block_device_cache_direct = false
# Default false
block_device_cache_noflush = false
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_logical_sector_size = 0
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_physical_sector_size = 0
# Enable iothreads (data-plane) to be used. This causes IO to be
# handled in a separate IO thread. This is currently only implemented
# for SCSI.

View File

@@ -244,6 +244,16 @@ block_device_cache_direct = false
# Default false
block_device_cache_noflush = false
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_logical_sector_size = 0
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_physical_sector_size = 0
# Enable iothreads (data-plane) to be used. This causes IO to be
# handled in a separate IO thread. This is currently only implemented
# for SCSI.
@@ -523,6 +533,11 @@ dial_timeout_ms = 90
# (default: 3000)
reconnect_timeout_ms = 5000
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
# Create Container Request Timeout
# This timeout value is used to set the maximum duration for the agent to process a CreateContainerRequest.
# It's also used to ensure that workloads, especially those involving large image pulls within the guest,

View File

@@ -281,6 +281,16 @@ block_device_cache_direct = false
# Default false
block_device_cache_noflush = false
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_logical_sector_size = 0
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_physical_sector_size = 0
# Enable iothreads (data-plane) to be used. This causes IO to be
# handled in a separate IO thread. This is currently only implemented
# for SCSI.
@@ -565,6 +575,11 @@ dial_timeout_ms = 10
# (default: 3000)
reconnect_timeout_ms = 3000
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
# Create Container Request Timeout
# This timeout value is used to set the maximum duration for the agent to process a CreateContainerRequest.
# It's also used to ensure that workloads, especially those involving large image pulls within the guest,

View File

@@ -256,6 +256,16 @@ block_device_cache_direct = false
# Default false
block_device_cache_noflush = false
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_logical_sector_size = 0
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
# Default 0
block_device_physical_sector_size = 0
# Enable iothreads (data-plane) to be used. This causes IO to be
# handled in a separate IO thread. This is currently implemented
# for virtio-scsi and virtio-blk.
@@ -541,6 +551,11 @@ dial_timeout_ms = 10
# (default: 3000)
reconnect_timeout_ms = 3000
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
# Create Container Request Timeout
# This timeout value is used to set the maximum duration for the agent to process a CreateContainerRequest.
# It's also used to ensure that workloads, especially those involving large image pulls within the guest,

View File

@@ -6,6 +6,7 @@
name = "ch-config"
version = "0.1.0"
edition = { workspace = true }
license = "Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@@ -112,6 +112,12 @@ pub struct BlockConfig {
/// block device multi-queue
pub num_queues: usize,
/// Logical sector size in bytes reported to the guest. 0 means use hypervisor default.
pub logical_sector_size: u32,
/// Physical sector size in bytes reported to the guest. 0 means use hypervisor default.
pub physical_sector_size: u32,
}
#[derive(Debug, Clone, Default)]

View File

@@ -866,6 +866,8 @@ impl QemuInner {
),
block_device.config.is_readonly,
block_device.config.no_drop,
block_device.config.logical_sector_size,
block_device.config.physical_sector_size,
)
.context("hotplug block device")?;

View File

@@ -642,6 +642,8 @@ impl Qmp {
is_direct: Option<bool>,
is_readonly: bool,
no_drop: bool,
logical_block_size: u32,
physical_block_size: u32,
) -> Result<(Option<PciPath>, Option<String>)> {
// `blockdev-add`
let node_name = format!("drive-{index}");
@@ -719,6 +721,13 @@ impl Qmp {
let mut blkdev_add_args = Dictionary::new();
blkdev_add_args.insert("drive".to_owned(), node_name.clone().into());
if logical_block_size > 0 {
blkdev_add_args.insert("logical_block_size".to_owned(), logical_block_size.into());
}
if physical_block_size > 0 {
blkdev_add_args.insert("physical_block_size".to_owned(), physical_block_size.into());
}
if block_driver == VIRTIO_SCSI {
// Helper closure to decode a flattened u16 SCSI index into an (ID, LUN) pair.
let get_scsi_id_lun = |index_u16: u16| -> Result<(u8, u8)> {

View File

@@ -422,6 +422,8 @@ impl ResourceManagerInner {
blkdev_aio: BlockDeviceAio::new(&blkdev_info.block_device_aio),
num_queues: blkdev_info.num_queues,
queue_size: blkdev_info.queue_size,
logical_sector_size: blkdev_info.block_device_logical_sector_size,
physical_sector_size: blkdev_info.block_device_physical_sector_size,
..Default::default()
});

View File

@@ -49,6 +49,8 @@ impl BlockVolume {
blkdev_aio: BlockDeviceAio::new(&blkdev_info.block_device_aio),
num_queues: blkdev_info.num_queues,
queue_size: blkdev_info.queue_size,
logical_sector_size: blkdev_info.block_device_logical_sector_size,
physical_sector_size: blkdev_info.block_device_physical_sector_size,
..Default::default()
};

View File

@@ -64,6 +64,8 @@ impl RawblockVolume {
blkdev_aio: BlockDeviceAio::new(&blkdev_info.block_device_aio),
num_queues: blkdev_info.num_queues,
queue_size: blkdev_info.queue_size,
logical_sector_size: blkdev_info.block_device_logical_sector_size,
physical_sector_size: blkdev_info.block_device_physical_sector_size,
..Default::default()
};

View File

@@ -491,6 +491,7 @@ ifneq (,$(QEMUCMD))
DEFAULTVCPUS_NV = 1
DEFAULTMEMORY_NV = 8192
DEFAULTTIMEOUT_NV = 1200
DEFAULTLAUNCHPROCESSTIMEOUT_NV = 15
DEFAULTVFIOPORT_NV = root-port
DEFAULTPCIEROOTPORT_NV = 8
@@ -506,6 +507,8 @@ ifneq (,$(QEMUCMD))
# Best practice for production is to set this to true
DEFSANDBOXCGROUPONLY_NV = true
DEFENABLEVCPUPINNING_NV = true
ifneq (,$(QEMUFW))
FIRMWAREPATH := $(PREFIXDEPS)/share/$(EDK2_NAME)/$(QEMUFW)
endif
@@ -678,7 +681,9 @@ USER_VARS += KERNELPARAMS_CONFIDENTIAL_NV
USER_VARS += KERNELVERITYPARAMS_NV
USER_VARS += KERNELVERITYPARAMS_CONFIDENTIAL_NV
USER_VARS += DEFAULTTIMEOUT_NV
USER_VARS += DEFAULTLAUNCHPROCESSTIMEOUT_NV
USER_VARS += DEFSANDBOXCGROUPONLY_NV
USER_VARS += DEFENABLEVCPUPINNING_NV
USER_VARS += DEFROOTFSTYPE
USER_VARS += MACHINETYPE
USER_VARS += KERNELDIR

View File

@@ -537,6 +537,11 @@ debug_console_enabled = false
# (default: 90)
dial_timeout = 90
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
[runtime]
# If enabled, the runtime will log additional debug messages to the
# system log

View File

@@ -595,6 +595,11 @@ dial_timeout = 45
# (default: 50)
cdh_api_timeout = 50
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
[runtime]
# If enabled, the runtime will log additional debug messages to the
# system log

View File

@@ -611,6 +611,13 @@ debug_console_enabled = false
# (default: 90)
dial_timeout = @DEFAULTTIMEOUT_NV@
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# With NVIDIA GPUs and NVSwitches, the attestation-agent needs extra time
# to collect evidence during initialization.
# (agent default when unset: 6)
launch_process_timeout = @DEFAULTLAUNCHPROCESSTIMEOUT_NV@
[runtime]
# If enabled, the runtime will log additional debug messages to the
# system log
@@ -645,7 +652,7 @@ disable_guest_seccomp = @DEFDISABLEGUESTSECCOMP@
# vCPUs pinning settings
# if enabled, each vCPU thread will be scheduled to a fixed CPU
# qualified condition: num(vCPU threads) == num(CPUs in sandbox's CPUSet)
enable_vcpus_pinning = false
enable_vcpus_pinning = @DEFENABLEVCPUPINNING_NV@
# Apply a custom SELinux security policy to the container process inside the VM.
# This is used when you want to apply a type other than the default `container_t`,

View File

@@ -588,6 +588,13 @@ debug_console_enabled = false
# (default: 90)
dial_timeout = @DEFAULTTIMEOUT_NV@
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# With NVIDIA GPUs and NVSwitches, the attestation-agent needs extra time
# to collect evidence during initialization.
# (agent default when unset: 6)
launch_process_timeout = @DEFAULTLAUNCHPROCESSTIMEOUT_NV@
[runtime]
# If enabled, the runtime will log additional debug messages to the
# system log
@@ -622,7 +629,7 @@ disable_guest_seccomp = @DEFDISABLEGUESTSECCOMP@
# vCPUs pinning settings
# if enabled, each vCPU thread will be scheduled to a fixed CPU
# qualified condition: num(vCPU threads) == num(CPUs in sandbox's CPUSet)
enable_vcpus_pinning = false
enable_vcpus_pinning = @DEFENABLEVCPUPINNING_NV@
# Apply a custom SELinux security policy to the container process inside the VM.
# This is used when you want to apply a type other than the default `container_t`,

View File

@@ -590,6 +590,13 @@ debug_console_enabled = false
# (default: 90)
dial_timeout = @DEFAULTTIMEOUT_NV@
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# With NVIDIA GPUs and NVSwitches, the attestation-agent needs extra time
# to collect evidence during initialization.
# (agent default when unset: 6)
launch_process_timeout = @DEFAULTLAUNCHPROCESSTIMEOUT_NV@
[runtime]
# If enabled, the runtime will log additional debug messages to the
# system log
@@ -624,7 +631,7 @@ disable_guest_seccomp = @DEFDISABLEGUESTSECCOMP@
# vCPUs pinning settings
# if enabled, each vCPU thread will be scheduled to a fixed CPU
# qualified condition: num(vCPU threads) == num(CPUs in sandbox's CPUSet)
enable_vcpus_pinning = false
enable_vcpus_pinning = @DEFENABLEVCPUPINNING_NV@
# Apply a custom SELinux security policy to the container process inside the VM.
# This is used when you want to apply a type other than the default `container_t`,

View File

@@ -573,6 +573,11 @@ debug_console_enabled = false
# (default: 30)
dial_timeout = 90
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
[runtime]
# If enabled, the runtime will log additional debug messages to the
# system log

View File

@@ -603,6 +603,11 @@ debug_console_enabled = false
# (default: 90)
dial_timeout = 90
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
[runtime]
# If enabled, the runtime will log additional debug messages to the
# system log

View File

@@ -580,6 +580,11 @@ debug_console_enabled = false
# (default: 60)
dial_timeout = 60
# Timeout in seconds for guest components (attestation-agent, confidential-data-hub)
# to create their Unix sockets after being spawned by the agent.
# (agent default when unset: 6)
launch_process_timeout = 6
[runtime]
# If enabled, the runtime will log additional debug messages to the
# system log

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.25.8
go 1.25.9
// WARNING: Do NOT use `replace` directives as those break dependabot:
// https://github.com/kata-containers/kata-containers/issues/11020

View File

@@ -224,12 +224,13 @@ func (r runtime) emptyDirMode() (string, error) {
}
type agent struct {
KernelModules []string `toml:"kernel_modules"`
Debug bool `toml:"enable_debug"`
Tracing bool `toml:"enable_tracing"`
DebugConsoleEnabled bool `toml:"debug_console_enabled"`
DialTimeout uint32 `toml:"dial_timeout"`
CdhApiTimeout uint32 `toml:"cdh_api_timeout"`
KernelModules []string `toml:"kernel_modules"`
Debug bool `toml:"enable_debug"`
Tracing bool `toml:"enable_tracing"`
DebugConsoleEnabled bool `toml:"debug_console_enabled"`
DialTimeout uint32 `toml:"dial_timeout"`
CdhApiTimeout uint32 `toml:"cdh_api_timeout"`
LaunchProcessTimeout uint32 `toml:"launch_process_timeout"`
}
func (orig *tomlConfig) Clone() tomlConfig {
@@ -798,6 +799,10 @@ func (a agent) cdhApiTimout() uint32 {
return a.CdhApiTimeout
}
func (a agent) launchProcessTimeout() uint32 {
return a.LaunchProcessTimeout
}
func (a agent) debug() bool {
return a.Debug
}
@@ -1464,13 +1469,14 @@ func updateRuntimeConfigHypervisor(configPath string, tomlConf tomlConfig, confi
func updateRuntimeConfigAgent(configPath string, tomlConf tomlConfig, config *oci.RuntimeConfig) error {
for _, agent := range tomlConf.Agent {
config.AgentConfig = vc.KataAgentConfig{
LongLiveConn: true,
Debug: agent.debug(),
Trace: agent.trace(),
KernelModules: agent.kernelModules(),
EnableDebugConsole: agent.debugConsoleEnabled(),
DialTimeout: agent.dialTimout(),
CdhApiTimeout: agent.cdhApiTimout(),
LongLiveConn: true,
Debug: agent.debug(),
Trace: agent.trace(),
KernelModules: agent.kernelModules(),
EnableDebugConsole: agent.debugConsoleEnabled(),
DialTimeout: agent.dialTimout(),
CdhApiTimeout: agent.cdhApiTimout(),
LaunchProcessTimeout: agent.launchProcessTimeout(),
}
}

View File

@@ -292,15 +292,16 @@ func ephemeralPath() string {
// KataAgentConfig is a structure storing information needed
// to reach the Kata Containers agent.
type KataAgentConfig struct {
KernelModules []string
ContainerPipeSize uint32
DialTimeout uint32
CdhApiTimeout uint32
LongLiveConn bool
Debug bool
Trace bool
EnableDebugConsole bool
Policy string
KernelModules []string
ContainerPipeSize uint32
DialTimeout uint32
CdhApiTimeout uint32
LaunchProcessTimeout uint32
LongLiveConn bool
Debug bool
Trace bool
EnableDebugConsole bool
Policy string
}
// KataAgentState is the structure describing the data stored from this
@@ -366,6 +367,11 @@ func KataAgentKernelParams(config KataAgentConfig) []Param {
params = append(params, Param{Key: vcAnnotations.CdhApiTimeoutKernelParam, Value: cdhApiTimeout})
}
if config.LaunchProcessTimeout > 0 {
launchProcessTimeout := strconv.FormatUint(uint64(config.LaunchProcessTimeout), 10)
params = append(params, Param{Key: vcAnnotations.LaunchProcessTimeoutKernelParam, Value: launchProcessTimeout})
}
return params
}

View File

@@ -1083,47 +1083,56 @@ func TestKataAgentKernelParams(t *testing.T) {
// nolint: govet
type testData struct {
debug bool
trace bool
containerPipeSize uint32
expectedParams []Param
debug bool
trace bool
containerPipeSize uint32
launchProcessTimeout uint32
expectedParams []Param
}
debugParam := Param{Key: "agent.log", Value: "debug"}
traceParam := Param{Key: "agent.trace", Value: "true"}
containerPipeSizeParam := Param{Key: vcAnnotations.ContainerPipeSizeKernelParam, Value: "2097152"}
launchProcessTimeoutParam := Param{Key: vcAnnotations.LaunchProcessTimeoutKernelParam, Value: "60"}
data := []testData{
{false, false, 0, []Param{}},
{false, false, 0, 0, []Param{}},
// Debug
{true, false, 0, []Param{debugParam}},
{true, false, 0, 0, []Param{debugParam}},
// Tracing
{false, true, 0, []Param{traceParam}},
{false, true, 0, 0, []Param{traceParam}},
// Debug + Tracing
{true, true, 0, []Param{debugParam, traceParam}},
{true, true, 0, 0, []Param{debugParam, traceParam}},
// pipesize
{false, false, 2097152, []Param{containerPipeSizeParam}},
{false, false, 2097152, 0, []Param{containerPipeSizeParam}},
// Debug + pipesize
{true, false, 2097152, []Param{debugParam, containerPipeSizeParam}},
{true, false, 2097152, 0, []Param{debugParam, containerPipeSizeParam}},
// Tracing + pipesize
{false, true, 2097152, []Param{traceParam, containerPipeSizeParam}},
{false, true, 2097152, 0, []Param{traceParam, containerPipeSizeParam}},
// Debug + Tracing + pipesize
{true, true, 2097152, []Param{debugParam, traceParam, containerPipeSizeParam}},
{true, true, 2097152, 0, []Param{debugParam, traceParam, containerPipeSizeParam}},
// LaunchProcessTimeout
{false, false, 0, 60, []Param{launchProcessTimeoutParam}},
// Debug + LaunchProcessTimeout
{true, false, 0, 60, []Param{debugParam, launchProcessTimeoutParam}},
}
for i, d := range data {
config := KataAgentConfig{
Debug: d.debug,
Trace: d.trace,
ContainerPipeSize: d.containerPipeSize,
Debug: d.debug,
Trace: d.trace,
ContainerPipeSize: d.containerPipeSize,
LaunchProcessTimeout: d.launchProcessTimeout,
}
count := len(d.expectedParams)

View File

@@ -3411,7 +3411,7 @@ type Storage struct {
unknownFields protoimpl.UnknownFields
// Driver is used to define the way the storage is passed through the
// virtual machine. It can be "9p", "blk", or something else, but for
// virtual machine. It can be "blk", or something else, but for
// all cases, this will define if some extra steps are required before
// this storage gets mounted into the container.
Driver string `protobuf:"bytes,1,opt,name=driver,proto3" json:"driver,omitempty"`
@@ -3427,7 +3427,7 @@ type Storage struct {
Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"`
// Fstype represents the filesystem that needs to be used to mount the
// storage inside the VM. For instance, it could be "xfs" for block
// device, "9p" for shared filesystem, or "tmpfs" for shared /dev/shm.
// device, or "tmpfs" for shared /dev/shm.
Fstype string `protobuf:"bytes,4,opt,name=fstype,proto3" json:"fstype,omitempty"`
// Options describes the additional options that might be needed to
// mount properly the storage filesystem.

View File

@@ -334,11 +334,13 @@ const (
AgentTrace = kataAnnotAgentPrefix + "enable_tracing"
// AgentContainerPipeSize is an annotation to specify the size of the pipes created for containers
AgentContainerPipeSize = kataAnnotAgentPrefix + ContainerPipeSizeOption
ContainerPipeSizeOption = "container_pipe_size"
ContainerPipeSizeKernelParam = "agent." + ContainerPipeSizeOption
CdhApiTimeoutOption = "cdh_api_timeout"
CdhApiTimeoutKernelParam = "agent." + CdhApiTimeoutOption
AgentContainerPipeSize = kataAnnotAgentPrefix + ContainerPipeSizeOption
ContainerPipeSizeOption = "container_pipe_size"
ContainerPipeSizeKernelParam = "agent." + ContainerPipeSizeOption
CdhApiTimeoutOption = "cdh_api_timeout"
CdhApiTimeoutKernelParam = "agent." + CdhApiTimeoutOption
LaunchProcessTimeoutOption = "launch_process_timeout"
LaunchProcessTimeoutKernelParam = "agent." + LaunchProcessTimeoutOption
// Policy is an annotation containing the contents of an agent policy file, base64 encoded.
Policy = kataAnnotAgentPrefix + "policy"

File diff suppressed because it is too large Load Diff

View File

@@ -41,7 +41,7 @@ serde = { version = "1.0.131", features = ["derive"] }
serde_json = "1.0.73"
# Image pull/unpack
image-rs = { git = "https://github.com/confidential-containers/guest-components", tag = "v0.18.0", features = [
image-rs = { git = "https://github.com/confidential-containers/guest-components", rev = "de3f6ff62aa736619b80d99dfca5bc3d2c9a799d", features = [
"oci-client-rustls",
"signature-cosign-rustls",
] }

View File

@@ -1,7 +1,7 @@
module kata-containers/csi-kata-directvolume
// Keep in sync with version in versions.yaml
go 1.25.8
go 1.25.9
// 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.25.8
go 1.25.9
require (
github.com/BurntSushi/toml v1.1.0

View File

@@ -635,7 +635,7 @@ function helm_helper() {
base_values_file="${helm_chart_dir}/try-kata-nvidia-gpu.values.yaml"
fi
;;
qemu-snp|qemu-tdx|qemu-se|qemu-se-runtime-rs|qemu-cca|qemu-coco-dev|qemu-coco-dev-runtime-rs)
qemu-snp|qemu-snp-runtime-rs|qemu-tdx|qemu-se|qemu-se-runtime-rs|qemu-cca|qemu-coco-dev|qemu-coco-dev-runtime-rs)
# Use TEE example file
if [[ -f "${helm_chart_dir}/try-kata-tee.values.yaml" ]]; then
base_values_file="${helm_chart_dir}/try-kata-tee.values.yaml"

View File

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

View File

@@ -11,7 +11,7 @@ source "${BATS_TEST_DIRNAME}/../../common.bash"
load "${BATS_TEST_DIRNAME}/confidential_kbs.sh"
SUPPORTED_GPU_TEE_HYPERVISORS=("qemu-nvidia-gpu-snp" "qemu-nvidia-gpu-tdx")
SUPPORTED_TEE_HYPERVISORS=("qemu-snp" "qemu-tdx" "qemu-se" "qemu-se-runtime-rs" "${SUPPORTED_GPU_TEE_HYPERVISORS[@]}")
SUPPORTED_TEE_HYPERVISORS=("qemu-snp" "qemu-snp-runtime-rs" "qemu-tdx" "qemu-se" "qemu-se-runtime-rs" "${SUPPORTED_GPU_TEE_HYPERVISORS[@]}")
SUPPORTED_NON_TEE_HYPERVISORS=("qemu-coco-dev" "qemu-coco-dev-runtime-rs")
function setup_unencrypted_confidential_pod() {
@@ -36,7 +36,7 @@ function get_remote_command_per_hypervisor() {
qemu-se*)
echo "cd /sys/firmware/uv; cat prot_virt_guest | grep 1"
;;
qemu-snp)
qemu-snp|qemu-snp-runtime-rs)
echo "dmesg | grep \"Memory Encryption Features active:.*SEV-SNP\""
;;
qemu-tdx)
@@ -290,6 +290,45 @@ export SEALED_SECRET_PRECREATED_TEST="sealed.eyJiNjQiOnRydWUsImFsZyI6IkVTMjU2Iiw
export SEALED_SECRET_PRECREATED_NIM_INSTRUCT="sealed.eyJiNjQiOnRydWUsImFsZyI6IkVTMjU2Iiwia2lkIjoia2JzOi8vL2RlZmF1bHQvc2lnbmluZy1rZXkvc2VhbGVkLXNlY3JldCJ9.eyJ2ZXJzaW9uIjoiMC4xLjAiLCJ0eXBlIjoidmF1bHQiLCJuYW1lIjoia2JzOi8vL2RlZmF1bHQvbmdjLWFwaS1rZXkvaW5zdHJ1Y3QiLCJwcm92aWRlciI6ImticyIsInByb3ZpZGVyX3NldHRpbmdzIjp7fSwiYW5ub3RhdGlvbnMiOnt9fQ.wpqvVFUaQymqgf54h70shZWDpk2NLW305wALz09YF0GKFBKBQiQB2sRwvn9Jk_rSju3YGLYxPO2Ub8qUbiMCuA"
export SEALED_SECRET_PRECREATED_NIM_EMBEDQA="sealed.eyJiNjQiOnRydWUsImFsZyI6IkVTMjU2Iiwia2lkIjoia2JzOi8vL2RlZmF1bHQvc2lnbmluZy1rZXkvc2VhbGVkLXNlY3JldCJ9.eyJ2ZXJzaW9uIjoiMC4xLjAiLCJ0eXBlIjoidmF1bHQiLCJuYW1lIjoia2JzOi8vL2RlZmF1bHQvbmdjLWFwaS1rZXkvZW1iZWRxYSIsInByb3ZpZGVyIjoia2JzIiwicHJvdmlkZXJfc2V0dGluZ3MiOnt9LCJhbm5vdGF0aW9ucyI6e319.4C1uqtVXi_qZT8vh_yZ4KpsRdgr2s4hU6ElKj18Hq1DJi_Iji61yuKsS6S1jWdb7drdoKKACvMD6RmCd85SJOQ"
# Set up KBS with image security policy requiring cosign signatures using the NVIDIA
# container signing public key. When initdata includes image_security_policy_uri
# pointing to this policy, the guest will verify image signatures when it pulls the image.
# Note: keyPath-only sigstoreSigned does not require Rekor per spec; if the guest fails
# with "signature not found in transparency log", the in-guest verifier may need to
# support key-only verification (host-side: cosign verify --key <pubkey> --insecure-ignore-tlog <image>).
function setup_kbs_nim_image_policy() {
local policy_json public_key
# Cosign public key for nvcr.io images. Source: NVIDIA NGC Catalog API.
# See https://docs.nvidia.com/ngc/latest/ngc-catalog-user-guide.html#finding-nvidia-s-public-key
public_key=$(curl -sSL "https://api.ngc.nvidia.com/v2/catalog/containers/public-key")
policy_json=$(cat << EOF
{
"default": [{"type": "reject"}],
"transports": {
"docker": {
"nvcr.io/nim/meta": [
{
"type": "sigstoreSigned",
"keyPath": "kbs:///default/cosign-public-key/nim",
"signedIdentity": {"type": "matchRepository"}
}
],
"nvcr.io/nim/nvidia": [
{
"type": "sigstoreSigned",
"keyPath": "kbs:///default/cosign-public-key/nim",
"signedIdentity": {"type": "matchRepository"}
}
]
}
}
}
EOF
)
kbs_set_resource "default" "security-policy" "nim" "${policy_json}"
kbs_set_resource "default" "cosign-public-key" "nim" "${public_key}"
}
# Provision the signing public key to KBS so CDH can verify the pre-created sealed secrets.
function setup_sealed_secret_signing_public_key() {
kbs_set_resource "default" "signing-key" "sealed-secret" "${SEALED_SECRET_SIGNING_PUBLIC_JWK}"

View File

@@ -187,7 +187,7 @@ function deploy_kata() {
# Workaround to avoid modifying the workflow yaml files
case "${KATA_HYPERVISOR}" in
qemu-tdx|qemu-snp|qemu-nvidia-gpu-*)
qemu-tdx|qemu-snp|qemu-snp-runtime-rs|qemu-nvidia-gpu-*)
USE_EXPERIMENTAL_SETUP_SNAPSHOTTER=true
SNAPSHOTTER="nydus"
EXPERIMENTAL_FORCE_GUEST_PULL=false
@@ -447,7 +447,7 @@ function cleanup() {
}
function deploy_snapshotter() {
if [[ "${KATA_HYPERVISOR}" == "qemu-tdx" || "${KATA_HYPERVISOR}" == "qemu-snp" ]]; then
if [[ "${KATA_HYPERVISOR}" == "qemu-tdx" || "${KATA_HYPERVISOR}" == "qemu-snp" || "${KATA_HYPERVISOR}" == "qemu-snp-runtime-rs" ]]; then
echo "[Skip] ${SNAPSHOTTER} is pre-installed in the TEE machine"
return
fi
@@ -461,7 +461,7 @@ function deploy_snapshotter() {
}
function cleanup_snapshotter() {
if [[ "${KATA_HYPERVISOR}" == "qemu-tdx" || "${KATA_HYPERVISOR}" == "qemu-snp" ]]; then
if [[ "${KATA_HYPERVISOR}" == "qemu-tdx" || "${KATA_HYPERVISOR}" == "qemu-snp" || "${KATA_HYPERVISOR}" == "qemu-snp-runtime-rs" ]]; then
echo "[Skip] ${SNAPSHOTTER} is pre-installed in the TEE machine"
return
fi

View File

@@ -146,15 +146,22 @@ setup() {
kbs_set_cpu0_resource_policy
# get measured artifacts from qemu command line of previous test
# Go runtime logs: "launching <path> with: [<args>]"
# runtime-rs logs: "qemu args: <args>"
log_line=$(sudo journalctl -r -x -t kata | grep -m 1 'launching.*qemu.*with:' || true)
qemu_cmd=$(echo "$log_line" | sed 's/.*with: \[\(.*\)\]".*/\1/')
if [[ -n "$log_line" ]]; then
qemu_cmd=$(echo "$log_line" | sed 's/.*with: \[\(.*\)\]".*/\1/')
else
log_line=$(sudo journalctl -r -x -t kata | grep -m 1 'qemu args:' || true)
qemu_cmd=$(echo "$log_line" | sed 's/.*qemu args: //')
fi
[[ -n "$qemu_cmd" ]] || { echo "Could not find QEMU command line"; return 1; }
kernel_path=$(echo "$qemu_cmd" | grep -oP -- '-kernel \K[^ ]+')
initrd_path=$(echo "$qemu_cmd" | grep -oP -- '-initrd \K[^ ]+' || true)
firmware_path=$(echo "$qemu_cmd" | grep -oP -- '-bios \K[^ ]+')
vcpu_count=$(echo "$qemu_cmd" | grep -oP -- '-smp \K\d+')
append=$(echo "$qemu_cmd" | sed -n 's/.*-append \(.*\) -bios.*/\1/p')
append=$(echo "$qemu_cmd" | grep -oP -- '-append \K.*?(?= -(smp|bios) )')
# Remove escape backslashes for quotes from output for dm-mod.create parameters
append="${append//\\\"/\"}"

View File

@@ -15,7 +15,7 @@ setup() {
[ "${KATA_HYPERVISOR}" == "qemu-se-runtime-rs" ] && skip "Requires CPU hotplug which isn't supported on ${KATA_HYPERVISOR} yet"
[[ "${KATA_HYPERVISOR}" == qemu-coco-dev* ]] && skip "Requires CPU hotplug which disabled by static_sandbox_resource_mgmt"
( [ "${KATA_HYPERVISOR}" == "qemu-tdx" ] || [ "${KATA_HYPERVISOR}" == "qemu-snp" ] || \
[ "${KATA_HYPERVISOR}" == "qemu-se" ] ) \
[ "${KATA_HYPERVISOR}" == "qemu-snp-runtime-rs" ] || [ "${KATA_HYPERVISOR}" == "qemu-se" ] ) \
&& skip "TEEs do not support memory / CPU hotplug"
pod_name="constraints-cpu-test"
@@ -121,7 +121,7 @@ teardown() {
[ "${KATA_HYPERVISOR}" == "qemu-se-runtime-rs" ] && skip "Requires CPU hotplug which isn't supported on ${KATA_HYPERVISOR} yet"
[[ "${KATA_HYPERVISOR}" == qemu-coco-dev* ]] && skip "Requires CPU hotplug which disabled by static_sandbox_resource_mgmt"
( [ "${KATA_HYPERVISOR}" == "qemu-tdx" ] || [ "${KATA_HYPERVISOR}" == "qemu-snp" ] || \
[ "${KATA_HYPERVISOR}" == "qemu-se" ] ) \
[ "${KATA_HYPERVISOR}" == "qemu-snp-runtime-rs" ] || [ "${KATA_HYPERVISOR}" == "qemu-se" ] ) \
&& skip "TEEs do not support memory / CPU hotplug"
# Debugging information

View File

@@ -9,14 +9,18 @@ load "${BATS_TEST_DIRNAME}/../../common.bash"
load "${BATS_TEST_DIRNAME}/lib.sh"
load "${BATS_TEST_DIRNAME}/tests_common.sh"
# Currently only the Go runtime provides the config path used here.
# If a Rust hypervisor runs this test, mirror the enabling_hypervisor
# pattern in tests/common.bash to select the correct runtime-rs config.
shim_config_file="/opt/kata/share/defaults/kata-containers/configuration-${KATA_HYPERVISOR}.toml"
case "${KATA_HYPERVISOR}" in
*-runtime-rs)
shim_config_file="/opt/kata/share/defaults/kata-containers/runtime-rs/runtimes/${KATA_HYPERVISOR}/configuration-${KATA_HYPERVISOR}.toml"
;;
*)
shim_config_file="/opt/kata/share/defaults/kata-containers/runtimes/${KATA_HYPERVISOR}/configuration-${KATA_HYPERVISOR}.toml"
;;
esac
check_and_skip() {
case "${KATA_HYPERVISOR}" in
qemu-tdx|qemu-coco-dev|qemu-snp)
qemu-tdx|qemu-coco-dev|qemu-snp|qemu-snp-runtime-rs)
if [ "$(uname -m)" == "s390x" ]; then
skip "measured rootfs tests not implemented for s390x"
fi

View File

@@ -96,6 +96,8 @@ setup_kbs_credentials() {
kbs_set_gpu0_resource_policy
kbs_set_resource_base64 "default" "credentials" "nvcr" "${KBS_AUTH_CONFIG_JSON}"
kbs_set_resource "default" "ngc-api-key" "instruct" "${NGC_API_KEY}"
setup_kbs_nim_image_policy
}
# CDH initdata for guest-pull: KBS URL, registry credentials URI, and allow-all policy.
@@ -125,6 +127,7 @@ url = "${cc_kbs_address}"
[image]
authenticated_registry_credentials_uri = "kbs:///default/credentials/nvcr"
image_security_policy_uri = "kbs:///default/security-policy/nim"
'''
"policy.rego" = '''

View File

@@ -112,6 +112,7 @@ url = "${cc_kbs_address}"
[image]
max_concurrent_layer_downloads_per_image = 1
authenticated_registry_credentials_uri = "kbs:///default/credentials/nvcr"
image_security_policy_uri = "kbs:///default/security-policy/nim"
'''
EOF
}
@@ -134,6 +135,9 @@ setup_kbs_credentials() {
# 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}"
# Enforce signed images for nvcr.io/nim (instruct and embedqa) in the guest.
setup_kbs_nim_image_policy
}
create_inference_pod() {

View File

@@ -138,7 +138,7 @@ add_runtime_handler_annotations() {
fi
case "${KATA_HYPERVISOR}" in
qemu-coco-dev | qemu-snp | qemu-tdx | qemu-coco-dev-runtime-rs)
qemu-coco-dev | qemu-snp | qemu-snp-runtime-rs | qemu-tdx | qemu-coco-dev-runtime-rs)
info "Add runtime handler annotations for ${KATA_HYPERVISOR}"
local handler_value="kata-${KATA_HYPERVISOR}"
for K8S_TEST_YAML in runtimeclass_workloads_work/*.yaml

View File

@@ -82,7 +82,7 @@ auto_generate_policy_enabled() {
is_coco_platform() {
case "${KATA_HYPERVISOR}" in
"qemu-tdx"|"qemu-snp"|"qemu-coco-dev"|"qemu-coco-dev-runtime-rs"|"qemu-nvidia-gpu-tdx"|"qemu-nvidia-gpu-snp")
"qemu-tdx"|"qemu-snp"|"qemu-snp-runtime-rs"|"qemu-coco-dev"|"qemu-coco-dev-runtime-rs"|"qemu-nvidia-gpu-tdx"|"qemu-nvidia-gpu-snp")
return 0
;;
*)
@@ -148,7 +148,7 @@ install_genpolicy_drop_ins() {
# 20-* OCI version overlay
if [[ "${KATA_HOST_OS:-}" == "cbl-mariner" ]]; then
cp "${examples_dir}/20-oci-1.2.0-drop-in.json" "${settings_d}/"
elif is_k3s_or_rke2 || is_nvidia_gpu_platform || [[ "${KATA_HYPERVISOR}" == "qemu-snp" ]] || [[ "${KATA_HYPERVISOR}" == "qemu-tdx" ]] || [[ -n "${CONTAINER_ENGINE_VERSION:-}" ]]; then
elif is_k3s_or_rke2 || is_nvidia_gpu_platform || [[ "${KATA_HYPERVISOR}" == "qemu-snp" ]] || [[ "${KATA_HYPERVISOR}" == "qemu-snp-runtime-rs" ]] || [[ "${KATA_HYPERVISOR}" == "qemu-tdx" ]] || [[ -n "${CONTAINER_ENGINE_VERSION:-}" ]]; then
cp "${examples_dir}/20-oci-1.3.0-drop-in.json" "${settings_d}/"
fi
@@ -340,7 +340,7 @@ hard_coded_policy_tests_enabled() {
# CI is testing hard-coded policies just on a the platforms listed here. Outside of CI,
# users can enable testing of the same policies (plus the auto-generated policies) by
# specifying AUTO_GENERATE_POLICY=yes.
local -r enabled_hypervisors=("qemu-coco-dev" "qemu-snp" "qemu-tdx" "qemu-coco-dev-runtime-rs")
local -r enabled_hypervisors=("qemu-coco-dev" "qemu-snp" "qemu-snp-runtime-rs" "qemu-tdx" "qemu-coco-dev-runtime-rs")
for enabled_hypervisor in "${enabled_hypervisors[@]}"
do
if [[ "${enabled_hypervisor}" == "${KATA_HYPERVISOR}" ]]; then

View File

@@ -1,7 +1,7 @@
module example.com/m
// Keep in sync with version in versions.yaml
go 1.25.8
go 1.25.9
require (
github.com/BurntSushi/toml v1.3.2

View File

@@ -26,10 +26,22 @@ handler: kata-{{ .shim }}-{{ .root.Values.env.multiInstallSuffix }}
{{- else }}
handler: kata-{{ .shim }}
{{- end }}
{{- /* Overhead section - controlled by global or per-shim overheadEnabled flag (default: true) */ -}}
{{- $shimOverheadEnabled := true -}}
{{- if hasKey .root.Values.runtimeClasses "overheadEnabled" -}}
{{- $shimOverheadEnabled = .root.Values.runtimeClasses.overheadEnabled -}}
{{- end -}}
{{- with .shimConfig.runtimeClass -}}
{{- if hasKey . "overheadEnabled" -}}
{{- $shimOverheadEnabled = .overheadEnabled -}}
{{- end -}}
{{- end -}}
{{- if $shimOverheadEnabled }}
overhead:
podFixed:
memory: {{ .config.memory | quote }}
cpu: {{ .config.cpu | quote }}
{{- end }}
scheduling:
nodeSelector:
katacontainers.io/kata-runtime: "true"

View File

@@ -69,6 +69,7 @@ snapshotter:
# runtimeClass:
# nodeSelector: # extra node selectors added to the RuntimeClass
# example.io/feature: "true"
# overheadEnabled: true # enable/disable overhead in RuntimeClass (default: inherits from runtimeClasses.overheadEnabled)
# overhead: # override pod overhead (falls back to built-in defaults)
# memory: "160Mi"
# cpu: "250m"
@@ -344,6 +345,10 @@ runtimeClasses:
enabled: true
createDefault: false
defaultName: "kata"
# Global switch for overhead in all RuntimeClasses (default: true)
# Set to false to disable overhead for all shims globally.
# Individual shims can override this via shims.<name>.runtimeClass.overheadEnabled
overheadEnabled: true
env:
installationPrefix: ""

View File

@@ -4,8 +4,6 @@ required_tests:
- Pull request WIP checks / WIP Check
- Darwin tests / test
- Shellcheck required / shellcheck-required
# TODO: cargo-deny-runner.yaml not yet treated as conditional
- Cargo Crates Check Runner / cargo-deny-runner
- GHA security analysis / zizmor
- Lint GHA workflows / run-actionlint
- EditorConfig checker / editorconfig-checker
@@ -135,6 +133,7 @@ mapping:
static:
# Checks that static checks are passing
names:
- Cargo Deny Check / cargo-deny (bans licenses sources)
# static-checks.yaml (build-checks.yaml)
- Static checks / build-checks / check (make check, agent-ctl, src/tools/agent-ctl, rust, protobuf-compiler, clang, ubuntu-22.04)
- Static checks / build-checks / check (make check, agent, src/agent, rust, libdevmapper, libseccomp, protobuf-compiler, clang, ub...

View File

@@ -1,7 +1,7 @@
module module-path
// Keep in sync with version in versions.yaml
go 1.25.8
go 1.25.9
require (
github.com/sirupsen/logrus v1.9.3

View File

@@ -292,7 +292,7 @@ externals:
coco-guest-components:
description: "Provides attested key unwrapping for image decryption"
url: "https://github.com/confidential-containers/guest-components/"
version: "30b552e7841b10e656fa28cf643ed25b9d45e33f"
version: "de3f6ff62aa736619b80d99dfca5bc3d2c9a799d"
toolchain: "1.90.0"
coco-trustee:
@@ -470,12 +470,12 @@ languages:
description: "Google's 'go' language"
notes: "'version' is the default minimum version used by this project."
# When updating this, also update in go.mod files.
version: "1.25.8"
version: "1.25.9"
meta:
description: |
'newest-version' is the latest version known to work when
building Kata
newest-version: "1.25.8"
newest-version: "1.25.9"
rust:
description: "Rust language"