mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-04-12 06:52:10 +00:00
Compare commits
28 Commits
burgerdev/
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd6377a038 | ||
|
|
5eb7844183 | ||
|
|
8be3a24112 | ||
|
|
9448988783 | ||
|
|
a0410e0d5c | ||
|
|
a32c6fd9ff | ||
|
|
5bcc006447 | ||
|
|
7daeb78b67 | ||
|
|
3ce3644c3c | ||
|
|
6f3c11aec4 | ||
|
|
d4a042a155 | ||
|
|
78fa4c88e2 | ||
|
|
7244389ad4 | ||
|
|
1d77c4e60f | ||
|
|
ff26a6b876 | ||
|
|
2588a0e5a5 | ||
|
|
e8f34a2b26 | ||
|
|
36a2d8e7f2 | ||
|
|
82de35c720 | ||
|
|
fd6375d8d5 | ||
|
|
2312f67c9b | ||
|
|
218077506b | ||
|
|
dca89485f0 | ||
|
|
5e1ab0aa7d | ||
|
|
3b155ab0b1 | ||
|
|
31f9a5461b | ||
|
|
98ee385220 | ||
|
|
26ffe1223b |
@@ -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
|
||||
@@ -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
|
||||
32
.github/workflows/cargo-deny-runner.yaml
vendored
32
.github/workflows/cargo-deny-runner.yaml
vendored
@@ -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
38
.github/workflows/cargo-deny.yaml
vendored
Normal 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 }}
|
||||
2
.github/workflows/run-kata-coco-tests.yaml
vendored
2
.github/workflows/run-kata-coco-tests.yaml
vendored
@@ -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 }}
|
||||
|
||||
42
deny.toml
42
deny.toml
@@ -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"
|
||||
|
||||
@@ -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:?}");
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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")?;
|
||||
|
||||
|
||||
@@ -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)> {
|
||||
|
||||
@@ -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()
|
||||
});
|
||||
|
||||
|
||||
@@ -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()
|
||||
};
|
||||
|
||||
|
||||
@@ -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()
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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`,
|
||||
|
||||
@@ -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`,
|
||||
|
||||
@@ -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`,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"
|
||||
|
||||
2314
src/tools/agent-ctl/Cargo.lock
generated
2314
src/tools/agent-ctl/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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",
|
||||
] }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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//\\\"/\"}"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" = '''
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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: ""
|
||||
|
||||
@@ -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...
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user