Compare commits

...

29 Commits

Author SHA1 Message Date
Fabiano Fidêncio
734e75b7a4 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-07 13:26:05 +02:00
RuoqingHe
feaec78ad0 Merge pull request #12776 from fidencio/topic/kata-deploy-move-into-the-root-workspace
kata-deploy: Move into the root workspace
2026-04-07 12:45:26 +08:00
Fabiano Fidêncio
461907918d kata-deploy: pin nydus-snapshotter via versions.yaml
Resolve externals.nydus-snapshotter version and url in the Docker image build
with yq from the repo-root versions.yaml instead of Dockerfile ARG defaults.

Drop the redundant workflow that only enforced parity between those two sources.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-07 10:07:06 +08:00
Fabiano Fidêncio
9e1f595160 kata-deploy: add Rust binary to root workspace
Add tools/packaging/kata-deploy/binary as a workspace member, inherit shared
dependency versions from the root manifest, and refresh Cargo.lock.

Build the kata-deploy image from the repository root: copy the workspace
layout into the rust-builder stage, run cargo test/build with -p kata-deploy,
and adjust artifact and static asset COPY paths. Update the payload build
script to invoke docker buildx with -f .../Dockerfile from the repo root.

Add a repo-root .dockerignore to keep the Docker build context smaller.
Document running unit tests with cargo test -p kata-deploy from the root.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-07 10:07:06 +08:00
Alex Lyn
46a7b9e75d Merge pull request #12775 from RuoqingHe/put-libs-to-root-workspace
libs: Move libs into root workspace
2026-04-07 09:25:26 +08:00
Dan Mihai
9b770793ba Merge pull request #12728 from manuelh-dev/mahuber/empty-dir-fsgrou-policy
genpolicy: adjust GID after passwd GID handling and set fs_group for encrypted emptyDir volumes
2026-04-06 10:22:34 -07:00
Fabiano Fidêncio
47770daa3b helm: Align values.yaml with try-kata-nvidia-gpu.values.yaml
We've switched to nydus there, but never did for the values.yaml.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-06 18:51:54 +02:00
Fabiano Fidêncio
1300145f7a tests: add k3s/rke2 to OCI 1.3.0 drop-in overlay condition
k3s and rke2 ship containerd 2.2.2, which requires the OCI 1.3.0
drop-in overlay. Move them from the separate OCI 1.2.1 branch into
the OCI 1.3.0 condition alongside nvidia-gpu, qemu-snp, qemu-tdx,
and custom container engine versions.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-06 18:50:20 +02:00
Fabiano Fidêncio
0a739b3b55 Merge pull request #12755 from katexochen/runtime-rs-config-cleanup
runtime-rs: cleanup config
2026-04-06 13:14:58 +02:00
Ruoqing He
cb7c790dc7 libs: Specify crates explicitly in Makefile
--all option would trigger building and testing for everything within
our root workspace, which is not desired here. Let's specify the crates
of libs explicitly in our Makefile.

Signed-off-by: Ruoqing He <ruoqing.he@lingcage.com>
2026-04-06 11:03:38 +02:00
Ruoqing He
2a024f55d0 libs: Move libs into root workspace
Remove libs from exclude list, and move them explicitly into root
workspace to make sure our core components are in a consistent state.

This is a follow up of #12413.

Signed-off-by: Ruoqing He <ruoqing.he@lingcage.com>
2026-04-06 11:03:38 +02:00
Fabiano Fidêncio
9a2825a429 runtime: config: Use OVMF for the qemu-nvidia-gpu
2ba0cb0d4a7 did the ground work for using OVMF even for the
qemu-nvidia-gpu, but missed actually setting the OVMF path to be used,
which we'e fixing now.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-04-06 03:54:56 +02:00
Fabiano Fidêncio
e1fae11509 Merge pull request #12392 from Apokleos/enhance-tdx
runtime-rs: Enhance TDX in qemu
2026-04-05 20:54:43 +02:00
Alex Lyn
35cafe8715 runtime-rs: configure TDX machine options with kernel_irqchip=split
When TDX confidential guest support is enabled, set `kernel_irqchip=split`
for TDX CVM:
...
-machine \
   q35,accel=kvm,kernel_irqchip=split,confidential-guest-support=tdx \
...

Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
2026-04-05 10:18:47 +02:00
Fabiano Fidêncio
f074ceec6d Merge pull request #12682 from PiotrProkop/fix-direct-io-kata
runtime-rs: fix setting directio via config file
2026-04-03 16:11:57 +02:00
Fabiano Fidêncio
945aa5b43f Merge pull request #12774 from zvonkok/bump-nvrc
nvrc: Bump to the latest Release
2026-04-03 15:39:01 +02:00
Fabiano Fidêncio
ccfdf5e11b Merge pull request #12754 from llink5/fix/docker26-networking-9340
runtime: fix Docker 26+ networking by rescanning after Start
2026-04-03 13:15:38 +02:00
RuoqingHe
26bd5ad754 Merge pull request #12762 from YutingNie/fix-runtime-rs-shared-fs-typo
runtime-rs: Fix typo in share_fs error message
2026-04-03 15:24:33 +08:00
Yuting Nie
517882f93d runtime-rs: Fix typo in share_fs error message
There's a typo in the error message which gets prompted when an
unsupported share_fs was configured. Fixed shred -> shared.

Signed-off-by: Yuting Nie <yuting.nie@spacemit.com>
2026-04-03 05:23:46 +00:00
Alex Lyn
4a1c2b6620 Merge pull request #12309 from kata-containers/stale-issues-by-date
workflows: Create workflow to stale issues based on date
2026-04-03 09:31:34 +08:00
Zvonko Kaiser
3e23ee9998 nvrc: Bump to the latest Release
v0.1.4 has a bugfix for nvrc.log=trace which is now
optional.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-04-02 17:40:47 -04:00
llink5
f7878cc385 runtime: fix Docker 26+ networking by rescanning after Start
Docker 26+ configures container networking (veth pair, IP addresses,
routes) after task creation rather than before. Kata's endpoint scan
runs during CreateSandbox, before the interfaces exist, resulting in
VMs starting without network connectivity (no -netdev passed to QEMU).

Add RescanNetwork() which runs asynchronously after the Start RPC.
It polls the network namespace until Docker's interfaces appear, then
hotplugs them to QEMU and informs the guest agent to configure them
inside the VM.

Additional fixes:
- mountinfo parser: find fs type dynamically instead of hardcoded
  field index, fixing parsing with optional mount tags (shared:,
  master:)
- IsDockerContainer: check CreateRuntime hooks for Docker 26+
- DockerNetnsPath: extract netns path from libnetwork-setkey hook
  args with path traversal protection
- detectHypervisorNetns: verify PID ownership via /proc/pid/cmdline
  to guard against PID recycling
- startVM guard: rescan when len(endpoints)==0 after VM start

Fixes: #9340

Signed-off-by: llink5 <llink5@users.noreply.github.com>
2026-04-02 21:23:16 +02:00
Manuel Huber
57e42b10f1 tests: nvidia: Do not use elevated privileges
Do not run the NIM containers with elevated privileges. Note that,
using hostPath requires proper host folder permissions, and that
using emptyDir requires a proper fsGroup ID.
Once issue 11162 is resolved, we can further refine the securityContext
fields for the TEE manifests.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-04-01 10:23:26 -07:00
Manuel Huber
a762b136de tests: generate policy for pod-empty-dir-fsgroup
The logic in the k8s-empty-dirs.bats file missed to add a security
policy for the pod-empty-dir-fsgroup.yaml manifest. With this change,
we add the policy annotation.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-04-01 10:23:26 -07:00
Manuel Huber
43489f6d56 genpolicy: fs_group for encrypted emptyDir volumes
The shim uses Storage.fs_group on block/scsi encrypted emptyDir while
genpolicy used fsgid= in options and null fs_group, leading to
denying CreateContainerRequest when using block-encrypted emptyDir in
combination with fsGroup. Thus, emit fs_group in that scenario and keep
fsgid= for the existing shared-fs/local emptyDir behavior.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-04-01 10:23:26 -07:00
Manuel Huber
9923f251f5 genpolicy: adjust GID after passwd GID handling
After pod runAsUser triggers passwd-based GID resolution, genpolicy
clears AdditionalGids and inserts only the primary GID.
PodSecurityContext fsGroup and supplementalGroups get cleared, so
policy enforcement would deny CreateContainer when the runtime
includes those when specified.

This change applies fsGroup/supplementalGroups once in
get_container_process via apply_pod_fs_group_and_supplemental_groups.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-04-01 10:23:25 -07:00
PiotrProkop
67af63a540 runtime-rs: fix setting directio via config file
This fix applies the config file value as a fallback when block_device_cache_direct annotation is not explicitly set on the pod.

Signed-off-by: PiotrProkop <pprokop@nvidia.com>
2026-04-01 16:59:04 +02:00
stevenhorsman
99eaa8fcb1 workflows: Create workflow to stale issues based on date
The standard stale/action is intended to be run regularly with
a date offset, but we want to have one we can run against a specific
date in order to run the stale bot against issues created since a particular
release milestone, so calculate the offset in one step and use it in the next.

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

Note the stale action only processes a few issues at a time to avoid rate limiting, so why we want a cron job to it can get through
the backlog, but also to stale/unstale issues that are commented on.

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-03-31 15:57:37 +01:00
Paul Meyer
086c0ed18e runtime-rs: cleanup config
Some fields were misspelled, misplaced at an outdated path or copied
over from runtime-go but aren't supported in runtime-rs.
Cleaning them up to avoid confusion and ease migration.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-03-31 10:51:25 +02:00
65 changed files with 1547 additions and 573 deletions

13
.dockerignore Normal file
View File

@@ -0,0 +1,13 @@
# Context for tools/packaging/kata-deploy/Dockerfile (build from repo root: -f tools/packaging/kata-deploy/Dockerfile .)
#
# The Dockerfile only needs: Cargo.toml, Cargo.lock, src/, tools/packaging/kata-deploy/,
# and versions.yaml. Exclude heavy or irrelevant trees to keep context small.
.git
.github
target
kata-artifacts
docs
tests
utils
tools/packaging/kata-deploy/local-build
tools/packaging/kata-deploy/binary/target

View File

@@ -269,6 +269,50 @@ jobs:
timeout-minutes: 15
run: bash tests/functional/vfio/gha-run.sh run
run-docker-tests:
name: run-docker-tests
strategy:
# We can set this to true whenever we're 100% sure that
# all the tests are not flaky, otherwise we'll fail them
# all due to a single flaky instance.
fail-fast: false
matrix:
vmm:
- qemu
runs-on: ubuntu-22.04
env:
KATA_HYPERVISOR: ${{ matrix.vmm }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.commit-hash }}
fetch-depth: 0
persist-credentials: false
- name: Rebase atop of the latest target branch
run: |
./tests/git-helper.sh "rebase-atop-of-the-latest-target-branch"
env:
TARGET_BRANCH: ${{ inputs.target-branch }}
- name: Install dependencies
run: bash tests/integration/docker/gha-run.sh install-dependencies
env:
GH_TOKEN: ${{ github.token }}
- name: get-kata-tarball
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: kata-static-tarball-amd64${{ inputs.tarball-suffix }}
path: kata-artifacts
- name: Install kata
run: bash tests/integration/docker/gha-run.sh install-kata kata-artifacts
- name: Run docker smoke test
timeout-minutes: 5
run: bash tests/integration/docker/gha-run.sh run
run-nerdctl-tests:
name: run-nerdctl-tests
strategy:

View File

@@ -123,3 +123,44 @@ jobs:
- name: Run containerd-stability tests
timeout-minutes: 15
run: bash tests/stability/gha-run.sh run
run-docker-tests:
name: run-docker-tests
strategy:
# We can set this to true whenever we're 100% sure that
# all the tests are not flaky, otherwise we'll fail them
# all due to a single flaky instance.
fail-fast: false
matrix:
vmm: ['qemu']
runs-on: s390x-large
env:
KATA_HYPERVISOR: ${{ matrix.vmm }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.commit-hash }}
fetch-depth: 0
persist-credentials: false
- name: Rebase atop of the latest target branch
run: |
./tests/git-helper.sh "rebase-atop-of-the-latest-target-branch"
env:
TARGET_BRANCH: ${{ inputs.target-branch }}
- name: Install dependencies
run: bash tests/integration/docker/gha-run.sh install-dependencies
- name: get-kata-tarball
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: kata-static-tarball-s390x${{ inputs.tarball-suffix }}
path: kata-artifacts
- name: Install kata
run: bash tests/integration/docker/gha-run.sh install-kata kata-artifacts
- name: Run docker smoke test
timeout-minutes: 5
run: bash tests/integration/docker/gha-run.sh run

View File

@@ -1,35 +0,0 @@
name: nydus-snapshotter-version-sync
on:
pull_request:
types:
- opened
- edited
- reopened
- synchronize
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
nydus-snapshotter-version-check:
name: nydus-snapshotter-version-check
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Ensure nydus-snapshotter-version is in sync inside our repo
run: |
dockerfile_version=$(grep "ARG NYDUS_SNAPSHOTTER_VERSION" tools/packaging/kata-deploy/Dockerfile | cut -f2 -d'=')
versions_version=$(yq ".externals.nydus-snapshotter.version | explode(.)" versions.yaml)
if [[ "${dockerfile_version}" != "${versions_version}" ]]; then
echo "nydus-snapshotter version must be the same in the following places: "
echo "- versions.yaml: ${versions_version}"
echo "- tools/packaging/kata-deploy/Dockerfile: ${dockerfile_version}"
exit 1
fi

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 }}

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

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

478
Cargo.lock generated
View File

@@ -94,6 +94,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -409,6 +415,28 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "async-stream"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
dependencies = [
"async-stream-impl",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-stream-impl"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "async-task"
version = "4.7.1"
@@ -511,6 +539,17 @@ dependencies = [
"tower-service",
]
[[package]]
name = "backon"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef"
dependencies = [
"fastrand 2.3.0",
"gloo-timers",
"tokio",
]
[[package]]
name = "backtrace"
version = "0.3.76"
@@ -1272,6 +1311,16 @@ dependencies = [
"darling_macro 0.20.11",
]
[[package]]
name = "darling"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
dependencies = [
"darling_core 0.21.3",
"darling_macro 0.21.3",
]
[[package]]
name = "darling_core"
version = "0.14.4"
@@ -1299,6 +1348,20 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "darling_core"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.117",
]
[[package]]
name = "darling_macro"
version = "0.14.4"
@@ -1321,6 +1384,17 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "darling_macro"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
dependencies = [
"darling_core 0.21.3",
"quote",
"syn 2.0.117",
]
[[package]]
name = "dashmap"
version = "5.5.3"
@@ -1600,6 +1674,27 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "derive_more"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"syn 2.0.117",
]
[[package]]
name = "device_tree"
version = "1.1.0"
@@ -1726,6 +1821,18 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]]
name = "educe"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417"
dependencies = [
"enum-ordinalize",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "either"
version = "1.15.0"
@@ -1774,6 +1881,26 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "enum-ordinalize"
version = "4.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0"
dependencies = [
"enum-ordinalize-derive",
]
[[package]]
name = "enum-ordinalize-derive"
version = "4.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "enumflags2"
version = "0.7.12"
@@ -2338,6 +2465,18 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "gloo-timers"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994"
dependencies = [
"futures-channel",
"futures-core",
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "go-flag"
version = "0.1.0"
@@ -2406,6 +2545,8 @@ version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
]
@@ -2506,6 +2647,17 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "hostname"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd"
dependencies = [
"cfg-if 1.0.4",
"libc",
"windows-link",
]
[[package]]
name = "http"
version = "0.2.12"
@@ -2643,7 +2795,9 @@ dependencies = [
"http 1.4.0",
"hyper 1.8.1",
"hyper-util",
"log",
"rustls",
"rustls-native-certs",
"rustls-pki-types",
"tokio",
"tokio-rustls",
@@ -2662,6 +2816,19 @@ dependencies = [
"tokio-io-timeout",
]
[[package]]
name = "hyper-timeout"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
dependencies = [
"hyper 1.8.1",
"hyper-util",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
@@ -3127,6 +3294,19 @@ dependencies = [
"thiserror 1.0.69",
]
[[package]]
name = "jsonpath-rust"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c00ae348f9f8fd2d09f82a98ca381c60df9e0820d8d79fce43e649b4dc3128b"
dependencies = [
"pest",
"pest_derive",
"regex",
"serde_json",
"thiserror 2.0.18",
]
[[package]]
name = "jsonptr"
version = "0.4.7"
@@ -3201,6 +3381,18 @@ dependencies = [
"tonic-build 0.8.4",
]
[[package]]
name = "k8s-openapi"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06d9e5e61dd037cdc51da0d7e2b2be10f497478ea7e120d85dad632adb99882b"
dependencies = [
"base64 0.22.1",
"chrono",
"serde",
"serde_json",
]
[[package]]
name = "kata-agent"
version = "0.1.0"
@@ -3285,6 +3477,28 @@ dependencies = [
"tokio",
]
[[package]]
name = "kata-deploy"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"env_logger",
"k8s-openapi",
"kube",
"libc",
"log",
"regex",
"rstest",
"serde_json",
"serde_yaml 0.9.34+deprecated",
"serial_test 0.10.0",
"tempfile",
"tokio",
"toml_edit 0.22.27",
"walkdir",
]
[[package]]
name = "kata-sys-util"
version = "0.1.0"
@@ -3307,6 +3521,8 @@ dependencies = [
"slog",
"slog-scope",
"subprocess",
"tempfile",
"test-utils",
"thiserror 1.0.69",
]
@@ -3325,6 +3541,7 @@ dependencies = [
"num_cpus",
"oci-spec 0.8.4",
"regex",
"rstest",
"safe-path 0.1.0",
"serde",
"serde-enum-str",
@@ -3334,6 +3551,8 @@ dependencies = [
"slog-scope",
"sysctl",
"sysinfo",
"tempfile",
"test-utils",
"thiserror 1.0.69",
"toml",
]
@@ -3358,6 +3577,115 @@ dependencies = [
"libc",
]
[[package]]
name = "kube"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e7bb0b6a46502cc20e4575b6ff401af45cfea150b34ba272a3410b78aa014e"
dependencies = [
"k8s-openapi",
"kube-client",
"kube-core",
"kube-derive",
"kube-runtime",
]
[[package]]
name = "kube-client"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4987d57a184d2b5294fdad3d7fc7f278899469d21a4da39a8f6ca16426567a36"
dependencies = [
"base64 0.22.1",
"bytes 1.11.1",
"chrono",
"either",
"futures",
"home",
"http 1.4.0",
"http-body 1.0.1",
"http-body-util",
"hyper 1.8.1",
"hyper-rustls",
"hyper-timeout 0.5.2",
"hyper-util",
"jsonpath-rust",
"k8s-openapi",
"kube-core",
"pem",
"rustls",
"secrecy",
"serde",
"serde_json",
"serde_yaml 0.9.34+deprecated",
"thiserror 2.0.18",
"tokio",
"tokio-util",
"tower 0.5.3",
"tower-http",
"tracing",
]
[[package]]
name = "kube-core"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "914bbb770e7bb721a06e3538c0edd2babed46447d128f7c21caa68747060ee73"
dependencies = [
"chrono",
"derive_more",
"form_urlencoded",
"http 1.4.0",
"json-patch 4.1.0",
"k8s-openapi",
"schemars",
"serde",
"serde-value",
"serde_json",
"thiserror 2.0.18",
]
[[package]]
name = "kube-derive"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03dee8252be137772a6ab3508b81cd797dee62ee771112a2453bc85cbbe150d2"
dependencies = [
"darling 0.21.3",
"proc-macro2",
"quote",
"serde",
"serde_json",
"syn 2.0.117",
]
[[package]]
name = "kube-runtime"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aea4de4b562c5cc89ab10300bb63474ae1fa57ff5a19275f2e26401a323e3fd"
dependencies = [
"ahash 0.8.12",
"async-broadcast 0.7.2",
"async-stream",
"backon",
"educe",
"futures",
"hashbrown 0.15.5",
"hostname",
"json-patch 4.1.0",
"k8s-openapi",
"kube-client",
"parking_lot",
"pin-project",
"serde",
"serde_json",
"thiserror 2.0.18",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "kvm-bindings"
version = "0.14.0"
@@ -3539,6 +3867,7 @@ dependencies = [
"slog-json",
"slog-scope",
"slog-term",
"tempfile",
]
[[package]]
@@ -3584,11 +3913,16 @@ version = "0.2.0"
dependencies = [
"anyhow",
"chrono",
"lazy_static",
"maplit",
"nix 0.30.1",
"once_cell",
"page_size",
"slog",
"slog-async",
"slog-scope",
"slog-term",
"test-utils",
"tokio",
]
@@ -4493,6 +4827,15 @@ dependencies = [
"num-traits",
]
[[package]]
name = "ordered-float"
version = "2.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
dependencies = [
"num-traits",
]
[[package]]
name = "ordered-multimap"
version = "0.4.3"
@@ -4602,6 +4945,16 @@ dependencies = [
"quote",
]
[[package]]
name = "pem"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
dependencies = [
"base64 0.22.1",
"serde_core",
]
[[package]]
name = "percent-encoding"
version = "2.3.2"
@@ -4621,6 +4974,49 @@ dependencies = [
"serde_json",
]
[[package]]
name = "pest"
version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662"
dependencies = [
"memchr",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "pest_meta"
version = "2.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220"
dependencies = [
"pest",
"sha2 0.10.9",
]
[[package]]
name = "petgraph"
version = "0.5.1"
@@ -5974,7 +6370,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
dependencies = [
"aws-lc-rs",
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
@@ -6073,6 +6471,7 @@ name = "safe-path"
version = "0.1.0"
dependencies = [
"libc",
"tempfile",
]
[[package]]
@@ -6119,10 +6518,23 @@ checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
dependencies = [
"dyn-clone",
"ref-cast",
"schemars_derive",
"serde",
"serde_json",
]
[[package]]
name = "schemars_derive"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f"
dependencies = [
"proc-macro2",
"quote",
"serde_derive_internals",
"syn 2.0.117",
]
[[package]]
name = "scientific"
version = "0.5.3"
@@ -6164,6 +6576,15 @@ dependencies = [
"libc",
]
[[package]]
name = "secrecy"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a"
dependencies = [
"zeroize",
]
[[package]]
name = "security-framework"
version = "3.7.0"
@@ -6243,6 +6664,16 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8a059d895f1a31dd928f40abbea4e7177e3d8ff3aa4152fdb7a396ae1ef63a3"
[[package]]
name = "serde-value"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
dependencies = [
"ordered-float 2.10.1",
"serde",
]
[[package]]
name = "serde_core"
version = "1.0.228"
@@ -6263,6 +6694,17 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "serde_derive_internals"
version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "serde_ignored"
version = "0.1.14"
@@ -6496,6 +6938,8 @@ dependencies = [
"kata-sys-util",
"kata-types",
"nix 0.26.4",
"tempfile",
"test-utils",
"tokio",
]
@@ -7015,7 +7459,7 @@ dependencies = [
"byteorder",
"integer-encoding",
"log",
"ordered-float",
"ordered-float 1.1.1",
"threadpool",
]
@@ -7163,6 +7607,7 @@ dependencies = [
"futures-core",
"futures-sink",
"pin-project-lite",
"slab",
"tokio",
]
@@ -7227,6 +7672,18 @@ dependencies = [
"winnow 0.5.40",
]
[[package]]
name = "toml_edit"
version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap 2.13.0",
"toml_datetime 0.6.11",
"toml_write",
"winnow 0.7.15",
]
[[package]]
name = "toml_edit"
version = "0.25.4+spec-1.1.0"
@@ -7248,6 +7705,12 @@ dependencies = [
"winnow 0.7.15",
]
[[package]]
name = "toml_write"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
[[package]]
name = "tonic"
version = "0.9.2"
@@ -7264,7 +7727,7 @@ dependencies = [
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.32",
"hyper-timeout",
"hyper-timeout 0.4.1",
"percent-encoding",
"pin-project",
"prost 0.11.9",
@@ -7333,8 +7796,10 @@ dependencies = [
"pin-project-lite",
"sync_wrapper 1.0.2",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
@@ -7343,16 +7808,19 @@ version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
dependencies = [
"base64 0.22.1",
"bitflags 2.11.0",
"bytes 1.11.1",
"futures-util",
"http 1.4.0",
"http-body 1.0.1",
"iri-string",
"mime",
"pin-project-lite",
"tower 0.5.3",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
@@ -7525,6 +7993,12 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "uds_windows"
version = "1.2.0"

View File

@@ -6,6 +6,17 @@ rust-version = "1.88"
[workspace]
members = [
# libs
"src/libs/kata-sys-util",
"src/libs/kata-types",
"src/libs/logging",
"src/libs/mem-agent",
"src/libs/protocols",
"src/libs/runtime-spec",
"src/libs/safe-path",
"src/libs/shim-interface",
"src/libs/test-utils",
# kata-agent
"src/agent",
"src/agent/rustjail",
@@ -31,6 +42,9 @@ members = [
# genpolicy
"src/tools/genpolicy",
# kata-deploy (Kubernetes installer binary)
"tools/packaging/kata-deploy/binary",
# runtime-rs
"src/runtime-rs",
"src/runtime-rs/crates/agent",
@@ -48,10 +62,6 @@ resolver = "2"
# TODO: Add all excluded crates to root workspace
exclude = [
"src/tools",
"src/libs",
# kata-deploy binary is standalone and has its own Cargo.toml for now
"tools/packaging/kata-deploy/binary",
# We are cloning and building rust packages under
# "tools/packaging/kata-deploy/local-build/build" folder, which may mislead

View File

@@ -1,13 +0,0 @@
[workspace]
members = [
"kata-sys-util",
"kata-types",
"logging",
"mem-agent",
"protocols",
"runtime-spec",
"safe-path",
"shim-interface",
"test-utils",
]
resolver = "2"

View File

@@ -11,6 +11,17 @@ ifeq ($(USERID), 0)
override EXTRA_TEST_FLAGS = --ignored
endif
LIBS := \
-p kata-sys-util \
-p kata-types \
-p logging \
-p mem-agent \
-p protocols \
-p runtime-spec \
-p safe-path \
-p shim-interface \
-p test-utils
default: build
build:
@@ -23,13 +34,13 @@ check: clippy format
clippy:
@echo "INFO: cargo clippy..."
cargo clippy --all-targets --all-features --release \
cargo clippy $(LIBS) --all-features --release \
-- \
-D warnings
format:
@echo "INFO: cargo fmt..."
cargo fmt -- --check
cargo fmt $(LIBS) -- --check
clean:
cargo clean
@@ -38,8 +49,8 @@ clean:
# See the `test_logger_levels()` test for further information.
test:
@echo "INFO: testing libraries for development build"
cargo test --all $(EXTRA_RUSTFEATURES) -- --nocapture $(EXTRA_TEST_FLAGS)
cargo test $(LIBS) $(EXTRA_RUSTFEATURES) -- --nocapture $(EXTRA_TEST_FLAGS)
@echo "INFO: testing libraries for release build"
cargo test --release --all $(EXTRA_RUSTFEATURES) -- --nocapture $(EXTRA_TEST_FLAGS)
cargo test --release $(LIBS) $(EXTRA_RUSTFEATURES) -- --nocapture $(EXTRA_TEST_FLAGS)
.PHONY: install vendor

View File

@@ -137,16 +137,12 @@ ifeq ($(ARCH), aarch64)
EDK2_NAME := aavmf
endif
# Set firmware paths from QEMUFW/QEMUFWVOL if defined
# Set firmware path from QEMUFW if defined
FIRMWAREPATH :=
FIRMWAREVOLUMEPATH :=
ifneq (,$(QEMUCMD))
ifneq (,$(QEMUFW))
FIRMWAREPATH := $(PREFIXDEPS)/share/$(EDK2_NAME)/$(QEMUFW)
endif
ifneq (,$(QEMUFWVOL))
FIRMWAREVOLUMEPATH := $(PREFIXDEPS)/share/$(EDK2_NAME)/$(QEMUFWVOL)
endif
endif
KERNELVERITYPARAMS ?= ""
@@ -157,7 +153,6 @@ FIRMWARETDVFPATH := $(PREFIXDEPS)/share/ovmf/OVMF.inteltdx.fd
# SEV-SNP
FIRMWARE_SNP_PATH := $(PREFIXDEPS)/share/ovmf/AMDSEV.fd
FIRMWARE_VOLUME_SNP_PATH :=
##VAR DEFVCPUS=<number> Default number of vCPUs
DEFVCPUS := 1
@@ -204,7 +199,6 @@ DEFVIRTIOFSQUEUESIZE ?= 1024
# Make sure you quote args.
DEFVIRTIOFSEXTRAARGS ?= [\"--thread-pool-size=1\", \"-o\", \"announce_submounts\"]
DEFENABLEIOTHREADS := false
DEFINDEPIOTHREADS := 0
DEFENABLEVHOSTUSERSTORE := false
DEFVHOSTUSERSTOREPATH := $(PKGRUNDIR)/vhost-user
DEFVALIDVHOSTUSERSTOREPATHS := [\"$(DEFVHOSTUSERSTOREPATH)\"]
@@ -222,7 +216,6 @@ DEFCREATECONTAINERTIMEOUT ?= 30
DEFCREATECONTAINERTIMEOUT_COCO ?= 60
DEFSTATICRESOURCEMGMT_COCO = true
DEFDISABLEIMAGENVDIMM ?= false
DEFPODRESOURCEAPISOCK := ""
SED = sed
CLI_DIR = cmd
@@ -412,9 +405,6 @@ endif
# Most users will want to set this to "on,obsolete=deny,spawn=deny,resourcecontrol=deny"
# for better security. Note: "elevateprivileges=deny" doesn't work with daemonize option.
DEFSECCOMPSANDBOXPARAM := ""
# Default is empty string "" to match Rust default None (when commented out in config).
# Most users will want to set this to "system_u:system_r:container_t" for SELinux support.
DEFGUESTSELINUXLABEL := ""
endif
ifneq (,$(FCCMD))
@@ -524,7 +514,6 @@ USER_VARS += KERNELPATH_COCO
USER_VARS += KERNELPATH
USER_VARS += KERNELVIRTIOFSPATH
USER_VARS += FIRMWAREPATH
USER_VARS += FIRMWAREVOLUMEPATH
USER_VARS += MACHINEACCELERATORS
USER_VARS += CPUFEATURES
USER_VARS += DEFMACHINETYPE_CLH
@@ -584,9 +573,7 @@ USER_VARS += DEFVIRTIOFSEXTRAARGS
USER_VARS += DEFENABLEANNOTATIONS
USER_VARS += DEFENABLEANNOTATIONS_COCO
USER_VARS += DEFENABLEIOTHREADS
USER_VARS += DEFINDEPIOTHREADS
USER_VARS += DEFSECCOMPSANDBOXPARAM
USER_VARS += DEFGUESTSELINUXLABEL
USER_VARS += DEFENABLEVHOSTUSERSTORE
USER_VARS += DEFVHOSTUSERSTOREPATH
USER_VARS += DEFVALIDVHOSTUSERSTOREPATHS
@@ -628,11 +615,9 @@ USER_VARS += DEFCREATECONTAINERTIMEOUT
USER_VARS += DEFCREATECONTAINERTIMEOUT_COCO
USER_VARS += QEMUTDXEXPERIMENTALCMD
USER_VARS += FIRMWARE_SNP_PATH
USER_VARS += FIRMWARE_VOLUME_SNP_PATH
USER_VARS += KERNELTDXPARAMS
USER_VARS += DEFSHAREDFS_QEMU_TDX_VIRTIOFS
USER_VARS += FIRMWARETDVFPATH
USER_VARS += DEFPODRESOURCEAPISOCK
SOURCES := \
$(shell find . 2>&1 | grep -E '.*\.rs$$') \

View File

@@ -13,7 +13,6 @@ CPUFEATURES := pmu=off
QEMUCMD := qemu-system-aarch64
QEMUFW := AAVMF_CODE.fd
QEMUFWVOL := AAVMF_VARS.fd
# dragonball binary name
DBCMD := dragonball

View File

@@ -76,12 +76,6 @@ kernel_params = "@KERNELPARAMS@"
# If you want that qemu uses the default firmware leave this option empty
firmware = "@FIRMWAREPATH@"
# Path to the firmware volume.
# firmware TDVF or OVMF can be split into FIRMWARE_VARS.fd (UEFI variables
# as configuration) and FIRMWARE_CODE.fd (UEFI program image). UEFI variables
# can be customized per each user while UEFI code is kept same.
firmware_volume = "@FIRMWAREVOLUMEPATH@"
# Machine accelerators
# comma-separated list of machine accelerators to pass to the hypervisor.
# For example, `machine_accelerators = "nosmm,nosmbus,nosata,nopit,static-prt,nofw"`
@@ -89,12 +83,12 @@ machine_accelerators = "@MACHINEACCELERATORS@"
# Qemu seccomp sandbox feature
# comma-separated list of seccomp sandbox features to control the syscall access.
# For example, `seccompsandbox= "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# For example, `seccomp_sandbox = "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# Note: "elevateprivileges=deny" doesn't work with daemonize option, so it's removed from the seccomp sandbox
# Another note: enabling this feature may reduce performance, you may enable
# /proc/sys/net/core/bpf_jit_enable to reduce the impact. see https://man7.org/linux/man-pages/man8/bpfc.8.html
# Recommended value when enabling: "on,obsolete=deny,spawn=deny,resourcecontrol=deny"
seccompsandbox = "@DEFSECCOMPSANDBOXPARAM@"
seccomp_sandbox = "@DEFSECCOMPSANDBOXPARAM@"
# CPU features
# comma-separated list of cpu features to pass to the cpu
@@ -311,11 +305,6 @@ enable_iommu_platform = false
# Your distribution recommends: @DEFVALIDVHOSTUSERSTOREPATHS@
valid_vhost_user_store_paths = @DEFVALIDVHOSTUSERSTOREPATHS@
# The timeout for reconnecting on non-server spdk sockets when the remote end goes away.
# qemu will delay this many seconds and then attempt to reconnect.
# Zero disables reconnecting, and the default is zero.
vhost_user_reconnect_timeout_sec = 0
# Enable file based guest memory support. The default is an empty string which
# will disable this feature. In the case of virtio-fs, this is enabled
# automatically and '/dev/shm' is used as the backing folder.
@@ -350,7 +339,7 @@ enable_debug = false
#
# If set to the empty string "", no extra monitor socket is added. This is
# the default.
extra_monitor_socket = ""
dbg_monitor_socket = ""
# Disable the customizations done in the runtime when it detects
# that it is running on top a VMM. This will result in the runtime
@@ -378,18 +367,6 @@ disable_image_nvdimm = false
# Default false
hotplug_vfio_on_root_bus = false
# Enable hot-plugging of VFIO devices to a bridge-port,
# root-port or switch-port.
# The default setting is "no-port"
hot_plug_vfio = "no-port"
# In a confidential compute environment hot-plugging can compromise
# security.
# Enable cold-plugging of VFIO devices to a bridge-port,
# root-port or switch-port.
# The default setting is "no-port", which means disabled.
cold_plug_vfio = "no-port"
# Before hot plugging a PCIe device, you need to add a pcie_root_port device.
# Use this parameter when using some large PCI bar devices, such as Nvidia GPU
# The value means the number of pcie_root_port
@@ -483,9 +460,6 @@ guest_memory_dump_path = ""
# See: https://www.qemu.org/docs/master/qemu-qmp-ref.html#Dump-guest-memory for details
#guest_memory_dump_paging=false
# use legacy serial for guest console if available and implemented for architecture. Default false
use_legacy_serial = false
# disable applying SELinux on the VMM process (default false)
disable_selinux = @DEFDISABLESELINUX@
@@ -497,7 +471,7 @@ disable_selinux = @DEFDISABLESELINUX@
disable_guest_selinux = @DEFDISABLEGUESTSELINUX@
[factory]
[hypervisor.qemu.factory]
# VM templating support. Once enabled, new VMs are created from template
# using vm cloning. They will share the same initial kernel, initramfs and
# agent memory by mapping it readonly. It helps speeding up new container
@@ -726,20 +700,6 @@ agent_name = "@PROJECT_TYPE@"
# (default: true)
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
# 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`,
# so general users should not uncomment and apply it.
# (format: "user:role:type")
# Note: You cannot specify MCS policy with the label because the sensitivity levels and
# categories are determined automatically by high-level container runtimes such as containerd.
# Example value when enabling: "system_u:system_r:container_t"
guest_selinux_label = "@DEFGUESTSELINUXLABEL@"
# If enabled, the runtime will create opentracing.io traces and spans.
# (See https://www.jaegertracing.io/docs/getting-started).
# (default: disabled)

View File

@@ -60,12 +60,6 @@ kernel_params = "@KERNELPARAMS@"
# If you want that qemu uses the default firmware leave this option empty
firmware = "@FIRMWAREPATH@"
# Path to the firmware volume.
# firmware TDVF or OVMF can be split into FIRMWARE_VARS.fd (UEFI variables
# as configuration) and FIRMWARE_CODE.fd (UEFI program image). UEFI variables
# can be customized per each user while UEFI code is kept same.
firmware_volume = "@FIRMWAREVOLUMEPATH@"
# Machine accelerators
# comma-separated list of machine accelerators to pass to the hypervisor.
# For example, `machine_accelerators = "nosmm,nosmbus,nosata,nopit,static-prt,nofw"`
@@ -73,12 +67,12 @@ machine_accelerators = "@MACHINEACCELERATORS@"
# Qemu seccomp sandbox feature
# comma-separated list of seccomp sandbox features to control the syscall access.
# For example, `seccompsandbox= "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# For example, `seccomp_sandbox = "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# Note: "elevateprivileges=deny" doesn't work with daemonize option, so it's removed from the seccomp sandbox
# Another note: enabling this feature may reduce performance, you may enable
# /proc/sys/net/core/bpf_jit_enable to reduce the impact. see https://man7.org/linux/man-pages/man8/bpfc.8.html
# Recommended value when enabling: "on,obsolete=deny,spawn=deny,resourcecontrol=deny"
seccompsandbox = "@DEFSECCOMPSANDBOXPARAM@"
seccomp_sandbox = "@DEFSECCOMPSANDBOXPARAM@"
# CPU features
# comma-separated list of cpu features to pass to the cpu
@@ -307,11 +301,6 @@ enable_iommu_platform = false
# Your distribution recommends: @DEFVALIDVHOSTUSERSTOREPATHS@
valid_vhost_user_store_paths = @DEFVALIDVHOSTUSERSTOREPATHS@
# The timeout for reconnecting on non-server spdk sockets when the remote end goes away.
# qemu will delay this many seconds and then attempt to reconnect.
# Zero disables reconnecting, and the default is zero.
vhost_user_reconnect_timeout_sec = 0
# Enable file based guest memory support. The default is an empty string which
# will disable this feature. In the case of virtio-fs, this is enabled
# automatically and '/dev/shm' is used as the backing folder.
@@ -346,7 +335,7 @@ enable_debug = false
#
# If set to the empty string "", no extra monitor socket is added. This is
# the default.
extra_monitor_socket = ""
dbg_monitor_socket = ""
# Disable the customizations done in the runtime when it detects
# that it is running on top a VMM. This will result in the runtime
@@ -373,18 +362,6 @@ disable_image_nvdimm = false
# Default false
hotplug_vfio_on_root_bus = false
# Enable hot-plugging of VFIO devices to a bridge-port,
# root-port or switch-port.
# The default setting is "no-port"
hot_plug_vfio = "no-port"
# In a confidential compute environment hot-plugging can compromise
# security.
# Enable cold-plugging of VFIO devices to a bridge-port,
# root-port or switch-port.
# The default setting is "no-port", which means disabled.
cold_plug_vfio = "no-port"
# Before hot plugging a PCIe device, you need to add a pcie_root_port device.
# Use this parameter when using some large PCI bar devices, such as Nvidia GPU
# The value means the number of pcie_root_port
@@ -489,9 +466,6 @@ guest_memory_dump_path = ""
# See: https://www.qemu.org/docs/master/qemu-qmp-ref.html#Dump-guest-memory for details
guest_memory_dump_paging = false
# use legacy serial for guest console if available and implemented for architecture. Default false
use_legacy_serial = false
# disable applying SELinux on the VMM process (default false)
disable_selinux = @DEFDISABLESELINUX@
@@ -720,20 +694,6 @@ agent_name = "@PROJECT_TYPE@"
# (default: true)
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
# 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`,
# so general users should not uncomment and apply it.
# (format: "user:role:type")
# Note: You cannot specify MCS policy with the label because the sensitivity levels and
# categories are determined automatically by high-level container runtimes such as containerd.
# Example value when enabling: "system_u:system_r:container_t"
guest_selinux_label = "@DEFGUESTSELINUXLABEL@"
# If enabled, the runtime will create opentracing.io traces and spans.
# (See https://www.jaegertracing.io/docs/getting-started).
# (default: disabled)

View File

@@ -69,12 +69,6 @@ kernel_params = "@KERNELPARAMS@"
# If you want that qemu uses the default firmware leave this option empty
firmware = "@FIRMWAREPATH@"
# Path to the firmware volume.
# firmware TDVF or OVMF can be split into FIRMWARE_VARS.fd (UEFI variables
# as configuration) and FIRMWARE_CODE.fd (UEFI program image). UEFI variables
# can be customized per each user while UEFI code is kept same.
firmware_volume = "@FIRMWAREVOLUMEPATH@"
# Machine accelerators
# comma-separated list of machine accelerators to pass to the hypervisor.
# For example, `machine_accelerators = "nosmm,nosmbus,nosata,nopit,static-prt,nofw"`
@@ -82,12 +76,12 @@ machine_accelerators = "@MACHINEACCELERATORS@"
# Qemu seccomp sandbox feature
# comma-separated list of seccomp sandbox features to control the syscall access.
# For example, `seccompsandbox= "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# For example, `seccomp_sandbox = "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# Note: "elevateprivileges=deny" doesn't work with daemonize option, so it's removed from the seccomp sandbox
# Another note: enabling this feature may reduce performance, you may enable
# /proc/sys/net/core/bpf_jit_enable to reduce the impact. see https://man7.org/linux/man-pages/man8/bpfc.8.html
# Recommended value when enabling: "on,obsolete=deny,spawn=deny,resourcecontrol=deny"
seccompsandbox = "@DEFSECCOMPSANDBOXPARAM@"
seccomp_sandbox = "@DEFSECCOMPSANDBOXPARAM@"
# CPU features
# comma-separated list of cpu features to pass to the cpu
@@ -345,18 +339,6 @@ msize_9p = @DEFMSIZE9P@
# Default is false
disable_image_nvdimm = true
# Enable hot-plugging of VFIO devices to a bridge-port,
# root-port or switch-port.
# The default setting is "no-port"
hot_plug_vfio = "no-port"
# In a confidential compute environment hot-plugging can compromise
# security.
# Enable cold-plugging of VFIO devices to a bridge-port,
# root-port or switch-port.
# The default setting is "no-port", which means disabled.
cold_plug_vfio = "no-port"
# VFIO devices are hotplugged on a bridge by default.
# Enable hotplugging on root bus. This may be required for devices with
# a large PCI bar, as this is a current limitation with hotplugging on
@@ -460,9 +442,6 @@ guest_memory_dump_paging = false
# be default_memory.
enable_guest_swap = false
# use legacy serial for guest console if available and implemented for architecture. Default false
use_legacy_serial = false
# disable applying SELinux on the VMM process (default false)
disable_selinux = @DEFDISABLESELINUX@
@@ -474,7 +453,7 @@ disable_selinux = @DEFDISABLESELINUX@
disable_guest_selinux = @DEFDISABLEGUESTSELINUX@
[factory]
[hypervisor.qemu.factory]
# VM templating support. Once enabled, new VMs are created from template
# using vm cloning. They will share the same initial kernel, initramfs and
# agent memory by mapping it readonly. It helps speeding up new container
@@ -593,20 +572,6 @@ agent_name = "@PROJECT_TYPE@"
# (default: true)
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
# 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`,
# so general users should not uncomment and apply it.
# (format: "user:role:type")
# Note: You cannot specify MCS policy with the label because the sensitivity levels and
# categories are determined automatically by high-level container runtimes such as containerd.
# Example value when enabling: "system_u:system_r:container_t"
guest_selinux_label = "@DEFGUESTSELINUXLABEL@"
# If enabled, the runtime will create opentracing.io traces and spans.
# (See https://www.jaegertracing.io/docs/getting-started).
# (default: disabled)

View File

@@ -103,12 +103,6 @@ kernel_params = "@KERNELPARAMS@"
# If you want that qemu uses the default firmware leave this option empty
firmware = "@FIRMWARE_SNP_PATH@"
# Path to the firmware volume.
# firmware TDVF or OVMF can be split into FIRMWARE_VARS.fd (UEFI variables
# as configuration) and FIRMWARE_CODE.fd (UEFI program image). UEFI variables
# can be customized per each user while UEFI code is kept same.
firmware_volume = "@FIRMWARE_VOLUME_SNP_PATH@"
# Machine accelerators
# comma-separated list of machine accelerators to pass to the hypervisor.
# For example, `machine_accelerators = "nosmm,nosmbus,nosata,nopit,static-prt,nofw"`
@@ -116,12 +110,12 @@ machine_accelerators = "@MACHINEACCELERATORS@"
# Qemu seccomp sandbox feature
# comma-separated list of seccomp sandbox features to control the syscall access.
# For example, `seccompsandbox= "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# For example, `seccomp_sandbox = "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# Note: "elevateprivileges=deny" doesn't work with daemonize option, so it's removed from the seccomp sandbox
# Another note: enabling this feature may reduce performance, you may enable
# /proc/sys/net/core/bpf_jit_enable to reduce the impact. see https://man7.org/linux/man-pages/man8/bpfc.8.html
# Recommended value when enabling: "on,obsolete=deny,spawn=deny,resourcecontrol=deny"
seccompsandbox = "@DEFSECCOMPSANDBOXPARAM@"
seccomp_sandbox = "@DEFSECCOMPSANDBOXPARAM@"
# CPU features
# comma-separated list of cpu features to pass to the cpu
@@ -289,10 +283,6 @@ block_device_cache_noflush = false
#
enable_iothreads = @DEFENABLEIOTHREADS@
# Independent IOThreads enables IO to be processed in a separate thread, it is
# for QEMU hotplug device attach to iothread, like virtio-blk.
indep_iothreads = @DEFINDEPIOTHREADS@
# Enable pre allocation of VM RAM, default false
# Enabling this will result in lower container density
# as all of the memory will be allocated and locked
@@ -346,11 +336,6 @@ enable_iommu_platform = false
# Your distribution recommends: @DEFVALIDVHOSTUSERSTOREPATHS@
valid_vhost_user_store_paths = @DEFVALIDVHOSTUSERSTOREPATHS@
# The timeout for reconnecting on non-server spdk sockets when the remote end goes away.
# qemu will delay this many seconds and then attempt to reconnect.
# Zero disables reconnecting, and the default is zero.
vhost_user_reconnect_timeout_sec = 0
# Enable file based guest memory support. The default is an empty string which
# will disable this feature. In the case of virtio-fs, this is enabled
# automatically and '/dev/shm' is used as the backing folder.
@@ -407,7 +392,7 @@ disable_vhost_net = false
#
# If set to the empty string "", no extra monitor socket is added. This is
# the default.
#extra_monitor_socket = "hmp"
#dbg_monitor_socket = "hmp"
#
# Default entropy source.
@@ -495,9 +480,6 @@ guest_memory_dump_paging = false
# be default_memory.
enable_guest_swap = false
# use legacy serial for guest console if available and implemented for architecture. Default false
use_legacy_serial = false
# disable applying SELinux on the VMM process (default false)
disable_selinux = @DEFDISABLESELINUX@
@@ -509,7 +491,7 @@ disable_selinux = @DEFDISABLESELINUX@
disable_guest_selinux = @DEFDISABLEGUESTSELINUX@
[factory]
[hypervisor.qemu.factory]
# VM templating support. Once enabled, new VMs are created from template
# using vm cloning. They will share the same initial kernel, initramfs and
# agent memory by mapping it readonly. It helps speeding up new container
@@ -528,30 +510,6 @@ enable_template = false
# Default "/run/vc/vm/template"
template_path = "/run/vc/vm/template"
# The number of caches of VMCache:
# unspecified or == 0 --> VMCache is disabled
# > 0 --> will be set to the specified number
#
# VMCache is a function that creates VMs as caches before using it.
# It helps speed up new container creation.
# The function consists of a server and some clients communicating
# through Unix socket. The protocol is gRPC in protocols/cache/cache.proto.
# The VMCache server will create some VMs and cache them by factory cache.
# It will convert the VM to gRPC format and transport it when gets
# requestion from clients.
# Factory grpccache is the VMCache client. It will request gRPC format
# VM and convert it back to a VM. If VMCache function is enabled,
# kata-runtime will request VM from factory grpccache when it creates
# a new sandbox.
#
# Default 0
vm_cache_number = 0
# Specify the address of the Unix socket that is used by VMCache.
#
# Default /var/run/kata-containers/cache.sock
vm_cache_endpoint = "/var/run/kata-containers/cache.sock"
[agent.@PROJECT_TYPE@]
# If enabled, make the agent display debug-level messages.
# (default: disabled)
@@ -651,19 +609,6 @@ agent_name="@PROJECT_TYPE@"
# (default: true)
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
# 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`,
# so general users should not uncomment and apply it.
# (format: "user:role:type")
# Note: You cannot specify MCS policy with the label because the sensitivity levels and
# categories are determined automatically by high-level container runtimes such as containerd.
guest_selinux_label = "@DEFGUESTSELINUXLABEL@"
# If enabled, the runtime will create opentracing.io traces and spans.
# (See https://www.jaegertracing.io/docs/getting-started).
# (default: disabled)
@@ -757,22 +702,3 @@ enable_pprof = false
# to the hypervisor.
# (default: /run/kata-containers/dans)
dan_conf = "@DEFDANCONF@"
# pod_resource_api_sock specifies the unix socket for the Kubelet's
# PodResource API endpoint. If empty, kubernetes based cold plug
# will not be attempted. In order for this feature to work, the
# KubeletPodResourcesGet featureGate must be enabled in Kubelet,
# if using Kubelet older than 1.34.
#
# The pod resource API's socket is relative to the Kubelet's root-dir,
# which is defined by the cluster admin, and its location is:
# ${KubeletRootDir}/pod-resources/kubelet.sock
#
# cold_plug_vfio(see hypervisor config) acts as a feature gate:
# cold_plug_vfio = no_port (default) => no cold plug
# cold_plug_vfio != no_port AND pod_resource_api_sock = "" => need
# explicit CDI annotation for cold plug (applies mainly
# to non-k8s cases)
# cold_plug_vfio != no_port AND pod_resource_api_sock != "" => kubelet
# based cold plug.
pod_resource_api_sock = "@DEFPODRESOURCEAPISOCK@"

View File

@@ -83,12 +83,6 @@ kernel_verity_params = "@KERNELVERITYPARAMS@"
# If you want that qemu uses the default firmware leave this option empty
firmware = "@FIRMWARETDVFPATH@"
# Path to the firmware volume.
# firmware TDVF or OVMF can be split into FIRMWARE_VARS.fd (UEFI variables
# as configuration) and FIRMWARE_CODE.fd (UEFI program image). UEFI variables
# can be customized per each user while UEFI code is kept same.
firmware_volume = "@FIRMWAREVOLUMEPATH@"
# Machine accelerators
# comma-separated list of machine accelerators to pass to the hypervisor.
# For example, `machine_accelerators = "nosmm,nosmbus,nosata,nopit,static-prt,nofw"`
@@ -96,12 +90,12 @@ machine_accelerators = "@MACHINEACCELERATORS@"
# Qemu seccomp sandbox feature
# comma-separated list of seccomp sandbox features to control the syscall access.
# For example, `seccompsandbox= "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# For example, `seccomp_sandbox = "on,obsolete=deny,spawn=deny,resourcecontrol=deny"`
# Note: "elevateprivileges=deny" doesn't work with daemonize option, so it's removed from the seccomp sandbox
# Another note: enabling this feature may reduce performance, you may enable
# /proc/sys/net/core/bpf_jit_enable to reduce the impact. see https://man7.org/linux/man-pages/man8/bpfc.8.html
# Recommended value when enabling: "on,obsolete=deny,spawn=deny,resourcecontrol=deny"
seccompsandbox = "@DEFSECCOMPSANDBOXPARAM@"
seccomp_sandbox = "@DEFSECCOMPSANDBOXPARAM@"
# CPU features
# comma-separated list of cpu features to pass to the cpu
@@ -268,10 +262,6 @@ block_device_cache_noflush = false
#
enable_iothreads = @DEFENABLEIOTHREADS@
# Independent IOThreads enables IO to be processed in a separate thread, it is
# for QEMU hotplug device attach to iothread, like virtio-blk.
indep_iothreads = @DEFINDEPIOTHREADS@
# Enable pre allocation of VM RAM, default false
# Enabling this will result in lower container density
# as all of the memory will be allocated and locked
@@ -325,11 +315,6 @@ enable_iommu_platform = false
# Your distribution recommends: @DEFVALIDVHOSTUSERSTOREPATHS@
valid_vhost_user_store_paths = @DEFVALIDVHOSTUSERSTOREPATHS@
# The timeout for reconnecting on non-server spdk sockets when the remote end goes away.
# qemu will delay this many seconds and then attempt to reconnect.
# Zero disables reconnecting, and the default is zero.
vhost_user_reconnect_timeout_sec = 0
# Enable file based guest memory support. The default is an empty string which
# will disable this feature. In the case of virtio-fs, this is enabled
# automatically and '/dev/shm' is used as the backing folder.
@@ -364,7 +349,7 @@ enable_debug = false
#
# If set to the empty string "", no extra monitor socket is added. This is
# the default.
extra_monitor_socket = ""
dbg_monitor_socket = ""
# Disable the customizations done in the runtime when it detects
# that it is running on top a VMM. This will result in the runtime
@@ -474,9 +459,6 @@ guest_memory_dump_paging = false
# be default_memory.
enable_guest_swap = false
# use legacy serial for guest console if available and implemented for architecture. Default false
use_legacy_serial = false
# disable applying SELinux on the VMM process (default false)
disable_selinux = @DEFDISABLESELINUX@
@@ -488,7 +470,7 @@ disable_selinux = @DEFDISABLESELINUX@
disable_guest_selinux = @DEFDISABLEGUESTSELINUX@
[factory]
[hypervisor.qemu.factory]
# VM templating support. Once enabled, new VMs are created from template
# using vm cloning. They will share the same initial kernel, initramfs and
# agent memory by mapping it readonly. It helps speeding up new container
@@ -507,30 +489,6 @@ enable_template = false
# Default "/run/vc/vm/template"
template_path = "/run/vc/vm/template"
# The number of caches of VMCache:
# unspecified or == 0 --> VMCache is disabled
# > 0 --> will be set to the specified number
#
# VMCache is a function that creates VMs as caches before using it.
# It helps speed up new container creation.
# The function consists of a server and some clients communicating
# through Unix socket. The protocol is gRPC in protocols/cache/cache.proto.
# The VMCache server will create some VMs and cache them by factory cache.
# It will convert the VM to gRPC format and transport it when gets
# requestion from clients.
# Factory grpccache is the VMCache client. It will request gRPC format
# VM and convert it back to a VM. If VMCache function is enabled,
# kata-runtime will request VM from factory grpccache when it creates
# a new sandbox.
#
# Default 0
vm_cache_number = 0
# Specify the address of the Unix socket that is used by VMCache.
#
# Default /var/run/kata-containers/cache.sock
vm_cache_endpoint = "/var/run/kata-containers/cache.sock"
[agent.@PROJECT_TYPE@]
# If enabled, make the agent display debug-level messages.
# (default: disabled)
@@ -631,20 +589,6 @@ agent_name="@PROJECT_TYPE@"
# (default: true)
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
# 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`,
# so general users should not uncomment and apply it.
# (format: "user:role:type")
# Note: You cannot specify MCS policy with the label because the sensitivity levels and
# categories are determined automatically by high-level container runtimes such as containerd.
# Example value when enabling: "system_u:system_r:container_t"
guest_selinux_label = "@DEFGUESTSELINUXLABEL@"
# If enabled, the runtime will create opentracing.io traces and spans.
# (See https://www.jaegertracing.io/docs/getting-started).
# (default: disabled)
@@ -739,21 +683,3 @@ enable_pprof = false
# (default: /run/kata-containers/dans)
dan_conf = "@DEFDANCONF@"
# pod_resource_api_sock specifies the unix socket for the Kubelet's
# PodResource API endpoint. If empty, kubernetes based cold plug
# will not be attempted. In order for this feature to work, the
# KubeletPodResourcesGet featureGate must be enabled in Kubelet,
# if using Kubelet older than 1.34.
#
# The pod resource API's socket is relative to the Kubelet's root-dir,
# which is defined by the cluster admin, and its location is:
# ${KubeletRootDir}/pod-resources/kubelet.sock
#
# cold_plug_vfio(see hypervisor config) acts as a feature gate:
# cold_plug_vfio = no_port (default) => no cold plug
# cold_plug_vfio != no_port AND pod_resource_api_sock = "" => need
# explicit CDI annotation for cold plug (applies mainly
# to non-k8s cases)
# cold_plug_vfio != no_port AND pod_resource_api_sock != "" => kubelet
# based cold plug.
pod_resource_api_sock = "@DEFPODRESOURCEAPISOCK@"

View File

@@ -205,15 +205,6 @@ agent_name = "kata"
disable_guest_seccomp = true
# 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`,
# so general users should not uncomment and apply it.
# (format: "user:role:type")
# Note: You cannot specify MCS policy with the label because the sensitivity levels and
# categories are determined automatically by high-level container runtimes such as containerd.
# Example value when enabling: "system_u:system_r:container_t"
guest_selinux_label = "@DEFGUESTSELINUXLABEL@"
# If enabled, the runtime will create opentracing.io traces and spans.
# (See https://www.jaegertracing.io/docs/getting-started).
# (default: disabled)

View File

@@ -2610,6 +2610,7 @@ impl<'a> QemuCmdLine<'a> {
self.devices.push(Box::new(Bios::new(firmware.to_owned())));
self.machine
.set_kernel_irqchip("split")
.set_confidential_guest_support("tdx")
.set_nvdimm(false);
}

View File

@@ -858,7 +858,12 @@ impl QemuInner {
block_device.config.index,
&block_device.config.path_on_host,
&block_device.config.blkdev_aio.to_string(),
block_device.config.is_direct,
Some(
block_device
.config
.is_direct
.unwrap_or(self.config.blockdev_info.block_device_cache_direct),
),
block_device.config.is_readonly,
block_device.config.no_drop,
)

View File

@@ -165,6 +165,6 @@ pub fn new(id: &str, config: &SharedFsInfo) -> Result<Arc<dyn ShareFs>> {
VIRTIO_FS => Ok(Arc::new(
ShareVirtioFsStandalone::new(id, config).context("new standalone virtio fs")?,
)),
_ => Err(anyhow!("unsupported shred fs {:?}", &shared_fs)),
_ => Err(anyhow!("unsupported shared fs {:?}", &shared_fs)),
}
}

View File

@@ -143,7 +143,13 @@ DEFROOTFSTYPE := $(ROOTFSTYPE_EXT4)
FIRMWAREPATH :=
FIRMWAREVOLUMEPATH :=
FIRMWAREPATH_NV = $(FIRMWAREPATH)
FIRMWAREPATH_NV :=
ifeq ($(ARCH),amd64)
FIRMWAREPATH_NV := $(PREFIXDEPS)/share/$(EDK2_NAME)/OVMF.fd
endif
ifeq ($(ARCH),arm64)
FIRMWAREPATH_NV := $(PREFIXDEPS)/share/$(EDK2_NAME)/AAVMF_CODE.fd
endif
FIRMWARETDVFPATH := $(PREFIXDEPS)/share/ovmf/OVMF.inteltdx.fd
FIRMWARETDVFPATH_NV := $(FIRMWARETDVFPATH)

View File

@@ -9,9 +9,9 @@ import (
"context"
"fmt"
"github.com/containerd/containerd/api/types/task"
"github.com/sirupsen/logrus"
"github.com/containerd/containerd/api/types/task"
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
)
@@ -46,6 +46,19 @@ func startContainer(ctx context.Context, s *service, c *container) (retErr error
}
go watchSandbox(ctx, s)
// If no network endpoints were discovered during sandbox creation,
// schedule an async rescan. This handles runtimes that configure
// networking after task creation (e.g. Docker 26+ configures
// networking after the Start response, and prestart hooks may
// not have run yet on slower architectures).
// RescanNetwork is idempotent — it returns immediately if
// endpoints already exist.
go func() {
if err := s.sandbox.RescanNetwork(s.ctx); err != nil {
shimLog.WithError(err).Error("async network rescan failed — container may lack networking")
}
}()
// We use s.ctx(`ctx` derived from `s.ctx`) to check for cancellation of the
// shim context and the context passed to startContainer for tracing.
go watchOOMEvents(ctx, s)

View File

@@ -19,6 +19,7 @@ import (
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
vf "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/factory"
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
@@ -140,6 +141,17 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeCo
sandboxConfig.Containers[0].RootFs = rootFs
}
// Docker 26+ may set up networking before task creation instead of using
// prestart hooks. The netns path is not in the OCI spec but can be
// discovered from Docker's libnetwork hook args which contain the sandbox
// ID that maps to /var/run/docker/netns/<sandbox_id>.
if sandboxConfig.NetworkConfig.NetworkID == "" && !sandboxConfig.NetworkConfig.DisableNewNetwork {
if dockerNetns := utils.DockerNetnsPath(&ociSpec); dockerNetns != "" {
sandboxConfig.NetworkConfig.NetworkID = dockerNetns
kataUtilsLogger.WithField("netns", dockerNetns).Info("discovered Docker network namespace from hook args")
}
}
// Important to create the network namespace before the sandbox is
// created, because it is not responsible for the creation of the
// netns if it does not exist.

View File

@@ -20,7 +20,9 @@ import (
"golang.org/x/sys/unix"
)
const procMountInfoFile = "/proc/self/mountinfo"
const (
procMountInfoFile = "/proc/self/mountinfo"
)
// EnterNetNS is free from any call to a go routine, and it calls
// into runtime.LockOSThread(), meaning it won't be executed in a
@@ -29,27 +31,30 @@ func EnterNetNS(networkID string, cb func() error) error {
return vc.EnterNetNS(networkID, cb)
}
// SetupNetworkNamespace create a network namespace
// SetupNetworkNamespace creates a network namespace if one is not already
// provided via NetworkID. When NetworkID is empty and networking is not
// disabled, a new namespace is created as a placeholder; the actual
// hypervisor namespace will be discovered later by addAllEndpoints after
// the VM has started.
func SetupNetworkNamespace(config *vc.NetworkConfig) error {
if config.DisableNewNetwork {
kataUtilsLogger.Info("DisableNewNetNs is on, shim and hypervisor are running in the host netns")
return nil
}
var err error
var n ns.NetNS
if config.NetworkID == "" {
var (
err error
n ns.NetNS
)
if rootless.IsRootless() {
n, err = rootless.NewNS()
if err != nil {
return err
}
} else {
n, err = testutils.NewNS()
if err != nil {
return err
}
}
if err != nil {
return err
}
config.NetworkID = n.Path()
@@ -71,11 +76,23 @@ func SetupNetworkNamespace(config *vc.NetworkConfig) error {
}
const (
netNsMountType = "nsfs"
mountTypeFieldIdx = 8
mountDestIdx = 4
netNsMountType = "nsfs"
mountDestIdx = 4
)
// mountinfoFsType finds the filesystem type in a parsed mountinfo line.
// The mountinfo format has optional tagged fields (shared:, master:, etc.)
// between field 7 and a "-" separator. The fs type is the field immediately
// after "-". Returns "" if the separator is not found.
func mountinfoFsType(fields []string) string {
for i, f := range fields {
if f == "-" && i+1 < len(fields) {
return fields[i+1]
}
}
return ""
}
// getNetNsFromBindMount returns the network namespace for the bind-mounted path
func getNetNsFromBindMount(nsPath string, procMountFile string) (string, error) {
// Resolve all symlinks in the path as the mountinfo file contains
@@ -100,16 +117,15 @@ func getNetNsFromBindMount(nsPath string, procMountFile string) (string, error)
// "711 26 0:3 net:[4026532009] /run/docker/netns/default rw shared:535 - nsfs nsfs rw"
//
// Reference: https://www.kernel.org/doc/Documentation/filesystems/proc.txt
// We are interested in the first 9 fields of this file,
// to check for the correct mount type.
// The "-" separator has a variable position due to optional tagged
// fields, so we locate the fs type dynamically.
fields := strings.Split(text, " ")
if len(fields) < 9 {
continue
}
// We check here if the mount type is a network namespace mount type, namely "nsfs"
if fields[mountTypeFieldIdx] != netNsMountType {
if mountinfoFsType(fields) != netNsMountType {
continue
}

View File

@@ -149,3 +149,23 @@ func TestSetupNetworkNamespace(t *testing.T) {
err = SetupNetworkNamespace(config)
assert.NoError(err)
}
func TestMountinfoFsType(t *testing.T) {
assert := assert.New(t)
// Standard mountinfo line with optional tagged fields
fields := []string{"711", "26", "0:3", "net:[4026532009]", "/run/docker/netns/default", "rw", "shared:535", "-", "nsfs", "nsfs", "rw"}
assert.Equal("nsfs", mountinfoFsType(fields))
// Multiple optional tags before separator
fields = []string{"711", "26", "0:3", "net:[4026532009]", "/run/docker/netns/default", "rw", "shared:535", "master:1", "-", "nsfs", "nsfs", "rw"}
assert.Equal("nsfs", mountinfoFsType(fields))
// No separator
fields = []string{"711", "26", "0:3", "net:[4026532009]", "/run/docker/netns/default", "rw"}
assert.Equal("", mountinfoFsType(fields))
// Separator at end (malformed)
fields = []string{"711", "26", "-"}
assert.Equal("", mountinfoFsType(fields))
}

View File

@@ -72,6 +72,8 @@ type VCSandbox interface {
GetOOMEvent(ctx context.Context) (string, error)
GetHypervisorPid() (int, error)
// RescanNetwork re-scans the network namespace for late-discovered endpoints.
RescanNetwork(ctx context.Context) error
UpdateRuntimeMetrics() error
GetAgentMetrics(ctx context.Context) (string, error)

View File

@@ -17,9 +17,11 @@ import (
"runtime"
"sort"
"strconv"
"strings"
"time"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
otelTrace "go.opentelemetry.io/otel/trace"
@@ -45,6 +47,11 @@ type LinuxNetwork struct {
interworkingModel NetInterworkingModel
netNSCreated bool
danConfigPath string
// placeholderNetNS holds the path to a placeholder network namespace
// that we created but later abandoned in favour of the hypervisor's
// netns. If best-effort deletion in addAllEndpoints fails, teardown
// retries the cleanup via RemoveEndpoints.
placeholderNetNS string
}
// NewNetwork creates a new Linux Network from a NetworkConfig.
@@ -68,11 +75,11 @@ func NewNetwork(configs ...*NetworkConfig) (Network, error) {
}
return &LinuxNetwork{
config.NetworkID,
[]Endpoint{},
config.InterworkingModel,
config.NetworkCreated,
config.DanConfigPath,
netNSPath: config.NetworkID,
eps: []Endpoint{},
interworkingModel: config.InterworkingModel,
netNSCreated: config.NetworkCreated,
danConfigPath: config.DanConfigPath,
}, nil
}
@@ -325,28 +332,91 @@ func (n *LinuxNetwork) GetEndpointsNum() (int, error) {
// Scan the networking namespace through netlink and then:
// 1. Create the endpoints for the relevant interfaces found there.
// 2. Attach them to the VM.
//
// If no usable interfaces are found and the hypervisor is running in a
// different network namespace (e.g. Docker 26+ places QEMU in its own
// pre-configured namespace), switch to the hypervisor's namespace and
// rescan there. This handles the case where the OCI spec does not
// communicate the network namespace path.
func (n *LinuxNetwork) addAllEndpoints(ctx context.Context, s *Sandbox, hotplug bool) error {
netnsHandle, err := netns.GetFromPath(n.netNSPath)
endpoints, err := n.scanEndpointsInNs(ctx, s, n.netNSPath, hotplug)
if err != nil {
return err
}
// If the scan found no usable endpoints, check whether the
// hypervisor is running in a different namespace and retry there.
if len(endpoints) == 0 && s != nil {
if hypervisorNs, ok := n.detectHypervisorNetns(s); ok {
networkLogger().WithFields(logrus.Fields{
"original_netns": n.netNSPath,
"hypervisor_netns": hypervisorNs,
}).Debug("no endpoints in original netns, switching to hypervisor netns")
origPath := n.netNSPath
origCreated := n.netNSCreated
n.netNSPath = hypervisorNs
_, err = n.scanEndpointsInNs(ctx, s, n.netNSPath, hotplug)
if err != nil {
n.netNSPath = origPath
n.netNSCreated = origCreated
return err
}
// Clean up the placeholder namespace we created — we're now
// using the hypervisor's namespace and the placeholder is empty.
// Only clear netNSCreated once deletion succeeds; on failure,
// stash the path so RemoveEndpoints can retry during teardown.
if origCreated {
if delErr := deleteNetNS(origPath); delErr != nil {
networkLogger().WithField("netns", origPath).WithError(delErr).Warn("failed to delete placeholder netns, will retry during teardown")
n.placeholderNetNS = origPath
}
}
// The hypervisor's namespace was not created by us.
n.netNSCreated = false
}
}
sort.Slice(n.eps, func(i, j int) bool {
return n.eps[i].Name() < n.eps[j].Name()
})
networkLogger().WithField("endpoints", n.eps).Info("endpoints found after scan")
return nil
}
// scanEndpointsInNs scans a network namespace for usable (non-loopback,
// configured) interfaces and adds them as endpoints. Returns the list of
// newly added endpoints.
func (n *LinuxNetwork) scanEndpointsInNs(ctx context.Context, s *Sandbox, nsPath string, hotplug bool) ([]Endpoint, error) {
netnsHandle, err := netns.GetFromPath(nsPath)
if err != nil {
return nil, err
}
defer netnsHandle.Close()
netlinkHandle, err := netlink.NewHandleAt(netnsHandle)
if err != nil {
return err
return nil, err
}
defer netlinkHandle.Close()
linkList, err := netlinkHandle.LinkList()
if err != nil {
return err
return nil, err
}
epsBefore := len(n.eps)
var added []Endpoint
for _, link := range linkList {
netInfo, err := networkInfoFromLink(netlinkHandle, link)
if err != nil {
return err
// No rollback needed — no endpoints were added in this iteration yet.
return nil, err
}
// Ignore unconfigured network interfaces. These are
@@ -368,22 +438,62 @@ func (n *LinuxNetwork) addAllEndpoints(ctx context.Context, s *Sandbox, hotplug
continue
}
if err := doNetNS(n.netNSPath, func(_ ns.NetNS) error {
_, err = n.addSingleEndpoint(ctx, s, netInfo, hotplug)
return err
if err := doNetNS(nsPath, func(_ ns.NetNS) error {
ep, addErr := n.addSingleEndpoint(ctx, s, netInfo, hotplug)
if addErr == nil {
added = append(added, ep)
}
return addErr
}); err != nil {
return err
// Rollback: remove any endpoints added during this scan
// so that a failed scan does not leave partial side effects.
n.eps = n.eps[:epsBefore]
return nil, err
}
}
sort.Slice(n.eps, func(i, j int) bool {
return n.eps[i].Name() < n.eps[j].Name()
})
return added, nil
}
networkLogger().WithField("endpoints", n.eps).Info("endpoints found after scan")
// detectHypervisorNetns checks whether the hypervisor process is running in a
// network namespace different from the one we are currently tracking. If so it
// returns the procfs path to the hypervisor's netns and true.
func (n *LinuxNetwork) detectHypervisorNetns(s *Sandbox) (string, bool) {
pid, err := s.GetHypervisorPid()
if err != nil || pid <= 0 {
return "", false
}
return nil
// Guard against PID recycling: verify the process belongs to this
// sandbox by checking its command line for the sandbox ID. QEMU is
// started with -name sandbox-<id>, so the ID will appear in cmdline.
// /proc/pid/cmdline uses null bytes as argument separators; replace
// them so the substring search works on the joined argument string.
cmdlineRaw, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
if err != nil {
return "", false
}
cmdline := strings.ReplaceAll(string(cmdlineRaw), "\x00", " ")
if !strings.Contains(cmdline, s.id) {
return "", false
}
hypervisorNs := fmt.Sprintf("/proc/%d/ns/net", pid)
// Compare device and inode numbers. Inode numbers are only unique
// within a device, so both must match to confirm the same namespace.
var currentStat, hvStat unix.Stat_t
if err := unix.Stat(n.netNSPath, &currentStat); err != nil {
return "", false
}
if err := unix.Stat(hypervisorNs, &hvStat); err != nil {
return "", false
}
if currentStat.Dev != hvStat.Dev || currentStat.Ino != hvStat.Ino {
return hypervisorNs, true
}
return "", false
}
func convertDanDeviceToNetworkInfo(device *vctypes.DanDevice) (*NetworkInfo, error) {
@@ -571,6 +681,17 @@ func (n *LinuxNetwork) RemoveEndpoints(ctx context.Context, s *Sandbox, endpoint
return deleteNetNS(n.netNSPath)
}
// Retry cleanup of a placeholder namespace whose earlier deletion
// failed in addAllEndpoints.
if n.placeholderNetNS != "" && endpoints == nil {
if delErr := deleteNetNS(n.placeholderNetNS); delErr != nil {
networkLogger().WithField("netns", n.placeholderNetNS).WithError(delErr).Warn("failed to delete placeholder netns during teardown")
} else {
networkLogger().WithField("netns", n.placeholderNetNS).Info("placeholder network namespace deleted")
n.placeholderNetNS = ""
}
}
return nil
}

View File

@@ -363,11 +363,11 @@ func TestConvertDanDeviceToNetworkInfo(t *testing.T) {
func TestAddEndpoints_Dan(t *testing.T) {
network := &LinuxNetwork{
"net-123",
[]Endpoint{},
NetXConnectDefaultModel,
true,
"testdata/dan-config.json",
netNSPath: "net-123",
eps: []Endpoint{},
interworkingModel: NetXConnectDefaultModel,
netNSCreated: true,
danConfigPath: "testdata/dan-config.json",
}
ctx := context.TODO()

View File

@@ -255,6 +255,10 @@ func (s *Sandbox) GetHypervisorPid() (int, error) {
return 0, nil
}
func (s *Sandbox) RescanNetwork(ctx context.Context) error {
return nil
}
func (s *Sandbox) GuestVolumeStats(ctx context.Context, path string) ([]byte, error) {
return nil, nil
}

View File

@@ -20,6 +20,7 @@ import (
"strings"
"sync"
"syscall"
"time"
v1 "github.com/containerd/cgroups/stats/v1"
v2 "github.com/containerd/cgroups/v2/stats"
@@ -330,6 +331,81 @@ func (s *Sandbox) GetHypervisorPid() (int, error) {
return pids[0], nil
}
// RescanNetwork re-scans the network namespace for endpoints if none have
// been discovered yet. This is idempotent: if endpoints already exist it
// returns immediately. It enables Docker 26+ support where networking is
// configured after task creation but before Start.
//
// Docker 26+ configures networking (veth pair, IP addresses) between
// Create and Start. The interfaces may not be present immediately, so
// this method polls until they appear or a timeout is reached.
//
// When new endpoints are found, the guest agent is informed about the
// interfaces and routes so that networking becomes functional inside the VM.
func (s *Sandbox) RescanNetwork(ctx context.Context) error {
if s.config.NetworkConfig.DisableNewNetwork {
return nil
}
if len(s.network.Endpoints()) > 0 {
return nil
}
const maxWait = 5 * time.Second
const pollInterval = 50 * time.Millisecond
deadline := time.NewTimer(maxWait)
defer deadline.Stop()
ticker := time.NewTicker(pollInterval)
defer ticker.Stop()
s.Logger().Debug("waiting for network interfaces in namespace")
for {
if _, err := s.network.AddEndpoints(ctx, s, nil, true); err != nil {
return err
}
if len(s.network.Endpoints()) > 0 {
return s.configureGuestNetwork(ctx)
}
select {
case <-ctx.Done():
return ctx.Err()
case <-deadline.C:
s.Logger().Warn("no network interfaces found after timeout — networking may be configured by prestart hooks")
return nil
case <-ticker.C:
}
}
}
// configureGuestNetwork informs the guest agent about discovered network
// endpoints so that interfaces and routes become functional inside the VM.
func (s *Sandbox) configureGuestNetwork(ctx context.Context) error {
endpoints := s.network.Endpoints()
s.Logger().WithField("endpoints", len(endpoints)).Info("configuring hotplugged network in guest")
// Note: ARP neighbors (3rd return value) are not propagated here
// because the agent interface only exposes per-entry updates. The
// full setupNetworks path in kataAgent handles them; this path is
// only reached for late-discovered endpoints where neighbor entries
// are populated dynamically by the kernel.
interfaces, routes, _, err := generateVCNetworkStructures(ctx, endpoints)
if err != nil {
return fmt.Errorf("generating network structures: %w", err)
}
for _, ifc := range interfaces {
if _, err := s.agent.updateInterface(ctx, ifc); err != nil {
return fmt.Errorf("updating interface %s in guest: %w", ifc.Name, err)
}
}
if len(routes) > 0 {
if _, err := s.agent.updateRoutes(ctx, routes); err != nil {
return fmt.Errorf("updating routes in guest: %w", err)
}
}
return nil
}
// GetAllContainers returns all containers.
func (s *Sandbox) GetAllContainers() []VCContainer {
ifa := make([]VCContainer, len(s.containers))

View File

@@ -12,6 +12,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"syscall"
"time"
@@ -493,17 +494,38 @@ func RevertBytes(num uint64) uint64 {
return 1024*RevertBytes(a) + b
}
// dockerLibnetworkSetkey is the hook argument that identifies Docker's
// network configuration hook. The argument following it is the sandbox ID.
const dockerLibnetworkSetkey = "libnetwork-setkey"
// dockerNetnsPrefixes are the well-known filesystem paths where the Docker
// daemon bind-mounts container network namespaces.
var dockerNetnsPrefixes = []string{"/var/run/docker/netns/", "/run/docker/netns/"}
// validSandboxID matches Docker sandbox IDs: exactly 64 lowercase hex characters.
var validSandboxID = regexp.MustCompile(`^[0-9a-f]{64}$`)
// IsDockerContainer returns if the container is managed by docker
// This is done by checking the prestart hook for `libnetwork` arguments.
// This is done by checking the prestart and createRuntime hooks for
// `libnetwork` arguments. Docker 26+ may use CreateRuntime hooks
// instead of the deprecated Prestart hooks.
func IsDockerContainer(spec *specs.Spec) bool {
if spec == nil || spec.Hooks == nil {
return false
}
for _, hook := range spec.Hooks.Prestart { //nolint:all
for _, arg := range hook.Args {
if strings.HasPrefix(arg, "libnetwork") {
return true
// Check both Prestart (Docker < 26) and CreateRuntime (Docker >= 26) hooks.
hookSets := [][]specs.Hook{
spec.Hooks.Prestart, //nolint:all
spec.Hooks.CreateRuntime,
}
for _, hooks := range hookSets {
for _, hook := range hooks {
for _, arg := range hook.Args {
if strings.HasPrefix(arg, "libnetwork") {
return true
}
}
}
}
@@ -511,6 +533,50 @@ func IsDockerContainer(spec *specs.Spec) bool {
return false
}
// DockerNetnsPath attempts to discover Docker's pre-created network namespace
// path from OCI spec hooks. Docker's libnetwork-setkey hook contains the
// sandbox ID as its second argument, which maps to the netns file under
// /var/run/docker/netns/<sandbox_id>.
func DockerNetnsPath(spec *specs.Spec) string {
if spec == nil || spec.Hooks == nil {
return ""
}
// Search both Prestart and CreateRuntime hooks for libnetwork-setkey.
hookSets := [][]specs.Hook{
spec.Hooks.Prestart, //nolint:all
spec.Hooks.CreateRuntime,
}
for _, hooks := range hookSets {
for _, hook := range hooks {
for i, arg := range hook.Args {
if arg == dockerLibnetworkSetkey && i+1 < len(hook.Args) {
sandboxID := hook.Args[i+1]
// Docker sandbox IDs are exactly 64 lowercase hex
// characters. Reject anything else to prevent path
// traversal and unexpected input.
if !validSandboxID.MatchString(sandboxID) {
continue
}
// Docker stores netns under well-known paths.
// Use Lstat to reject symlinks (which could point
// outside the Docker netns directory) and non-regular
// files such as directories.
for _, prefix := range dockerNetnsPrefixes {
nsPath := prefix + sandboxID
if fi, err := os.Lstat(nsPath); err == nil && fi.Mode().IsRegular() {
return nsPath
}
}
}
}
}
}
return ""
}
// GetGuestNUMANodes constructs guest NUMA nodes mapping to host NUMA nodes and host CPUs.
func GetGuestNUMANodes(numaMapping []string) ([]types.GuestNUMANode, error) {
// Add guest NUMA node for each specified subsets of host NUMA nodes.

View File

@@ -579,24 +579,178 @@ func TestRevertBytes(t *testing.T) {
assert.Equal(expectedNum, num)
}
// TestIsDockerContainer validates hook-detection logic in isolation.
// End-to-end Docker→containerd→kata integration is covered by
// external tests (see tests/integration/kubernetes/).
func TestIsDockerContainer(t *testing.T) {
assert := assert.New(t)
// nil spec
assert.False(IsDockerContainer(nil))
// nil hooks
assert.False(IsDockerContainer(&specs.Spec{}))
// Unrelated prestart hook
ociSpec := &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{
{
Args: []string{
"haha",
},
},
Prestart: []specs.Hook{ //nolint:all
{Args: []string{"haha"}},
},
},
}
assert.False(IsDockerContainer(ociSpec))
// Prestart hook with libnetwork (Docker < 26)
ociSpec.Hooks.Prestart = append(ociSpec.Hooks.Prestart, specs.Hook{ //nolint:all
Args: []string{"libnetwork-xxx"},
})
assert.True(IsDockerContainer(ociSpec))
// CreateRuntime hook with libnetwork (Docker >= 26)
ociSpec2 := &specs.Spec{
Hooks: &specs.Hooks{
CreateRuntime: []specs.Hook{
{Args: []string{"/usr/bin/docker-proxy", "libnetwork-setkey", "abc123", "ctrl"}},
},
},
}
assert.True(IsDockerContainer(ociSpec2))
// CreateRuntime hook without libnetwork
ociSpec3 := &specs.Spec{
Hooks: &specs.Hooks{
CreateRuntime: []specs.Hook{
{Args: []string{"/some/other/hook"}},
},
},
}
assert.False(IsDockerContainer(ociSpec3))
}
// TestDockerNetnsPath validates netns path discovery from OCI hook args.
// This does not test the actual namespace opening or endpoint scanning;
// see integration tests for full-path coverage.
func TestDockerNetnsPath(t *testing.T) {
assert := assert.New(t)
// Valid 64-char hex sandbox IDs for test cases.
validID := strings.Repeat("ab", 32) // 64 hex chars
validID2 := strings.Repeat("cd", 32) // another 64 hex chars
invalidShortID := "abc123" // too short
invalidUpperID := strings.Repeat("AB", 32) // uppercase rejected
// nil spec
assert.Equal("", DockerNetnsPath(nil))
// nil hooks
assert.Equal("", DockerNetnsPath(&specs.Spec{}))
// Hook without libnetwork-setkey
spec := &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{ //nolint:all
{Args: []string{"/some/binary", "unrelated"}},
},
},
}
assert.Equal("", DockerNetnsPath(spec))
// Prestart hook with libnetwork-setkey but sandbox ID too short (rejected by regex)
spec = &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{ //nolint:all
{Args: []string{"/usr/bin/proxy", "libnetwork-setkey", invalidShortID, "ctrl"}},
},
},
}
assert.Equal("", DockerNetnsPath(spec))
// Prestart hook with libnetwork-setkey but uppercase hex (rejected by regex)
spec = &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{ //nolint:all
{Args: []string{"/usr/bin/proxy", "libnetwork-setkey", invalidUpperID, "ctrl"}},
},
},
}
assert.Equal("", DockerNetnsPath(spec))
// Prestart hook with valid sandbox ID but netns file doesn't exist on disk
spec = &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{ //nolint:all
{Args: []string{"/usr/bin/proxy", "libnetwork-setkey", validID, "ctrl"}},
},
},
}
assert.Equal("", DockerNetnsPath(spec))
// Prestart hook with libnetwork-setkey and existing netns file — success path
tmpDir := t.TempDir()
fakeNsDir := filepath.Join(tmpDir, "netns")
err := os.MkdirAll(fakeNsDir, 0755)
assert.NoError(err)
fakeNsFile := filepath.Join(fakeNsDir, validID)
err = os.WriteFile(fakeNsFile, []byte{}, 0644)
assert.NoError(err)
// Temporarily override dockerNetnsPrefixes so DockerNetnsPath can find
// the netns file we created under the temp directory.
origPrefixes := dockerNetnsPrefixes
dockerNetnsPrefixes = []string{fakeNsDir + "/"}
defer func() { dockerNetnsPrefixes = origPrefixes }()
spec = &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{ //nolint:all
{Args: []string{"/usr/bin/proxy", "libnetwork-setkey", validID, "ctrl"}},
},
},
}
assert.Equal(fakeNsFile, DockerNetnsPath(spec))
// Sandbox ID that is a directory rather than a regular file — must be rejected
dirID := validID2
err = os.MkdirAll(filepath.Join(fakeNsDir, dirID), 0755)
assert.NoError(err)
spec = &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{ //nolint:all
{Args: []string{"/usr/bin/proxy", "libnetwork-setkey", dirID, "ctrl"}},
},
},
}
assert.Equal("", DockerNetnsPath(spec))
// CreateRuntime hook with valid sandbox ID — file doesn't exist
validID3 := strings.Repeat("ef", 32)
spec = &specs.Spec{
Hooks: &specs.Hooks{
CreateRuntime: []specs.Hook{
{Args: []string{"/usr/bin/proxy", "libnetwork-setkey", validID3, "ctrl"}},
},
},
}
assert.Equal("", DockerNetnsPath(spec))
// Hook with libnetwork-setkey as last arg (no sandbox ID follows) — no panic
spec = &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{ //nolint:all
{Args: []string{"libnetwork-setkey"}},
},
},
}
assert.Equal("", DockerNetnsPath(spec))
// Empty args slice
spec = &specs.Spec{
Hooks: &specs.Hooks{
Prestart: []specs.Hook{ //nolint:all
{Args: []string{}},
},
},
}
assert.Equal("", DockerNetnsPath(spec))
}

View File

@@ -166,4 +166,14 @@ impl yaml::K8sResource for CronJob {
fn get_sysctls(&self) -> Vec<pod::Sysctl> {
yaml::get_sysctls(&self.spec.jobTemplate.spec.template.spec.securityContext)
}
fn get_pod_security_context(&self) -> Option<&pod::PodSecurityContext> {
self.spec
.jobTemplate
.spec
.template
.spec
.securityContext
.as_ref()
}
}

View File

@@ -167,4 +167,8 @@ impl yaml::K8sResource for DaemonSet {
fn get_sysctls(&self) -> Vec<pod::Sysctl> {
yaml::get_sysctls(&self.spec.template.spec.securityContext)
}
fn get_pod_security_context(&self) -> Option<&pod::PodSecurityContext> {
self.spec.template.spec.securityContext.as_ref()
}
}

View File

@@ -178,4 +178,8 @@ impl yaml::K8sResource for Deployment {
fn get_sysctls(&self) -> Vec<pod::Sysctl> {
yaml::get_sysctls(&self.spec.template.spec.securityContext)
}
fn get_pod_security_context(&self) -> Option<&pod::PodSecurityContext> {
self.spec.template.spec.securityContext.as_ref()
}
}

View File

@@ -167,6 +167,10 @@ impl yaml::K8sResource for Job {
fn get_sysctls(&self) -> Vec<pod::Sysctl> {
yaml::get_sysctls(&self.spec.template.spec.securityContext)
}
fn get_pod_security_context(&self) -> Option<&pod::PodSecurityContext> {
self.spec.template.spec.securityContext.as_ref()
}
}
pub fn pod_name_regex(job_name: String) -> String {

View File

@@ -114,10 +114,12 @@ pub fn get_mount_and_storage(
if let Some(emptyDir) = &yaml_volume.emptyDir {
let settings_volumes = &settings.volumes;
let volume = match emptyDir.medium.as_deref() {
Some("Memory") => &settings_volumes.emptyDir_memory,
_ if settings.cluster_config.encrypted_emptydir => &settings_volumes.emptyDir_encrypted,
_ => &settings_volumes.emptyDir,
let (volume, block_encrypted_emptydir) = match emptyDir.medium.as_deref() {
Some("Memory") => (&settings_volumes.emptyDir_memory, false),
_ if settings.cluster_config.encrypted_emptydir => {
(&settings_volumes.emptyDir_encrypted, true)
}
_ => (&settings_volumes.emptyDir, false),
};
get_empty_dir_mount_and_storage(
@@ -127,6 +129,7 @@ pub fn get_mount_and_storage(
yaml_mount,
volume,
pod_security_context,
block_encrypted_emptydir,
);
} else if yaml_volume.persistentVolumeClaim.is_some() || yaml_volume.azureFile.is_some() {
get_shared_bind_mount(yaml_mount, p_mounts, "rprivate", "rw");
@@ -150,18 +153,42 @@ fn get_empty_dir_mount_and_storage(
yaml_mount: &pod::VolumeMount,
settings_empty_dir: &settings::EmptyDirVolume,
pod_security_context: &Option<pod::PodSecurityContext>,
block_encrypted_emptydir: bool,
) {
debug!("Settings emptyDir: {:?}", settings_empty_dir);
if yaml_mount.subPathExpr.is_none() {
let mut options = settings_empty_dir.options.clone();
if let Some(gid) = pod_security_context.as_ref().and_then(|sc| sc.fsGroup) {
// This matches the runtime behavior of only setting the fsgid if the mountpoint GID is not 0.
// https://github.com/kata-containers/kata-containers/blob/b69da5f3ba8385c5833b31db41a846a203812675/src/runtime/virtcontainers/kata_agent.go#L1602-L1607
if gid != 0 {
options.push(format!("fsgid={gid}"));
// Pod fsGroup in policy must mirror how the shim encodes it on Storage:
// - block-encrypted host emptyDirs become virtio-blk/scsi volumes; the runtime sets
// Storage.fs_group from mount metadata (handleDeviceBlockVolume in kata_agent.go).
// - shared-fs / guest-local emptyDirs use Storage.options: the runtime appends
// fsgid=<host GID> when the volume is not root-owned (handleEphemeralStorage and
// handleLocalStorage in kata_agent.go). Genpolicy uses pod fsGroup when non-zero as
// the usual kubelet-applied GID for that stat.
let pod_gid = pod_security_context.as_ref().and_then(|sc| sc.fsGroup);
let fs_group = if block_encrypted_emptydir {
match pod_gid {
Some(gid) if gid > 0 => protobuf::MessageField::some(agent::FSGroup {
group_id: u32::try_from(gid).unwrap_or_else(|_| {
panic!(
"get_empty_dir_mount_and_storage: securityContext.fsGroup {gid} \
must be <= {}",
u32::MAX
)
}),
..Default::default()
}),
_ => protobuf::MessageField::none(),
}
}
} else {
if let Some(gid) = pod_gid {
if gid != 0 {
options.push(format!("fsgid={gid}"));
}
}
protobuf::MessageField::none()
};
storages.push(agent::Storage {
driver: settings_empty_dir.driver.clone(),
driver_options: settings_empty_dir.driver_options.clone(),
@@ -173,7 +200,7 @@ fn get_empty_dir_mount_and_storage(
} else {
settings_empty_dir.mount_point.clone()
},
fs_group: protobuf::MessageField::none(),
fs_group,
shared: settings_empty_dir.shared,
special_fields: ::protobuf::SpecialFields::new(),
});

View File

@@ -937,6 +937,10 @@ impl yaml::K8sResource for Pod {
fn get_sysctls(&self) -> Vec<Sysctl> {
yaml::get_sysctls(&self.spec.securityContext)
}
fn get_pod_security_context(&self) -> Option<&PodSecurityContext> {
self.spec.securityContext.as_ref()
}
}
impl Container {

View File

@@ -971,6 +971,16 @@ impl AgentPolicy {
);
}
yaml::apply_pod_fs_group_and_supplemental_groups(
&mut process,
resource.get_pod_security_context(),
is_pause_container,
);
debug!(
"get_container_process: after apply_pod_fs_group_and_supplemental_groups: User = {:?}",
&process.User
);
///////////////////////////////////////////////////////////////////////////////////////
// Container-level settings from user's YAML.
yaml_container.get_process_fields(&mut process);

View File

@@ -128,4 +128,8 @@ impl yaml::K8sResource for ReplicaSet {
fn get_sysctls(&self) -> Vec<pod::Sysctl> {
yaml::get_sysctls(&self.spec.template.spec.securityContext)
}
fn get_pod_security_context(&self) -> Option<&pod::PodSecurityContext> {
self.spec.template.spec.securityContext.as_ref()
}
}

View File

@@ -131,4 +131,8 @@ impl yaml::K8sResource for ReplicationController {
fn get_sysctls(&self) -> Vec<pod::Sysctl> {
yaml::get_sysctls(&self.spec.template.spec.securityContext)
}
fn get_pod_security_context(&self) -> Option<&pod::PodSecurityContext> {
self.spec.template.spec.securityContext.as_ref()
}
}

View File

@@ -211,6 +211,10 @@ impl yaml::K8sResource for StatefulSet {
fn get_sysctls(&self) -> Vec<pod::Sysctl> {
yaml::get_sysctls(&self.spec.template.spec.securityContext)
}
fn get_pod_security_context(&self) -> Option<&pod::PodSecurityContext> {
self.spec.template.spec.securityContext.as_ref()
}
}
impl StatefulSet {

View File

@@ -107,6 +107,10 @@ pub trait K8sResource {
// for some of the K8s resource types.
}
fn get_pod_security_context(&self) -> Option<&pod::PodSecurityContext> {
None
}
fn get_sysctls(&self) -> Vec<pod::Sysctl> {
vec![]
}
@@ -388,6 +392,39 @@ fn handle_unused_field(path: &str, silent_unsupported_fields: bool) {
}
}
/// Applies pod `fsGroup` and `supplementalGroups` to `AdditionalGids`.
pub fn apply_pod_fs_group_and_supplemental_groups(
process: &mut policy::KataProcess,
security_context: Option<&pod::PodSecurityContext>,
is_pause_container: bool,
) {
if is_pause_container {
return;
}
let Some(context) = security_context else {
return;
};
if let Some(fs_group) = context.fsGroup {
let gid: u32 = fs_group.try_into().unwrap();
process.User.AdditionalGids.insert(gid);
debug!(
"apply_pod_fs_group_and_supplemental_groups: inserted fs_group = {gid} into AdditionalGids, User = {:?}",
&process.User
);
}
if let Some(supplemental_groups) = &context.supplementalGroups {
supplemental_groups.iter().for_each(|g| {
process.User.AdditionalGids.insert(*g);
});
debug!(
"apply_pod_fs_group_and_supplemental_groups: inserted supplementalGroups = {:?} into AdditionalGids, User = {:?}",
&supplemental_groups, &process.User
);
}
}
pub fn get_process_fields(
process: &mut policy::KataProcess,
must_check_passwd: &mut bool,
@@ -447,27 +484,6 @@ pub fn get_process_fields(
*must_check_passwd = false;
}
if !is_pause_container {
if let Some(fs_group) = context.fsGroup {
let gid = fs_group.try_into().unwrap();
process.User.AdditionalGids.insert(gid);
debug!(
"get_process_fields: inserted fs_group = {gid} into AdditionalGids, User = {:?}",
&process.User
);
}
if let Some(supplemental_groups) = &context.supplementalGroups {
supplemental_groups.iter().for_each(|g| {
process.User.AdditionalGids.insert(*g);
});
debug!(
"get_process_fields: inserted supplementalGroups = {:?} into AdditionalGids, User = {:?}",
&supplemental_groups, &process.User
);
}
}
if let Some(allow) = context.allowPrivilegeEscalation {
process.NoNewPrivileges = !allow
}

View File

@@ -345,12 +345,12 @@
"driver_options": [
"encryption_key=ephemeral"
],
"fs_group": null,
"fs_group": {
"group_id": 1000
},
"fstype": "ext4",
"mount_point": "/run/kata-containers/sandbox/storage/MDAvMDA=",
"options": [
"fsgid=1000"
],
"options": [],
"source": "00/00",
"shared": true
}

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

@@ -0,0 +1,45 @@
#!/bin/bash
#
# Copyright (c) 2023 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
set -o errexit
set -o nounset
set -o pipefail
kata_tarball_dir="${2:-kata-artifacts}"
docker_dir="$(dirname "$(readlink -f "$0")")"
source "${docker_dir}/../../common.bash"
image="${image:-instrumentisto/nmap:latest}"
function install_dependencies() {
info "Installing the dependencies needed for running the docker smoke test"
sudo -E docker pull "${image}"
}
function run() {
info "Running docker smoke test tests using ${KATA_HYPERVISOR} hypervisor"
enabling_hypervisor
info "Running docker with runc"
sudo docker run --rm --entrypoint nping "${image}" --tcp-connect -c 2 -p 80 www.github.com
info "Running docker with Kata Containers (${KATA_HYPERVISOR})"
sudo docker run --rm --runtime io.containerd.kata-${KATA_HYPERVISOR}.v2 --entrypoint nping "${image}" --tcp-connect -c 2 -p 80 www.github.com
}
function main() {
action="${1:-}"
case "${action}" in
install-dependencies) install_dependencies ;;
install-kata) install_kata ;;
run) run ;;
*) >&2 die "Invalid argument" ;;
esac
}
main "$@"

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)

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

@@ -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

@@ -22,10 +22,17 @@ setup() {
pod_name="sharevol-kata"
pod_logs_file=""
setup_common || die "setup_common failed"
yaml_file="${pod_config_dir}/pod-empty-dir.yaml"
# Add policy to yaml
policy_settings_dir="$(create_tmp_policy_settings_dir "${pod_config_dir}")"
add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest"
}
@test "Empty dir volumes" {
local yaml_file
local mount_command
local dd_command
yaml_file="${pod_config_dir}/pod-empty-dir.yaml"
mount_command=(sh -c "mount | grep cache")
add_exec_to_policy_settings "${policy_settings_dir}" "${mount_command[@]}"
@@ -33,11 +40,9 @@ setup() {
dd_command=(sh -c "dd if=/dev/zero of=/tmp/cache/file1 bs=1M count=50; echo $?")
add_exec_to_policy_settings "${policy_settings_dir}" "${dd_command[@]}"
add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest"
# Add policy to yaml
auto_generate_policy "${policy_settings_dir}" "${yaml_file}"
}
@test "Empty dir volumes" {
# Create the pod
kubectl create -f "${yaml_file}"
@@ -55,20 +60,25 @@ setup() {
local agnhost_name
local agnhost_version
local gid
local image
local logs
local pod_file
local pod_yaml
local pod_yaml_in
local uid
# This is a reproducer of k8s e2e "[sig-storage] EmptyDir volumes when FSGroup is specified [LinuxOnly] [NodeFeature:FSGroup] new files should be created with FSGroup ownership when container is non-root" test
pod_file="${pod_config_dir}/pod-empty-dir-fsgroup.yaml"
pod_yaml_in="${pod_config_dir}/pod-empty-dir-fsgroup.yaml.in"
pod_yaml="${pod_config_dir}/pod-empty-dir-fsgroup.yaml"
agnhost_name="${container_images_agnhost_name}"
agnhost_version="${container_images_agnhost_version}"
image="${agnhost_name}:${agnhost_version}"
export AGNHOST_IMAGE="${agnhost_name}:${agnhost_version}"
envsubst '${AGNHOST_IMAGE}' <"${pod_yaml_in}" >"${pod_yaml}"
# Add policy to yaml
auto_generate_policy "${policy_settings_dir}" "${pod_yaml}"
# Try to avoid timeout by prefetching the image.
sed -e "s#\${agnhost_image}#${image}#" "$pod_file" |\
kubectl create -f -
kubectl create -f "${pod_yaml}"
cmd="kubectl get pods ${pod_name} | grep Completed"
waitForProcess "${wait_time}" "${sleep_time}" "${cmd}"
@@ -90,6 +100,7 @@ setup() {
teardown() {
[ ! -f "$pod_logs_file" ] || rm -f "$pod_logs_file"
[[ -n "${pod_config_dir:-}" ]] && rm -f "${pod_config_dir}/pod-empty-dir-fsgroup.yaml"
delete_tmp_policy_settings_dir "${policy_settings_dir}"
teardown_common "${node}" "${node_start_time:-}"

View File

@@ -10,6 +10,7 @@ load "${BATS_TEST_DIRNAME}/confidential_common.sh"
export KATA_HYPERVISOR="${KATA_HYPERVISOR:-qemu-nvidia-gpu}"
# when using hostPath, ensure directory is writable by container user
export LOCAL_NIM_CACHE="/opt/nim/.cache"
SKIP_MULTI_GPU_TESTS=${SKIP_MULTI_GPU_TESTS:-false}

View File

@@ -16,14 +16,18 @@ metadata:
# cc_init_data annotation will be added by genpolicy with CDH configuration
# from the custom default-initdata.toml created by create_nim_initdata_file()
spec:
# Explicit user/group/supplementary groups to support nydus guest-pull.
# See issue https://github.com/kata-containers/kata-containers/issues/11162 and
# other references to this issue in the genpolicy source folder.
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
supplementalGroups: [4, 20, 24, 25, 27, 29, 30, 44, 46]
restartPolicy: Never
runtimeClassName: kata
imagePullSecrets:
- name: ngc-secret-instruct
securityContext:
runAsUser: 0
runAsGroup: 0
fsGroup: 0
containers:
- name: ${POD_NAME_INSTRUCT}
image: nvcr.io/nim/meta/llama-3.1-8b-instruct:1.13.1

View File

@@ -14,10 +14,6 @@ spec:
runtimeClassName: kata
imagePullSecrets:
- name: ngc-secret-instruct
securityContext:
runAsUser: 0
runAsGroup: 0
fsGroup: 0
containers:
- name: ${POD_NAME_INSTRUCT}
image: nvcr.io/nim/meta/llama-3.1-8b-instruct:1.13.1

View File

@@ -16,15 +16,18 @@ metadata:
# cc_init_data annotation will be added by genpolicy with CDH configuration
# from the custom default-initdata.toml created by create_nim_initdata_file()
spec:
# Explicit user/group/supplementary groups to support nydus guest-pull.
# See issue https://github.com/kata-containers/kata-containers/issues/11162 and
# other references to this issue in the genpolicy source folder.
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
restartPolicy: Always
runtimeClassName: kata
serviceAccountName: default
imagePullSecrets:
- name: ngc-secret-embedqa
securityContext:
fsGroup: 0
runAsGroup: 0
runAsUser: 0
containers:
- name: ${POD_NAME_EMBEDQA}
image: nvcr.io/nim/nvidia/llama-3.2-nv-embedqa-1b-v2:1.10.1

View File

@@ -10,15 +10,16 @@ metadata:
labels:
app: ${POD_NAME_EMBEDQA}
spec:
# unlike the instruct manifest, this image needs securityContext to
# avoid NVML/GPU permission failures
securityContext:
runAsUser: 1000
runAsGroup: 1000
restartPolicy: Always
runtimeClassName: kata
serviceAccountName: default
imagePullSecrets:
- name: ngc-secret-embedqa
securityContext:
fsGroup: 0
runAsGroup: 0
runAsUser: 0
containers:
- name: ${POD_NAME_EMBEDQA}
image: nvcr.io/nim/nvidia/llama-3.2-nv-embedqa-1b-v2:1.10.1

View File

@@ -15,7 +15,7 @@ spec:
fsGroup: 123
containers:
- name: mounttest-container
image: ${agnhost_image}
image: ${AGNHOST_IMAGE}
command:
- /agnhost
args:
@@ -28,7 +28,7 @@ spec:
- name: emptydir-volume
mountPath: /test-volume
- name: mounttest-container-2
image: ${agnhost_image}
image: ${AGNHOST_IMAGE}
command:
- /agnhost
args:

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,9 +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; then
cp "${examples_dir}/20-oci-1.2.1-drop-in.json" "${settings_d}/"
elif 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
@@ -342,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

@@ -7,17 +7,17 @@
FROM golang:1.24-alpine AS nydus-binary-downloader
# Keep the version here aligned with "ndyus-snapshotter.version"
# in versions.yaml
ARG NYDUS_SNAPSHOTTER_VERSION=v0.15.13
ARG NYDUS_SNAPSHOTTER_REPO=https://github.com/containerd/nydus-snapshotter
COPY versions.yaml /tmp/versions.yaml
RUN \
set -e && \
apk add --no-cache curl yq-go && \
NYDUS_SNAPSHOTTER_VERSION="$(yq eval -e '.externals.nydus-snapshotter.version | explode(.)' /tmp/versions.yaml)" && \
NYDUS_SNAPSHOTTER_REPO="$(yq eval -e '.externals.nydus-snapshotter.url | explode(.)' /tmp/versions.yaml)" && \
mkdir -p /opt/nydus-snapshotter && \
ARCH="$(uname -m)" && \
if [ "${ARCH}" = "x86_64" ]; then ARCH=amd64 ; fi && \
if [ "${ARCH}" = "aarch64" ]; then ARCH=arm64; fi && \
apk add --no-cache curl && \
curl -fOL --progress-bar "${NYDUS_SNAPSHOTTER_REPO}/releases/download/${NYDUS_SNAPSHOTTER_VERSION}/nydus-snapshotter-${NYDUS_SNAPSHOTTER_VERSION}-linux-${ARCH}.tar.gz" && \
tar xvzpf "nydus-snapshotter-${NYDUS_SNAPSHOTTER_VERSION}-linux-${ARCH}.tar.gz" -C /opt/nydus-snapshotter && \
rm "nydus-snapshotter-${NYDUS_SNAPSHOTTER_VERSION}-linux-${ARCH}.tar.gz"
@@ -49,10 +49,13 @@ RUN \
apt-get clean && rm -rf /var/lib/apt/lists/ && \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain ${RUST_TOOLCHAIN}
WORKDIR /kata-deploy
# Build from the repository root so kata-deploy uses the root Cargo workspace:
# docker build -f tools/packaging/kata-deploy/Dockerfile .
WORKDIR /kata
# Copy standalone binary project
COPY binary /kata-deploy
COPY Cargo.toml Cargo.lock ./
COPY src ./src
COPY tools/packaging/kata-deploy/binary ./tools/packaging/kata-deploy/binary
# Install target and run tests based on architecture
# - AMD64/arm64: use musl for fully static binaries
@@ -93,23 +96,23 @@ RUN \
RUN \
rust_target="$(cat /tmp/rust_target)"; \
echo "Running binary tests with target ${rust_target}..." && \
RUSTFLAGS="-D warnings" cargo test --target "${rust_target}" -- --test-threads=1 && \
RUSTFLAGS="-D warnings" cargo test -p kata-deploy --target "${rust_target}" -- --test-threads=1 && \
echo "All tests passed!"
RUN \
rust_target="$(cat /tmp/rust_target)"; \
echo "Building kata-deploy binary for ${rust_target}..." && \
RUSTFLAGS="-D warnings" cargo build --release --target "${rust_target}" && \
RUSTFLAGS="-D warnings" cargo build --release -p kata-deploy --target "${rust_target}" && \
mkdir -p /kata-deploy/bin && \
cp "/kata-deploy/target/${rust_target}/release/kata-deploy" /kata-deploy/bin/kata-deploy && \
cp "/kata/target/${rust_target}/release/kata-deploy" /kata-deploy/bin/kata-deploy && \
echo "Cleaning up build artifacts to save disk space..." && \
rm -rf /kata-deploy/target && \
rm -rf /kata/target && \
cargo clean
#### Extract kata artifacts
FROM alpine:3.22 AS artifact-extractor
ARG KATA_ARTIFACTS=kata-static.tar.zst
ARG KATA_ARTIFACTS=tools/packaging/kata-deploy/kata-static.tar.zst
ARG DESTINATION=/opt/kata-artifacts
COPY ${KATA_ARTIFACTS} /tmp/
@@ -222,11 +225,11 @@ COPY --from=runtime-assembler /output/lib/ /lib/
COPY --from=runtime-assembler /output/lib64/ /lib64/
# Copy nydus snapshotter
COPY nydus-snapshotter ${DESTINATION}/nydus-snapshotter
COPY tools/packaging/kata-deploy/nydus-snapshotter ${DESTINATION}/nydus-snapshotter
COPY --from=nydus-binary-downloader /opt/nydus-snapshotter/bin/containerd-nydus-grpc ${DESTINATION}/nydus-snapshotter/
COPY --from=nydus-binary-downloader /opt/nydus-snapshotter/bin/nydus-overlayfs ${DESTINATION}/nydus-snapshotter/
# Copy runtimeclasses and node-feature-rules
COPY node-feature-rules ${DESTINATION}/node-feature-rules
COPY tools/packaging/kata-deploy/node-feature-rules ${DESTINATION}/node-feature-rules
ENTRYPOINT ["/usr/bin/kata-deploy"]

View File

@@ -1,58 +1,38 @@
[package]
name = "kata-deploy"
version = "0.1.0"
authors.workspace = true
edition = "2021"
license.workspace = true
rust-version = "1.90.0"
authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>"]
license = "Apache-2.0"
[[bin]]
name = "kata-deploy"
path = "src/main.rs"
[dependencies]
# Error handling
anyhow = "1.0"
# Logging
log = "0.4"
anyhow.workspace = true
clap.workspace = true
env_logger = "0.10"
# Command line parsing
clap = { version = "4.5", features = ["derive"] }
# TOML parsing and manipulation
toml_edit = "0.22"
# YAML parsing and manipulation
serde_yaml = "0.9"
# Kubernetes API client
kube = { version = "2.0", features = ["runtime", "derive"] }
k8s-openapi = { version = "0.26", default-features = false, features = [
"v1_33",
] }
# System operations (using nsenter command instead of syscalls)
libc = "0.2"
# JSON serialization
serde_json = "1.0"
# File operations
walkdir = "2"
# String manipulation
regex = "1.10"
# Async runtime (required by kube-rs and for async main)
tokio = { version = "1.38", features = [
kube = { version = "2.0", features = ["runtime", "derive"] }
libc.workspace = true
log.workspace = true
regex.workspace = true
serde_json.workspace = true
serde_yaml = "0.9"
tokio = { workspace = true, features = [
"rt-multi-thread",
"macros",
"signal",
"time",
] }
toml_edit = "0.22"
walkdir = "2"
[dev-dependencies]
tempfile = "3.8"
rstest = "0.18"
rstest.workspace = true
serial_test.workspace = true
tempfile.workspace = true

View File

@@ -757,18 +757,15 @@ fn get_arch_var_or_base(base_name: &str, arch: &str) -> Option<String> {
mod tests {
//! Tests for configuration parsing and validation.
//!
//! IMPORTANT: All tests in this crate MUST be run serially (--test-threads=1)
//! because they manipulate shared environment variables. Running tests in parallel
//! will cause race conditions and test failures.
//!
//! Use: cargo test --bin kata-deploy -- --test-threads=1
//! Tests that touch environment variables use `serial_test::serial` so they do not run
//! in parallel within this process. For extra isolation you can still use
//! `cargo test -p kata-deploy config::tests -- --test-threads=1`.
use super::*;
use rstest::rstest;
use serial_test::serial;
// NOTE: These tests modify environment variables which are process-global.
// Run with: cargo test config::tests -- --test-threads=1
// to ensure proper test isolation.
// NOTE: Env-var tests use #[serial] (see above) for safe parallel execution with other modules.
/// Helper to clean up common environment variables used in tests
fn cleanup_env_vars() {
@@ -867,6 +864,7 @@ mod tests {
);
}
#[serial]
#[test]
fn test_get_arch() {
let arch = get_arch().unwrap();
@@ -874,6 +872,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_get_arch_var() {
std::env::set_var("SHIMS_X86_64", "test1 test2");
@@ -887,10 +886,12 @@ mod tests {
#[rstest]
#[case(false, "config.toml.d")]
#[case(true, "config-v3.toml.d")]
#[serial]
fn test_k3s_rke2_drop_in_dir_name(#[case] use_v3: bool, #[case] expected: &str) {
assert_eq!(k3s_rke2_drop_in_dir_name(use_v3), expected);
}
#[serial]
#[test]
fn test_k3s_rke2_rendered_config_path() {
assert_eq!(k3s_rke2_rendered_config_path(), "/etc/containerd/config.toml");
@@ -905,6 +906,7 @@ mod tests {
#[case("version = 2\n", false, false)]
#[case("imports = [\"/path/config-v3.toml.d/*.toml\"]", true, true)]
#[case("imports = [\"/path/config.toml.d/*.toml\"]", true, false)]
#[serial]
fn test_k3s_rke2_rendered_has_import(
#[case] content: &str,
#[case] use_v3: bool,
@@ -913,6 +915,7 @@ mod tests {
assert_eq!(k3s_rke2_rendered_has_import(content, use_v3), expected);
}
#[serial]
#[test]
fn test_multi_install_suffix_not_set() {
setup_minimal_env();
@@ -929,6 +932,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_multi_install_suffix_with_value() {
setup_minimal_env();
@@ -950,6 +954,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_multi_install_suffix_different_values() {
let suffixes = ["staging", "prod", "v2", "test123"];
@@ -970,6 +975,7 @@ mod tests {
}
}
#[serial]
#[test]
fn test_multi_install_prefix_and_suffix() {
setup_minimal_env();
@@ -988,6 +994,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_validate_empty_shims_no_custom_runtimes() {
setup_minimal_env();
@@ -1013,6 +1020,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_validate_default_shim_not_in_shims() {
setup_minimal_env();
@@ -1025,6 +1033,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_validate_hypervisor_annotation_invalid_shim() {
setup_minimal_env();
@@ -1041,6 +1050,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_validate_agent_https_proxy_invalid_shim() {
setup_minimal_env();
@@ -1057,6 +1067,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_validate_snapshotter_mapping_invalid_shim() {
setup_minimal_env();
@@ -1067,6 +1078,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_validate_pull_type_mapping_invalid_shim() {
setup_minimal_env();
@@ -1077,6 +1089,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_validate_force_guest_pull_invalid_shim() {
setup_minimal_env();
@@ -1087,6 +1100,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_validate_success() {
setup_minimal_env();
@@ -1106,6 +1120,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_missing_node_name_fails() {
cleanup_env_vars();
@@ -1116,6 +1131,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_empty_node_name_fails() {
setup_minimal_env();
@@ -1125,6 +1141,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_empty_default_shim_fails() {
setup_minimal_env();
@@ -1137,6 +1154,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_whitespace_only_default_shim_fails() {
setup_minimal_env();
@@ -1147,6 +1165,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_whitespace_only_shims_fails() {
setup_minimal_env();
@@ -1156,6 +1175,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_agent_no_proxy_invalid_shim() {
setup_minimal_env();
@@ -1166,6 +1186,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_multi_install_suffix_empty_treated_as_none() {
setup_minimal_env();
@@ -1177,6 +1198,7 @@ mod tests {
cleanup_env_vars();
}
#[serial]
#[test]
fn test_arch_specific_all_variables() {
// Test ALL architecture-specific variables work without base variables

View File

@@ -41,7 +41,7 @@ updateStrategy:
debug: false
snapshotter:
setup: [] # ["nydus", "erofs"] or []
setup: ["nydus"] # ["nydus", "erofs"] or []
# Shim configuration
# By default (disableAll: false), all shims with enabled: ~ (null) are enabled.
@@ -153,8 +153,8 @@ shims:
- amd64
allowedHypervisorAnnotations: []
containerd:
snapshotter: ""
forceGuestPull: true
snapshotter: "nydus"
forceGuestPull: false
crio:
guestPull: true
agent:
@@ -176,8 +176,8 @@ shims:
- amd64
allowedHypervisorAnnotations: []
containerd:
snapshotter: ""
forceGuestPull: true
snapshotter: "nydus"
forceGuestPull: false
crio:
guestPull: true
agent:

View File

@@ -11,25 +11,48 @@ set -o nounset
set -o pipefail
set -o errtrace
KATA_DEPLOY_DIR="`dirname ${0}`/../../kata-deploy"
SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../../../.." && pwd)"
KATA_DEPLOY_DIR="${REPO_ROOT}/tools/packaging/kata-deploy"
STAGED_ARTIFACT="${KATA_DEPLOY_DIR}/kata-static.tar.zst"
KATA_DEPLOY_ARTIFACT="${1:-"kata-static.tar.zst"}"
REGISTRY="${2:-"quay.io/kata-containers/kata-deploy"}"
TAG="${3:-}"
echo "Copying ${KATA_DEPLOY_ARTIFACT} to ${KATA_DEPLOY_DIR}"
cp ${KATA_DEPLOY_ARTIFACT} ${KATA_DEPLOY_DIR}
# Only remove a staged copy we created (skip when source is already the staged path).
REMOVE_STAGED_ON_EXIT=false
cleanup() {
if [ "${REMOVE_STAGED_ON_EXIT}" = true ]; then
rm -f "${STAGED_ARTIFACT}"
fi
}
trap cleanup EXIT
pushd ${KATA_DEPLOY_DIR}
src_rp="$(realpath -e "${KATA_DEPLOY_ARTIFACT}" 2>/dev/null || true)"
dest_rp="$(realpath -e "${STAGED_ARTIFACT}" 2>/dev/null || true)"
if [ -n "${src_rp}" ] && [ -n "${dest_rp}" ] && [ "${src_rp}" = "${dest_rp}" ]; then
echo "Artifact already at staged path ${STAGED_ARTIFACT}; skipping copy"
else
echo "Copying ${KATA_DEPLOY_ARTIFACT} to ${STAGED_ARTIFACT}"
cp "${KATA_DEPLOY_ARTIFACT}" "${STAGED_ARTIFACT}"
REMOVE_STAGED_ON_EXIT=true
fi
pushd "${REPO_ROOT}"
arch=$(uname -m)
[ "$arch" = "x86_64" ] && arch="amd64"
[ "$arch" = "aarch64" ] && arch="arm64"
# Disable provenance and SBOM so each tag is a single image manifest. quay.io rejects
# pushing multi-arch manifest lists that include attestation manifests ("manifest invalid").
PLATFORM="linux/${arch}"
IMAGE_TAG="${REGISTRY}:kata-containers-$(git rev-parse HEAD)-${arch}"
IMAGE_TAG="${REGISTRY}:kata-containers-$(git -C "${REPO_ROOT}" rev-parse HEAD)-${arch}"
DOCKERFILE="${REPO_ROOT}/tools/packaging/kata-deploy/Dockerfile"
echo "Building the image"
docker buildx build --platform "${PLATFORM}" --provenance false --sbom false \
-f "${DOCKERFILE}" \
--tag "${IMAGE_TAG}" --push .
if [ -n "${TAG}" ]; then
@@ -37,6 +60,7 @@ if [ -n "${TAG}" ]; then
echo "Building the ${ADDITIONAL_TAG} image"
docker buildx build --platform "${PLATFORM}" --provenance false --sbom false \
-f "${DOCKERFILE}" \
--tag "${ADDITIONAL_TAG}" --push .
fi

View File

@@ -234,7 +234,7 @@ externals:
nvrc:
# yamllint disable-line rule:line-length
desc: "The NVRC project provides a Rust binary that implements a simple init system for microVMs"
version: "v0.1.3"
version: "v0.1.4"
url: "https://github.com/NVIDIA/nvrc/releases/download/"
nvidia:
@@ -383,8 +383,6 @@ externals:
url: "https://github.com/dragonflyoss/image-service"
version: "v2.2.3"
# Keep the version here aligned with the NYDUS_SNAPSHOTTER_VERSION
# on tools/packaging/kata-deploy/Dockerfile
nydus-snapshotter:
description: "Snapshotter for Nydus image acceleration service"
url: "https://github.com/containerd/nydus-snapshotter"