Compare commits

...

42 Commits

Author SHA1 Message Date
Aurélien Bombo
9d4fcd3708 runtime-rs: Use fully qualified NixPath::is_empty()
This avoids issues like below which are now errors in Rust 1.94:

error: a method with this name may be added to the standard library in the future
   --> src/libs/kata-sys-util/src/mount.rs:265:12
    |
265 |     if src.is_empty() {
    |            ^^^^^^^^
    |
    = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior!
    = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919>
    = help: call with fully qualified syntax `nix::NixPath::is_empty(...)` to keep using the current method

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-03-19 17:07:02 -05:00
Aurélien Bombo
78272ad7b7 runtime-rs: Remove unnecessary unsafe blocks
This avoids issues like below which are now errors in Rust 1.94.

error: unnecessary `unsafe` block
   --> src/libs/kata-sys-util/src/protection.rs:129:19
    |
129 |         let fn0 = unsafe { x86_64::__cpuid(0) };
    |                   ^^^^^^ unnecessary `unsafe` block
    |
    = note: `-D unused-unsafe` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(unused_unsafe)]`

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-03-19 17:07:02 -05:00
Alex Lyn
de2ddf6ed9 Merge pull request #12637 from stevenhorsman/bump-rust-to-1.92
versions: Bump rust to 1.92
2026-03-19 10:02:18 +08:00
Aurélien Bombo
352b4cdad2 Merge pull request #12660 from LandonTClipp/ci_docs
ci: Don't run CI builds on doc PRs
2026-03-17 12:19:11 -05:00
stevenhorsman
56b6917adf versions: Bump rust to 1.92
Now that 1.94 has release, in compliance with our toolchain guidance
we should bump to rust 1.92

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-03-17 16:04:58 +00:00
stevenhorsman
2a4227e02e kata-ctl: Try fixing unused_assignement error
`allow(unused_assignments)` isn't working as it's
in macro generated code, so referencing the command
in the error, to use it

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-03-17 16:04:58 +00:00
stevenhorsman
ca7cdcd732 kata-ctl: Rewrite path_join test
This test was failing clippy by calling .unwrap() after
an .is_ok(), but after I looked at it, it seemed a bit messy,
so I split it up and tried rewriting it to make it more readable
IMHO.

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-03-17 16:04:58 +00:00
stevenhorsman
501578cc5a agent: Remove non-idiomatic unwrap
Calling .unwrap() after an .is_some() check is considered non-idiomatic in
as it performs redundant work and makes the code more verbose.

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-03-17 16:04:58 +00:00
Alex Lyn
833b72470c Merge pull request #12647 from sprt/gp-improve
genpolicy: Improve emptyDir storage options and mount point validation
2026-03-17 13:56:42 +08:00
Manuel Huber
660e3bb653 gpu: Obsolete the NVIDIA initrd build
As the NVIDIA stack has shifted to using an image for both the
confidential and non-confidential variants, we retire the initrd
build.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-03-16 21:29:58 -04:00
Aurélien Bombo
f8e234c6f9 Merge pull request #12650 from kata-containers/sprt/remove-csi
ci: Stop building/deploying CSI driver
2026-03-16 16:53:02 -05:00
Steve Horsman
294c367063 Merge pull request #12668 from manuelh-dev/release/3.28.0
release: Bump version to 3.28.0
2026-03-16 19:47:12 +00:00
Manuel Huber
5210584f95 release: Bump version to 3.28.0
Bump VERSION and helm-charts versions.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-03-16 09:52:35 -07:00
Manuel Huber
e13748f46d tests: Adapt trusted ephemeral storage test
With the new CDH version, the LUKS header is moved off of the disk
into guest memory. We hence adapt the test's filesystem type checks.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-03-16 09:43:17 -07:00
Manuel Huber
5bbc0abb81 tests: use pre-created, signed sealed secrets
With signature support for sealed secret, use pre-created signed
sealed secrets and provision the signing public key to the KBS.

Add instructions for re-creating these signed secrets.

Improve k8s-sealed-secrets.bats by reducing repeated kubectl logs
calls. A test run showed a SIGPIPE error one one of the grep-logs
while the printouts of the initial kubectl logs invocation showed
that the expected values were actually in the logs.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-03-16 09:43:17 -07:00
Manuel Huber
a9b222f91e gpu: Update chiseled rootfs with new CDH deps
With CDH requiring libcryptsetup, mkfs.ext4, dd, and their
dependencies, we will need to update the chiseled NVIDIA rootfs
accordingly.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-03-16 09:43:17 -07:00
Manuel Huber
169f92ff09 agent: cdh: Update CDH and API
With the new CDH version, the secure_mount API changes.
Further, the new CDH version no longer uses the luks-encrypt-storage
script but utilizes libcryptsetup as well as mkfs.ext4 and dd. Hence, adapt
some of the CDH and Kata components build steps

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-03-16 09:43:17 -07:00
Alex Lyn
ef5db0a01f Merge pull request #12607 from zvonkok/system-map
kernel: Ship System.map as part of the kernel build
2026-03-16 09:37:44 +08:00
Zvonko Kaiser
99f32de1e5 kata-deploy: Update RuntimeClass PodOverhead
Align the podOverhead with the default_memory updated
in the previous commit.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-15 09:53:32 -07:00
Zvonko Kaiser
6a853a9684 gpu: Bump NVRC
We have a new release add this one to the next
Kata release.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>

Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-15 09:53:32 -07:00
Zvonko Kaiser
8ff5d164c6 runtime: make CDI annotation vendor-agnostic with lookup table
Replace hardcoded NVIDIA vendor ID (0x10de) and class (0x030) checks
with a vendor-agnostic lookup table (cdiDeviceKind) that maps PCI
vendor/class pairs to CDI device kinds. This makes it straightforward
to add support for new device types by adding entries to the table.

Refactor siblingAnnotation to resolve device BDFs once upfront and
reuse them for both CDI type detection and sibling matching, eliminating
redundant sysfs reads. Devices not in the lookup table (e.g. NVSwitches)
are skipped with errNoSiblingFound, while known device types that fail
to match a sibling produce a hard error.

Consolidate the hot-plug and cold-plug device loops into a single loop
over extracted container paths, removing duplicated filtering logic.

Export GetPCIDeviceProperty from the device drivers package to allow
vendor/class lookup from sysfs in the container annotation path.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-15 09:53:32 -07:00
Zvonko Kaiser
d4c21f50b5 gpu: Bump default memory to 8G for GPU runtimes
We need enough inital memory to prepare more complex
platforms like HGX H100 or HGX B200 systems.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-15 09:53:32 -07:00
Zvonko Kaiser
5c9683f006 gpu: Remove devtmpfs.mount=0
With the newest NVRC release this is solved and does
not need to be overriden.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-15 09:53:32 -07:00
Zvonko Kaiser
d22c314e91 gpu: Increase dial_timeout=1200
For cold-plug when running with nerdctl the timeouts in the config
are being used, increase the dial_timeout (e.g. for CreateSandbox) to match
create_container_timeout.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-15 09:53:32 -07:00
Zvonko Kaiser
7fe84c8038 gpu: HGX Rootfs Fixes
Various smaller fixes to enable HGX systems.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-15 09:53:32 -07:00
Joji Mekkattuparamban
1fd66db271 nvidia-gpu: add missing libraries to rootfs
Added the missing packages to the nvidia rootfs.

Fixes #12534

Signed-off-by: Joji Mekkattuparamban <jojim@nvidia.com>
2026-03-13 16:24:32 -07:00
Dan Mihai
9332b75c04 Merge pull request #12661 from stevenhorsman/runtime-go-1.25.8
runtime: bump go.mod version
2026-03-13 14:06:08 -07:00
Zvonko Kaiser
d382379571 kernel: Ship System.map as part of the kernel build
Some use-cases need the System.map of the running kernel,
ship it via kernel-artifact.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-13 19:27:18 +00:00
Manuel Huber
4a7022d2f4 tests: nvidia: call genpolicy auth for all tests
Call the setup_genpolicy_registry_auth in run_kubernetes_nv_tests.sh.
Authenticate before exercising any tests.

Recently, we have seen UnauthorizedError messages for the CUDA
vectorAdd image. While this image is not gated behind authentication,
rate limiting may be a possible issue.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-03-13 09:03:01 -07:00
LandonTClipp
9a8932412d docs: remove URL and markdown reference checks
This URL check performed a CURL command to see if it was real. This will
not work in the mkdocs world because the docs might reference a link that
is not yet built on the main page. This is a chicken-and-egg problem.

For reference:

```
ERROR: Invalid URL 'https://kata-containers.github.io/kata-containers/installation/#helm-chart' found in the following files:

tools/packaging/kata-deploy/helm-chart/README.md
```

The markdown reference requirement was put in place for the old docs system, but this
will not apply anymore in the new mkdocs system. I'm removing this
entirely because it will only get in the way and cause confusion.

Signed-off-by: LandonTClipp <11232769+LandonTClipp@users.noreply.github.com>
2026-03-12 15:48:35 -05:00
LandonTClipp
d5d741f4e3 ci: Don't run CI builds on doc PRs
We disable the Kata artifact builds and testing if the PR is only
related to documentation. Regular static checks will remain.

Signed-off-by: LandonTClipp <11232769+LandonTClipp@users.noreply.github.com>
2026-03-12 15:48:05 -05:00
Zvonko Kaiser
4c450a5b01 Merge pull request #12648 from manuelh-dev/mahuber/trustee-upgrade
versions: bump trustee to latest version
2026-03-12 14:09:15 -04:00
Steve Horsman
7d2e18575c Merge pull request #12343 from zvonkok/release-model
doc: Release model update
2026-03-12 14:44:51 +00:00
Zvonko Kaiser
7f662662cf lint: Fix 80 char column size
Make markdownlint happy

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-12 12:03:29 +00:00
Zvonko Kaiser
6e03a95730 doc: Update Release Process
Add how Kata is doing the rolling release.

Signed-off-by: Zvonko Kaiser <zkaiser@nvidia.com>
2026-03-12 12:03:29 +00:00
stevenhorsman
f25fa6ab25 runtime: bump go.mod version
Update the runtime's go.mod go version to 1.25.8 to
keep in sync with versions.yaml

Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-03-12 08:53:40 +00:00
Manuel Huber
0926c92aa0 versions: bump trustee to latest version
Ingest various recent fixes and dependency updates.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-03-11 14:45:42 -07:00
Aurélien Bombo
32444737b5 gatekeeper: Remove csi-kata-directvolume build from required tests
Since we don't build that anymore.

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-03-11 12:55:23 -05:00
Aurélien Bombo
64aed13d5f Revert "ci: Add no-op step to compile CSI driver"
This reverts commit e43c59a2c6.

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-03-11 12:55:23 -05:00
Aurélien Bombo
dd2c4c0db3 Revert "coco: ci: Add no-op steps to deploy CSI driver"
This reverts commit 5e4990bcf5.

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-03-11 12:55:23 -05:00
Aurélien Bombo
d598e0baf1 Revert "ci: Implement build step for CSI driver"
This partially reverts commit fb87bf221f.

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-03-11 12:55:23 -05:00
Aurélien Bombo
2a15cfc5ec genpolicy: Improve emptyDir storage options and mount point validation
These are two changes following a Copilot review on #10559:

1. Restore the p_storage.driver != "blk" check in allow_storage_options():
   - An early version of #10599 hardcoded p_storage.driver to "blk".
   - Hence that check needed to be removed to validate "blk" storage options.
   - The final version of #10599 hardcodes p_storage.driver to "" to
     account for both "blk" and "scsi", and checks storage options in
     allow_block_storage().
   - Hence that check should be restored to preserve the original behavior.

https://github.com/kata-containers/kata-containers/pull/10559#discussion_r2907646552

2. Don't use a regex to validate emptyDir storage mount points:
   - It's risky to use a regex to validate a path that has base64-encoded
     components.
   - We can infer the exact path anyway so the regex is redundant.

https://github.com/kata-containers/kata-containers/pull/10559#discussion_r2907646582

Signed-off-by: Aurélien Bombo <abombo@microsoft.com>
2026-03-10 11:22:10 -05:00
48 changed files with 508 additions and 559 deletions

View File

@@ -168,8 +168,6 @@ jobs:
- rootfs-image-nvidia-gpu-confidential
- rootfs-initrd
- rootfs-initrd-confidential
- rootfs-initrd-nvidia-gpu
- rootfs-initrd-nvidia-gpu-confidential
steps:
- name: Login to Kata Containers quay.io
if: ${{ inputs.push-to-registry == 'yes' }}
@@ -367,7 +365,6 @@ jobs:
matrix:
asset:
- agent-ctl
- csi-kata-directvolume
- genpolicy
- kata-ctl
- kata-manager

View File

@@ -152,7 +152,6 @@ jobs:
- rootfs-image
- rootfs-image-nvidia-gpu
- rootfs-initrd
- rootfs-initrd-nvidia-gpu
steps:
- name: Login to Kata Containers quay.io
if: ${{ inputs.push-to-registry == 'yes' }}

View File

@@ -110,10 +110,6 @@ jobs:
timeout-minutes: 10
run: bash tests/integration/kubernetes/gha-run.sh install-kbs-client
- name: Deploy CSI driver
timeout-minutes: 5
run: bash tests/integration/kubernetes/gha-run.sh deploy-csi-driver
- name: Run tests
timeout-minutes: 100
run: bash tests/integration/kubernetes/gha-run.sh run-tests
@@ -134,10 +130,6 @@ jobs:
[[ "${KATA_HYPERVISOR}" == "qemu-tdx" ]] && echo "ITA_KEY=${GH_ITA_KEY}" >> "${GITHUB_ENV}"
bash tests/integration/kubernetes/gha-run.sh delete-coco-kbs
- name: Delete CSI driver
timeout-minutes: 5
run: bash tests/integration/kubernetes/gha-run.sh delete-csi-driver
# Generate jobs for testing CoCo on non-TEE environments
run-k8s-tests-coco-nontee:
name: run-k8s-tests-coco-nontee
@@ -235,10 +227,6 @@ jobs:
timeout-minutes: 10
run: bash tests/integration/kubernetes/gha-run.sh install-kbs-client
- name: Deploy CSI driver
timeout-minutes: 5
run: bash tests/integration/kubernetes/gha-run.sh deploy-csi-driver
- name: Run tests
timeout-minutes: 80
run: bash tests/integration/kubernetes/gha-run.sh run-tests
@@ -257,11 +245,6 @@ jobs:
timeout-minutes: 10
run: bash tests/integration/kubernetes/gha-run.sh delete-coco-kbs
- name: Delete CSI driver
if: always()
timeout-minutes: 5
run: bash tests/integration/kubernetes/gha-run.sh delete-csi-driver
# Extensive matrix: autogenerated policy tests (nydus + experimental-force-guest-pull) on k0s, k3s, rke2, microk8s with qemu-coco-dev / qemu-coco-dev-runtime-rs
run-k8s-tests-coco-nontee-extensive-matrix:
if: ${{ inputs.extensive-matrix-autogenerated-policy == 'yes' }}
@@ -365,10 +348,6 @@ jobs:
timeout-minutes: 10
run: bash tests/integration/kubernetes/gha-run.sh install-kbs-client
- name: Deploy CSI driver
timeout-minutes: 5
run: bash tests/integration/kubernetes/gha-run.sh deploy-csi-driver
- name: Run tests
timeout-minutes: 80
run: bash tests/integration/kubernetes/gha-run.sh run-tests
@@ -387,11 +366,6 @@ jobs:
timeout-minutes: 10
run: bash tests/integration/kubernetes/gha-run.sh delete-coco-kbs
- name: Delete CSI driver
if: always()
timeout-minutes: 5
run: bash tests/integration/kubernetes/gha-run.sh delete-csi-driver
# Generate jobs for testing CoCo on non-TEE environments with erofs-snapshotter
run-k8s-tests-coco-nontee-with-erofs-snapshotter:
name: run-k8s-tests-coco-nontee-with-erofs-snapshotter
@@ -478,10 +452,6 @@ jobs:
timeout-minutes: 20
run: bash tests/integration/kubernetes/gha-run.sh deploy-kata
- name: Deploy CSI driver
timeout-minutes: 5
run: bash tests/integration/kubernetes/gha-run.sh deploy-csi-driver
- name: Run tests
timeout-minutes: 80
run: bash tests/integration/kubernetes/gha-run.sh run-tests
@@ -494,8 +464,3 @@ jobs:
if: always()
timeout-minutes: 15
run: bash tests/integration/kubernetes/gha-run.sh cleanup
- name: Delete CSI driver
if: always()
timeout-minutes: 5
run: bash tests/integration/kubernetes/gha-run.sh delete-csi-driver

View File

@@ -1 +1 @@
3.27.0
3.28.0

View File

@@ -1,57 +1,64 @@
# How to do a Kata Containers Release
This document lists the tasks required to create a Kata Release.
## Requirements
- GitHub permissions to run workflows.
## Versioning
## Release Model
The Kata Containers project uses [semantic versioning](http://semver.org/) for all releases.
Semantic versions are comprised of three fields in the form:
Kata Containers follows a rolling release model with monthly snapshots.
New features, bug fixes, and improvements are continuously integrated into
`main`. Each month, a snapshot is tagged as a new `MINOR` release.
```
MAJOR.MINOR.PATCH
```
### Versioning
When `MINOR` increases, the new release adds **new features** but *without changing the existing behavior*.
Releases use the `MAJOR.MINOR.PATCH` scheme. Monthly snapshots increment
`MINOR`; `PATCH` is typically `0`. Major releases are rare (years apart) and
signal significant architectural changes that may require updates to container
managers (Containerd, CRI-O) or other infrastructure. Breaking changes in
`MINOR` releases are avoided where possible, but may occasionally occur as
features are deprecated or removed.
When `MAJOR` increases, the new release adds **new features, bug fixes, or
both** and which **changes the behavior from the previous release** (incompatible with previous releases).
### No Stable Branches
A major release will also likely require a change of the container manager version used,
-for example Containerd or CRI-O. Please refer to the release notes for further details.
**Important** : the Kata Containers project doesn't have stable branches (see
[this issue](https://github.com/kata-containers/kata-containers/issues/9064) for details).
Bug fixes are released as part of `MINOR` or `MAJOR` releases only. `PATCH` is always `0`.
The Kata Containers project does not maintain stable branches (see
[#9064](https://github.com/kata-containers/kata-containers/issues/9064)).
Bug fixes land on `main` and ship in the next monthly snapshot rather than
being backported. Downstream projects that need extended support or compliance
certifications should select a monthly snapshot as their stable base and manage
their own validation and patch backporting from there.
## Release Process
### Bump the `VERSION` and `Chart.yaml` file
When the `kata-containers/kata-containers` repository is ready for a new release,
first create a PR to set the release in the [`VERSION`](./../VERSION) file and update the
`version` and `appVersion` in the
[`Chart.yaml`](./../tools/packaging/kata-deploy/helm-chart/kata-deploy/Chart.yaml) file and
have it merged.
When the `kata-containers/kata-containers` repository is ready for a new
release, first create a PR to set the release in the [`VERSION`](./../VERSION)
file and update the `version` and `appVersion` in the
[`Chart.yaml`](./../tools/packaging/kata-deploy/helm-chart/kata-deploy/Chart.yaml)
file and have it merged.
### Lock the `main` branch
In order to prevent any PRs getting merged during the release process, and slowing the release
process down, by impacting the payload caches, we have recently trailed setting the `main`
branch to read only whilst the release action runs.
In order to prevent any PRs getting merged during the release process, and
slowing the release process down, by impacting the payload caches, we have
recently trialed setting the `main` branch to read only whilst the release
action runs.
> [!NOTE]
> Admin permission is needed to complete this task.
### Wait for the `VERSION` bump PR payload publish to complete
To reduce the chance of need to re-run the release workflow, check the
[CI | Publish Kata Containers payload](https://github.com/kata-containers/kata-containers/actions/workflows/payload-after-push.yaml)
To reduce the chance of need to re-run the release workflow, check the [CI |
Publish Kata Containers
payload](https://github.com/kata-containers/kata-containers/actions/workflows/payload-after-push.yaml)
once the `VERSION` PR bump has merged to check that the assets build correctly
and are cached, so that the release process can just download these artifacts
rather than needing to build them all, which takes time and can reveal errors in infra.
rather than needing to build them all, which takes time and can reveal errors in
infra.
### Check GitHub Actions
@@ -63,11 +70,10 @@ release artifacts.
> [!NOTE]
> Write permissions to trigger the action.
The action is manually triggered and is responsible for generating a new
release (including a new tag), pushing those to the
`kata-containers/kata-containers` repository. The new release is initially
created as a draft. It is promoted to an official release when the whole
workflow has completed successfully.
The action is manually triggered and is responsible for generating a new release
(including a new tag), pushing those to the `kata-containers/kata-containers`
repository. The new release is initially created as a draft. It is promoted to
an official release when the whole workflow has completed successfully.
Check the [actions status
page](https://github.com/kata-containers/kata-containers/actions) to verify all
@@ -75,12 +81,13 @@ steps in the actions workflow have completed successfully. On success, a static
tarball containing Kata release artifacts will be uploaded to the [Release
page](https://github.com/kata-containers/kata-containers/releases).
If the workflow fails because of some external environmental causes, e.g. network
timeout, simply re-run the failed jobs until they eventually succeed.
If the workflow fails because of some external environmental causes, e.g.
network timeout, simply re-run the failed jobs until they eventually succeed.
If for some reason you need to cancel the workflow or re-run it entirely, go first
to the [Release page](https://github.com/kata-containers/kata-containers/releases) and
delete the draft release from the previous run.
If for some reason you need to cancel the workflow or re-run it entirely, go
first to the [Release
page](https://github.com/kata-containers/kata-containers/releases) and delete
the draft release from the previous run.
### Unlock the `main` branch
@@ -90,9 +97,8 @@ an admin to do it.
### Improve the release notes
Release notes are auto-generated by the GitHub CLI tool used as part of our
release workflow. However, some manual tweaking may still be necessary in
order to highlight the most important features and bug fixes in a specific
release.
release workflow. However, some manual tweaking may still be necessary in order
to highlight the most important features and bug fixes in a specific release.
With this in mind, please, poke @channel on #kata-dev and people who worked on
the release will be able to contribute to that.

View File

@@ -1,3 +1,3 @@
[toolchain]
# Keep in sync with versions.yaml
channel = "1.91"
channel = "1.92"

View File

@@ -110,8 +110,10 @@ impl Namespace {
unshare(cf)?;
if ns_type == NamespaceType::Uts && hostname.is_some() {
nix::unistd::sethostname(hostname.unwrap())?;
if ns_type == NamespaceType::Uts {
if let Some(host) = hostname {
nix::unistd::sethostname(host)?;
}
}
// Bind mount the new namespace from the current thread onto the mount point to persist it.

View File

@@ -2317,8 +2317,13 @@ async fn cdh_handler_trusted_storage(oci: &mut Spec) -> Result<()> {
for specdev in devices.iter() {
if specdev.path().as_path().to_str() == Some(TRUSTED_IMAGE_STORAGE_DEVICE) {
let dev_major_minor = format!("{}:{}", specdev.major(), specdev.minor());
cdh_secure_mount("BlockDevice", &dev_major_minor, "LUKS", KATA_IMAGE_WORK_DIR)
.await?;
cdh_secure_mount(
"block-device",
&dev_major_minor,
"luks2",
KATA_IMAGE_WORK_DIR,
)
.await?;
break;
}
}
@@ -2349,10 +2354,21 @@ pub(crate) async fn cdh_secure_mount(
let options = std::collections::HashMap::from([
("deviceId".to_string(), device_id.to_string()),
("encryptType".to_string(), encrypt_type.to_string()),
("sourceType".to_string(), "empty".to_string()),
("targetType".to_string(), "fileSystem".to_string()),
("filesystemType".to_string(), "ext4".to_string()),
("mkfsOpts".to_string(), "-E lazy_journal_init".to_string()),
("encryptionType".to_string(), encrypt_type.to_string()),
("dataIntegrity".to_string(), integrity),
]);
std::fs::create_dir_all(mount_point).inspect_err(|e| {
error!(
sl(),
"Failed to create mount point directory {}: {:?}", mount_point, e
);
})?;
confidential_data_hub::secure_mount(device_type, &options, vec![], mount_point).await?;
Ok(())

View File

@@ -59,7 +59,8 @@ async fn handle_block_storage(
.contains(&"encryption_key=ephemeral".to_string());
if has_ephemeral_encryption {
crate::rpc::cdh_secure_mount("BlockDevice", dev_num, "LUKS", &storage.mount_point).await?;
crate::rpc::cdh_secure_mount("block-device", dev_num, "luks2", &storage.mount_point)
.await?;
set_ownership(logger, storage)?;
new_device(storage.mount_point.clone())
} else {

View File

@@ -103,7 +103,7 @@ impl BrandString {
/// of the host CPU.
fn from_host_cpuid() -> Result<Self, Error> {
let mut this = Self::new();
let mut cpuid_regs = unsafe { host_cpuid(0x8000_0000) };
let mut cpuid_regs = host_cpuid(0x8000_0000);
if cpuid_regs.eax < 0x8000_0004 {
// Brand string not supported by the host CPU
@@ -111,7 +111,7 @@ impl BrandString {
}
for leaf in 0x8000_0002..=0x8000_0004 {
cpuid_regs = unsafe { host_cpuid(leaf) };
cpuid_regs = host_cpuid(leaf);
this.set_reg_for_leaf(leaf, Reg::Eax, cpuid_regs.eax);
this.set_reg_for_leaf(leaf, Reg::Ebx, cpuid_regs.ebx);
this.set_reg_for_leaf(leaf, Reg::Ecx, cpuid_regs.ecx);
@@ -393,7 +393,7 @@ mod tests {
match BrandString::from_host_cpuid() {
Ok(bstr) => {
for leaf in 0x8000_0002..=0x8000_0004_u32 {
let host_regs = unsafe { host_cpuid(leaf) };
let host_regs = host_cpuid(leaf);
assert_eq!(bstr.get_reg_for_leaf(leaf, Reg::Eax), host_regs.eax);
assert_eq!(bstr.get_reg_for_leaf(leaf, Reg::Ebx), host_regs.ebx);
assert_eq!(bstr.get_reg_for_leaf(leaf, Reg::Ecx), host_regs.ecx);
@@ -403,7 +403,7 @@ mod tests {
Err(Error::NotSupported) => {
// from_host_cpuid() should only fail if the host CPU doesn't support
// CPUID leaves up to 0x80000004, so let's make sure that's what happened.
let host_regs = unsafe { host_cpuid(0x8000_0000) };
let host_regs = host_cpuid(0x8000_0000);
assert!(host_regs.eax < 0x8000_0004);
}
_ => panic!("This function should not return another type of error"),

View File

@@ -25,7 +25,7 @@ pub fn get_cpuid(function: u32, count: u32) -> Result<CpuidResult, Error> {
// TODO: replace with validation based on `has_cpuid()` when it becomes stable:
// https://doc.rust-lang.org/core/arch/x86/fn.has_cpuid.html
// this is safe because the host supports the `cpuid` instruction
let max_function = unsafe { __get_cpuid_max(function & leaf_0x80000000::LEAF_NUM).0 };
let max_function = __get_cpuid_max(function & leaf_0x80000000::LEAF_NUM).0;
if function > max_function {
return Err(Error::InvalidParameters(format!(
"Function not supported: 0x{function:x}",
@@ -33,7 +33,7 @@ pub fn get_cpuid(function: u32, count: u32) -> Result<CpuidResult, Error> {
}
// this is safe because the host supports the `cpuid` instruction
let entry = unsafe { __cpuid_count(function, count) };
let entry = __cpuid_count(function, count);
if entry.eax == 0 && entry.ebx == 0 && entry.ecx == 0 && entry.edx == 0 {
return Err(Error::InvalidParameters(format!("Invalid count: {count}")));
}

View File

@@ -225,7 +225,7 @@ pub fn create_mount_destination<S: AsRef<Path>, D: AsRef<Path>, R: AsRef<Path>>(
/// Caller needs to ensure safety of the `dst` to avoid possible file path based attacks.
pub fn bind_remount<P: AsRef<Path>>(dst: P, readonly: bool) -> Result<()> {
let dst = dst.as_ref();
if dst.is_empty() {
if NixPath::is_empty(dst) {
return Err(Error::NullMountPointPath);
}
let dst = dst
@@ -262,10 +262,10 @@ pub fn bind_mount_unchecked<S: AsRef<Path>, D: AsRef<Path>>(
let src = src.as_ref();
let dst = dst.as_ref();
if src.is_empty() {
if NixPath::is_empty(src) {
return Err(Error::NullMountPointPath);
}
if dst.is_empty() {
if NixPath::is_empty(dst) {
return Err(Error::NullMountPointPath);
}
let abs_src = src
@@ -760,7 +760,7 @@ pub fn umount_timeout<P: AsRef<Path>>(path: P, timeout: u64) -> Result<()> {
/// # Safety
/// Caller needs to ensure safety of the `path` to avoid possible file path based attacks.
pub fn umount_all<P: AsRef<Path>>(mountpoint: P, lazy_umount: bool) -> Result<()> {
if mountpoint.as_ref().is_empty() || !mountpoint.as_ref().exists() {
if NixPath::is_empty(mountpoint.as_ref()) || !mountpoint.as_ref().exists() {
return Ok(());
}

View File

@@ -126,7 +126,7 @@ pub fn arch_guest_protection(
// shouldn't hurt to double-check and have better logging if anything
// goes wrong.
let fn0 = unsafe { x86_64::__cpuid(0) };
let fn0 = x86_64::__cpuid(0);
// The values in [ ebx, edx, ecx ] spell out "AuthenticAMD" when
// interpreted byte-wise as ASCII. No need to bother here with an
// actual conversion to string though.
@@ -139,7 +139,7 @@ pub fn arch_guest_protection(
}
// AMD64 Architecture Prgrammer's Manual Fn8000_001f docs on pg. 640
let fn8000_001f = unsafe { x86_64::__cpuid(0x8000_001f) };
let fn8000_001f = x86_64::__cpuid(0x8000_001f);
if fn8000_001f.eax & 0x10 == 0 {
return Err(ProtectionError::CheckFailed("SEV not supported".to_owned()));
}

View File

@@ -24,9 +24,7 @@ message SecureMountRequest {
string mount_point = 4;
}
message SecureMountResponse {
string mount_path = 1;
}
message SecureMountResponse {}
message ImagePullRequest {
// - `image_url`: The reference of the image to pull

View File

@@ -65,8 +65,6 @@ INITRDCONFIDENTIALNAME = $(PROJECT_TAG)-initrd-confidential.img
IMAGENAME_NV = $(PROJECT_TAG)-nvidia-gpu.img
IMAGENAME_CONFIDENTIAL_NV = $(PROJECT_TAG)-nvidia-gpu-confidential.img
INITRDNAME_NV = $(PROJECT_TAG)-initrd-nvidia-gpu.img
INITRDNAME_CONFIDENTIAL_NV = $(PROJECT_TAG)-initrd-nvidia-gpu-confidential.img
TARGET = $(BIN_PREFIX)-runtime
RUNTIME_OUTPUT = $(CURDIR)/$(TARGET)
@@ -136,8 +134,6 @@ INITRDCONFIDENTIALPATH := $(PKGDATADIR)/$(INITRDCONFIDENTIALNAME)
IMAGEPATH_NV := $(PKGDATADIR)/$(IMAGENAME_NV)
IMAGEPATH_CONFIDENTIAL_NV := $(PKGDATADIR)/$(IMAGENAME_CONFIDENTIAL_NV)
INITRDPATH_NV := $(PKGDATADIR)/$(INITRDNAME_NV)
INITRDPATH_CONFIDENTIAL_NV := $(PKGDATADIR)/$(INITRDNAME_CONFIDENTIAL_NV)
ROOTFSTYPE_EXT4 := \"ext4\"
ROOTFSTYPE_XFS := \"xfs\"
@@ -483,16 +479,12 @@ ifneq (,$(QEMUCMD))
KERNELPATH_CONFIDENTIAL_NV = $(KERNELDIR)/$(KERNELNAME_CONFIDENTIAL_NV)
DEFAULTVCPUS_NV = 1
DEFAULTMEMORY_NV = 2048
DEFAULTMEMORY_NV = 8192
DEFAULTTIMEOUT_NV = 1200
DEFAULTVFIOPORT_NV = root-port
DEFAULTPCIEROOTPORT_NV = 8
# Disable the devtmpfs mount in guest. NVRC does this, and later kata-agent
# attempts this as well in a non-failing manner. Otherwise, NVRC fails when
# using an image and /dev is already mounted.
KERNELPARAMS_NV = "cgroup_no_v1=all"
KERNELPARAMS_NV += "devtmpfs.mount=0"
KERNELPARAMS_NV += "pci=realloc"
KERNELPARAMS_NV += "pci=nocrs"
KERNELPARAMS_NV += "pci=assign-busses"
@@ -660,10 +652,6 @@ USER_VARS += IMAGENAME_NV
USER_VARS += IMAGENAME_CONFIDENTIAL_NV
USER_VARS += IMAGEPATH_NV
USER_VARS += IMAGEPATH_CONFIDENTIAL_NV
USER_VARS += INITRDNAME_NV
USER_VARS += INITRDNAME_CONFIDENTIAL_NV
USER_VARS += INITRDPATH_NV
USER_VARS += INITRDPATH_CONFIDENTIAL_NV
USER_VARS += KERNELNAME_NV
USER_VARS += KERNELPATH_NV
USER_VARS += KERNELNAME_CONFIDENTIAL_NV

View File

@@ -599,7 +599,7 @@ debug_console_enabled = false
# Agent connection dialing timeout value in seconds
# (default: 90)
dial_timeout = 90
dial_timeout = @DEFAULTTIMEOUT_NV@
[runtime]
# If enabled, the runtime will log additional debug messages to the

View File

@@ -576,7 +576,7 @@ debug_console_enabled = false
# Agent connection dialing timeout value in seconds
# (default: 90)
dial_timeout = 90
dial_timeout = @DEFAULTTIMEOUT_NV@
[runtime]
# If enabled, the runtime will log additional debug messages to the

View File

@@ -578,7 +578,7 @@ debug_console_enabled = false
# Agent connection dialing timeout value in seconds
# (default: 90)
dial_timeout = 90
dial_timeout = @DEFAULTTIMEOUT_NV@
[runtime]
# If enabled, the runtime will log additional debug messages to the

View File

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

View File

@@ -72,7 +72,7 @@ func IsPCIeDevice(bdf string) bool {
}
// read from /sys/bus/pci/devices/xxx/property
func getPCIDeviceProperty(bdf string, property PCISysFsProperty) string {
func GetPCIDeviceProperty(bdf string, property PCISysFsProperty) string {
if len(strings.Split(bdf, ":")) == 2 {
bdf = PCIDomain + ":" + bdf
}
@@ -220,9 +220,9 @@ func GetDeviceFromVFIODev(device config.DeviceInfo) ([]*config.VFIODev, error) {
return nil, err
}
vendorID := getPCIDeviceProperty(deviceBDF, PCISysFsDevicesVendor)
deviceID := getPCIDeviceProperty(deviceBDF, PCISysFsDevicesDevice)
pciClass := getPCIDeviceProperty(deviceBDF, PCISysFsDevicesClass)
vendorID := GetPCIDeviceProperty(deviceBDF, PCISysFsDevicesVendor)
deviceID := GetPCIDeviceProperty(deviceBDF, PCISysFsDevicesDevice)
pciClass := GetPCIDeviceProperty(deviceBDF, PCISysFsDevicesClass)
i, err := extractIndex(device.HostPath)
if err != nil {
@@ -276,7 +276,7 @@ func GetAllVFIODevicesFromIOMMUGroup(device config.DeviceInfo) ([]*config.VFIODe
switch vfioDeviceType {
case config.VFIOPCIDeviceNormalType, config.VFIOPCIDeviceMediatedType:
// This is vfio-pci and vfio-mdev specific
pciClass := getPCIDeviceProperty(deviceBDF, PCISysFsDevicesClass)
pciClass := GetPCIDeviceProperty(deviceBDF, PCISysFsDevicesClass)
// We need to ignore Host or PCI Bridges that are in the same IOMMU group as the
// passed-through devices. One CANNOT pass-through a PCI bridge or Host bridge.
// Class 0x0604 is PCI bridge, 0x0600 is Host bridge
@@ -288,8 +288,8 @@ func GetAllVFIODevicesFromIOMMUGroup(device config.DeviceInfo) ([]*config.VFIODe
continue
}
// Fetch the PCI Vendor ID and Device ID
vendorID := getPCIDeviceProperty(deviceBDF, PCISysFsDevicesVendor)
deviceID := getPCIDeviceProperty(deviceBDF, PCISysFsDevicesDevice)
vendorID := GetPCIDeviceProperty(deviceBDF, PCISysFsDevicesVendor)
deviceID := GetPCIDeviceProperty(deviceBDF, PCISysFsDevicesDevice)
// Do not directly assign to `vfio` -- need to access field still
vfio = config.VFIODev{

View File

@@ -7,6 +7,7 @@ package virtcontainers
import (
"context"
"errors"
"fmt"
"io"
"os"
@@ -1135,7 +1136,9 @@ func (c *Container) createDevices(ctx context.Context, contConfig *ContainerConf
// If we're hot-plugging this will be a no-op because at this stage
// no devices are attached to the root-port or switch-port
c.annotateContainerWithVFIOMetadata(vfioColdPlugDevices)
if err := c.annotateContainerWithVFIOMetadata(vfioColdPlugDevices); err != nil {
return err
}
return nil
}
@@ -1194,11 +1197,40 @@ func sortContainerVFIODevices(devices []config.DeviceInfo) []config.DeviceInfo {
return vfioDevices
}
// errNoSiblingFound is returned by siblingAnnotation when the VFIO device is
// not of a supported CDI device type, i.e. it has no entry in the cdiDeviceKind
// table (e.g. NVSwitches). Callers should treat this as a non-fatal "device not
// applicable" condition rather than a sibling-matching failure.
var errNoSiblingFound = fmt.Errorf("no suitable sibling found")
// cdiDeviceKey identifies a device type by vendor ID and PCI class prefix.
type cdiDeviceKey struct {
VendorID string
ClassPrefix string
}
// cdiDeviceKind maps known device types to their CDI annotation kind.
var cdiDeviceKind = map[cdiDeviceKey]string{
{VendorID: "0x10de", ClassPrefix: "0x030"}: "nvidia.com/gpu",
}
// cdiKindForDevice returns the CDI kind for a given vendor ID and PCI class,
// or empty string and false if the device is not recognized.
func cdiKindForDevice(vendorID, class string) (string, bool) {
for key, kind := range cdiDeviceKind {
if vendorID == key.VendorID && strings.Contains(class, key.ClassPrefix) {
return kind, true
}
}
return "", false
}
type DeviceRelation struct {
Bus string
Path string
Index int
BDF string
Bus string
Path string
Index int
BDF string
CDIKind string
}
// Depending on the HW we might need to inject metadata into the container
@@ -1223,15 +1255,13 @@ func (c *Container) annotateContainerWithVFIOMetadata(devices interface{}) error
// so lets first iterate over all root-port devices and then
// switch-port devices no special handling for bridge-port (PCI)
for _, dev := range config.PCIeDevicesPerPort["root-port"] {
// For the NV GPU we need special handling let's use only those
if dev.VendorID == "0x10de" && strings.Contains(dev.Class, "0x030") {
siblings = append(siblings, DeviceRelation{Bus: dev.Bus, Path: dev.HostPath, BDF: dev.BDF})
if kind, ok := cdiKindForDevice(dev.VendorID, dev.Class); ok {
siblings = append(siblings, DeviceRelation{Bus: dev.Bus, Path: dev.HostPath, BDF: dev.BDF, CDIKind: kind})
}
}
for _, dev := range config.PCIeDevicesPerPort["switch-port"] {
// For the NV GPU we need special handling let's use only those
if dev.VendorID == "0x10de" && strings.Contains(dev.Class, "0x030") {
siblings = append(siblings, DeviceRelation{Bus: dev.Bus, Path: dev.HostPath, BDF: dev.BDF})
if kind, ok := cdiKindForDevice(dev.VendorID, dev.Class); ok {
siblings = append(siblings, DeviceRelation{Bus: dev.Bus, Path: dev.HostPath, BDF: dev.BDF, CDIKind: kind})
}
}
// We need to sort the VFIO devices by bus to get the correct
@@ -1244,48 +1274,53 @@ func (c *Container) annotateContainerWithVFIOMetadata(devices interface{}) error
siblings[i].Index = i
}
// Now that we have the index lets connect the /dev/vfio/<num>
// to the correct index
if devices, ok := devices.([]ContainerDevice); ok {
for _, dev := range devices {
if dev.ContainerPath == "/dev/vfio/vfio" {
c.Logger().Infof("skipping /dev/vfio/vfio for vfio_mode=guest-kernel")
continue
}
err := c.siblingAnnotation(dev.ContainerPath, siblings)
if err != nil {
return err
}
// Collect container paths from either hot-plug or cold-plug devices
var containerPaths []string
if devs, ok := devices.([]ContainerDevice); ok {
for _, dev := range devs {
containerPaths = append(containerPaths, dev.ContainerPath)
}
}
if devs, ok := devices.([]config.DeviceInfo); ok {
for _, dev := range devs {
containerPaths = append(containerPaths, dev.ContainerPath)
}
}
if devices, ok := devices.([]config.DeviceInfo); ok {
for _, dev := range devices {
if dev.ContainerPath == "/dev/vfio/vfio" {
c.Logger().Infof("skipping /dev/vfio/vfio for vfio_mode=guest-kernel")
// Now that we have the index lets connect the /dev/vfio/<num>
// to the correct index
for _, devPath := range containerPaths {
if !strings.HasPrefix(devPath, "/dev/vfio") {
c.Logger().Infof("skipping guest annotations for non-VFIO device %q", devPath)
continue
}
if devPath == "/dev/vfio/vfio" {
c.Logger().Infof("skipping /dev/vfio/vfio for vfio_mode=guest-kernel")
continue
}
if err := c.siblingAnnotation(devPath, siblings); err != nil {
if errors.Is(err, errNoSiblingFound) {
c.Logger().Infof("no CDI annotation for device %s (not a known CDI device type)", devPath)
continue
}
err := c.siblingAnnotation(dev.ContainerPath, siblings)
if err != nil {
return err
}
return err
}
}
}
return nil
}
// createCDIAnnotation adds a container annotation mapping a VFIO device to a GPU index.
// createCDIAnnotation adds a container annotation mapping a VFIO device to a device index.
//
// devPath is the path to the VFIO device, which can be in the format
// "/dev/vfio/<num>" or "/dev/vfio/devices/vfio<num>". The function extracts
// the device number from the path and creates an annotation with the key
// "cdi.k8s.io/vfio<num>" and the value "nvidia.com/gpu=<index>", where
// <num> is the device number and <index> is the provided GPU index.
// "cdi.k8s.io/vfio<num>" and the value "<cdiKind>=<index>", where
// <cdiKind> is the CDI device kind (e.g. "nvidia.com/gpu"),
// <num> is the device number and <index> is the provided device index.
// The annotation is stored in c.config.CustomSpec.Annotations.
func (c *Container) createCDIAnnotation(devPath string, index int) {
func (c *Container) createCDIAnnotation(devPath string, index int, cdiKind string) {
// We have here either /dev/vfio/<num> or /dev/vfio/devices/vfio<num>
baseName := filepath.Base(devPath)
vfioNum := baseName
@@ -1294,66 +1329,68 @@ func (c *Container) createCDIAnnotation(devPath string, index int) {
vfioNum = strings.TrimPrefix(baseName, "vfio")
}
annoKey := fmt.Sprintf("cdi.k8s.io/vfio%s", vfioNum)
annoValue := fmt.Sprintf("nvidia.com/gpu=%d", index)
annoValue := fmt.Sprintf("%s=%d", cdiKind, index)
if c.config.CustomSpec.Annotations == nil {
c.config.CustomSpec.Annotations = make(map[string]string)
}
c.config.CustomSpec.Annotations[annoKey] = annoValue
c.Logger().Infof("annotated container with %s: %s", annoKey, annoValue)
}
func (c *Container) siblingAnnotation(devPath string, siblings []DeviceRelation) error {
for _, sibling := range siblings {
if sibling.Path == devPath {
c.createCDIAnnotation(devPath, sibling.Index)
return nil
// Resolve the device's BDFs once upfront. This serves two purposes:
// 1. Determine if the device is a known CDI type (if not, skip it)
// 2. Reuse the BDFs for sibling matching without redundant sysfs reads
isKnownCDIDevice := false
var devBDFs []string
if strings.HasPrefix(filepath.Base(devPath), "vfio") {
// IOMMUFD device (/dev/vfio/devices/vfio<NUM>): single device per char dev
major, minor, err := deviceUtils.GetMajorMinorFromDevPath(devPath)
if err != nil {
return err
}
// If the sandbox has cold-plugged an IOMMUFD device and if the
// device-plugins sends us a /dev/vfio/<NUM> device we need to
// check if the IOMMUFD device and the VFIO device are the same
// We have the sibling.BDF we now need to extract the BDF of the
// devPath that is either /dev/vfio/<NUM> or
// /dev/vfio/devices/vfio<NUM>
if strings.HasPrefix(filepath.Base(devPath), "vfio") {
// IOMMUFD device format (/dev/vfio/devices/vfio<NUM>), extract BDF from sysfs
major, minor, err := deviceUtils.GetMajorMinorFromDevPath(devPath)
if err != nil {
return err
}
iommufdBDF, err := deviceUtils.GetBDFFromVFIODev(major, minor)
if err != nil {
return err
}
if sibling.BDF == iommufdBDF {
c.createCDIAnnotation(devPath, sibling.Index)
// exit handling IOMMUFD device
return nil
}
bdf, err := deviceUtils.GetBDFFromVFIODev(major, minor)
if err != nil {
return err
}
// Legacy VFIO group device (/dev/vfio/<GROUP_NUM>), extract BDF from sysfs
devBDFs = []string{bdf}
vendorID := deviceUtils.GetPCIDeviceProperty(bdf, deviceUtils.PCISysFsDevicesVendor)
class := deviceUtils.GetPCIDeviceProperty(bdf, deviceUtils.PCISysFsDevicesClass)
_, isKnownCDIDevice = cdiKindForDevice(vendorID, class)
} else {
// Legacy VFIO group (/dev/vfio/<GROUP>): may contain multiple devices
vfioGroup := filepath.Base(devPath)
iommuDevicesPath := filepath.Join(config.SysIOMMUGroupPath, vfioGroup, "devices")
deviceFiles, err := os.ReadDir(iommuDevicesPath)
if err != nil {
return err
}
vfioBDFs := make([]string, 0)
for _, deviceFile := range deviceFiles {
// Get bdf of device eg 0000:00:1c.0
deviceBDF, _, _, err := deviceUtils.GetVFIODetails(deviceFile.Name(), iommuDevicesPath)
if err != nil {
return err
}
vfioBDFs = append(vfioBDFs, deviceBDF)
devBDFs = append(devBDFs, deviceBDF)
if !isKnownCDIDevice {
vendorID := deviceUtils.GetPCIDeviceProperty(deviceBDF, deviceUtils.PCISysFsDevicesVendor)
class := deviceUtils.GetPCIDeviceProperty(deviceBDF, deviceUtils.PCISysFsDevicesClass)
if _, ok := cdiKindForDevice(vendorID, class); ok {
isKnownCDIDevice = true
}
}
}
if slices.Contains(vfioBDFs, sibling.BDF) {
c.createCDIAnnotation(devPath, sibling.Index)
// exit handling legacy VFIO device
}
if !isKnownCDIDevice {
return fmt.Errorf("device %s: %w", devPath, errNoSiblingFound)
}
for _, sibling := range siblings {
if sibling.Path == devPath || slices.Contains(devBDFs, sibling.BDF) {
c.createCDIAnnotation(devPath, sibling.Index, sibling.CDIKind)
return nil
}
}
return fmt.Errorf("failed to match device %s with any cold-plugged GPU device by path or BDF; no suitable sibling found", devPath)
return fmt.Errorf("device %s is a known CDI device type but failed to match any sibling by path or BDF", devPath)
}
// create creates and starts a container inside a Sandbox. It has to be
@@ -1382,7 +1419,9 @@ func (c *Container) create(ctx context.Context) (err error) {
return
}
c.annotateContainerWithVFIOMetadata(c.devices)
if err := c.annotateContainerWithVFIOMetadata(c.devices); err != nil {
return fmt.Errorf("annotating VFIO devices: %w", err)
}
// Deduce additional system mount info that should be handled by the agent
// inside the VM

View File

@@ -841,7 +841,6 @@ func (q *qemu) createPCIeTopology(qemuConfig *govmmQemu.Config, hypervisorConfig
// /dev/vfio/devices/vfio0
// (1) Check if we have the new IOMMUFD or old container based VFIO
if strings.HasPrefix(dev.HostPath, pkgDevice.IommufdDevPath) {
q.Logger().Infof("### IOMMUFD Path: %s", dev.HostPath)
vfioDevices, err = drivers.GetDeviceFromVFIODev(dev)
if err != nil {
return fmt.Errorf("Cannot get VFIO device from IOMMUFD with device: %v err: %v", dev, err)

View File

@@ -173,7 +173,7 @@
"encryption_key=ephemeral"
],
"source": "",
"mount_point": "^$(spath)/$(b64_device_id)$",
"mount_point": "$(spath)/$(b64_device_id)",
"fstype": "ext4",
"options": [],
"shared": true

View File

@@ -1306,6 +1306,7 @@ allow_storage_source(p_storage, i_storage, bundle_id) if {
allow_storage_options(p_storage, i_storage) if {
print("allow_storage_options 1: start")
p_storage.driver != "blk"
p_storage.driver != "overlayfs"
p_storage.options == i_storage.options
@@ -1389,7 +1390,7 @@ allow_mount_point_by_device_id(p_storage, i_storage) if {
mount3 := replace(mount2, "$(b64_device_id)", base64url.encode(i_storage.source))
print("allow_mount_point_by_device_id: mount3 =", mount3)
regex.match(mount3, i_storage.mount_point)
mount3 == i_storage.mount_point
print("allow_mount_point_by_device_id: true")
}

View File

@@ -168,10 +168,10 @@ fn get_empty_dir_mount_and_storage(
source: settings_empty_dir.source.clone(),
fstype: settings_empty_dir.fstype.clone(),
options,
mount_point: if settings_empty_dir.mount_point.ends_with('$') {
settings_empty_dir.mount_point.clone()
} else {
mount_point: if settings_empty_dir.mount_point.ends_with('/') {
format!("{}{}$", &settings_empty_dir.mount_point, &yaml_mount.name)
} else {
settings_empty_dir.mount_point.clone()
},
fs_group: protobuf::MessageField::none(),
shared: settings_empty_dir.shared,

View File

@@ -1232,9 +1232,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.29"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
"futures-sink",
@@ -1242,9 +1242,9 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
@@ -1259,9 +1259,9 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.29"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
name = "futures-lite"
@@ -1278,9 +1278,9 @@ dependencies = [
[[package]]
name = "futures-macro"
version = "0.3.29"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
@@ -1289,21 +1289,27 @@ dependencies = [
[[package]]
name = "futures-sink"
version = "0.3.29"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]]
name = "futures-task"
version = "0.3.29"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-timer"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"
[[package]]
name = "futures-util"
version = "0.3.29"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-channel",
"futures-core",
@@ -1313,7 +1319,6 @@ dependencies = [
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
@@ -1885,6 +1890,7 @@ dependencies = [
"quick-xml",
"reqwest",
"ron",
"rstest",
"semver",
"serde",
"serde_json",
@@ -3144,6 +3150,12 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "relative-path"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2"
[[package]]
name = "rend"
version = "0.4.2"
@@ -3292,6 +3304,35 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "rstest"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49"
dependencies = [
"futures-timer",
"futures-util",
"rstest_macros",
]
[[package]]
name = "rstest_macros"
version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0"
dependencies = [
"cfg-if 1.0.0",
"glob",
"proc-macro-crate",
"proc-macro2",
"quote",
"regex",
"relative-path",
"rustc_version",
"syn 2.0.87",
"unicode-ident",
]
[[package]]
name = "rtnetlink"
version = "0.19.0"
@@ -3351,6 +3392,15 @@ version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.25"
@@ -4414,9 +4464,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.12"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "unicode-segmentation"

View File

@@ -57,6 +57,7 @@ quick-xml = { version = "0.28", features = ["serialize"] }
csv = "1.2"
serde_with = "2.3"
chrono = { version = "0.4", features = ["serde"] }
rstest = "0.26.1"
[target.'cfg(target_arch = "s390x")'.dependencies]
reqwest = { version = "0.11", default-features = false, features = [

View File

@@ -78,10 +78,9 @@ pub enum Commands {
}
#[derive(Debug, Args, Error)]
#[error("Argument is not valid")]
#[error("Argument is not valid: {command:?}")]
pub struct CheckArgument {
#[clap(subcommand)]
#[allow(unused_assignments)]
pub command: CheckSubCommand,
}

View File

@@ -157,10 +157,12 @@ pub fn get_sandbox_id_for_volume(volume_path: &str) -> Result<String> {
#[cfg(test)]
mod tests {
use super::*;
use anyhow::anyhow;
use kata_types::mount::DirectVolumeMountInfo;
use rstest::{fixture, rstest};
use serial_test::serial;
use std::{collections::HashMap, fs, path::PathBuf};
use tempfile::tempdir;
use std::{collections::HashMap, fs};
use tempfile::{tempdir, TempDir};
use test_utils::skip_if_not_root;
#[test]
@@ -195,61 +197,38 @@ mod tests {
fs::remove_dir_all(&joined_volume_path).expect("failed to cleanup test")
}
#[test]
fn test_path_join() {
#[derive(Debug)]
struct TestData<'a> {
rootfs: &'a str,
volume_path: &'a str,
result: Result<PathBuf>,
}
// the safe_path::scoped_join requires the prefix path to exist on testing machine
let root_fs = tempdir().expect("failed to create tmpdir").into_path();
let root_fs_str = root_fs.to_str().unwrap();
#[fixture]
fn root_fs() -> TempDir {
tempdir().expect("failed to create tmpdir")
}
let relative_secret_path = "../../etc/passwd";
let b64_relative_secret_path =
base64::encode_config(relative_secret_path, base64::URL_SAFE);
#[rstest]
#[case::relative_secret_path("../../etc/passwd", "Li4vLi4vZXRjL3Bhc3N3ZA==")] // "Li4vLi4vZXRjL3Bhc3N3ZA==" is b64 encoded url of "../../etc/passwd"
#[case::byte_array_path("abcdddd", "YWJjZGRkZA==")] // "YWJjZGRkZA==" is the b64 url encoded string of "abcdddd"
fn test_path_join(
root_fs: TempDir,
#[case] volume_path: &str,
#[case] expected_encoded_path: &str,
) {
let root_str = root_fs.path().to_str().unwrap();
// byte array of "abcdddd"
let b64_abs_path = vec![97, 98, 99, 100, 100, 100, 100];
// b64urlencoded string of "abcdddd"
let b64urlencodes_relative_path = "YWJjZGRkZA==";
let result = join_path(root_str, volume_path).expect("Should return Ok for valid paths");
let tests = &[
TestData {
rootfs: root_fs_str,
volume_path: "",
result: Err(anyhow!(std::io::ErrorKind::NotFound)),
},
TestData {
rootfs: root_fs_str,
volume_path: relative_secret_path,
result: Ok(root_fs.join(b64_relative_secret_path)),
},
TestData {
rootfs: root_fs_str,
volume_path: unsafe { std::str::from_utf8_unchecked(&b64_abs_path) },
result: Ok(root_fs.join(b64urlencodes_relative_path)),
},
];
let expected = root_fs.path().join(expected_encoded_path);
assert_eq!(result, expected);
}
for (i, d) in tests.iter().enumerate() {
let msg = format!("test[{i}]: {d:?}");
let result = join_path(d.rootfs, d.volume_path);
let msg = format!("{msg}, result: {result:?}");
if result.is_ok() {
assert!(
result.as_ref().unwrap() == d.result.as_ref().unwrap(),
"{}",
msg
);
continue;
}
let expected_error = format!("{}", d.result.as_ref().unwrap_err());
let actual_error = format!("{}", result.unwrap_err());
assert!(actual_error == expected_error, "{}", msg);
}
#[rstest]
fn test_path_join_empty_path_error(root_fs: TempDir) {
let root_str = root_fs.path().to_str().unwrap();
let result = join_path(root_str, "");
let err = result.expect_err("Should fail for empty volume_path");
assert_eq!(
err.to_string(),
anyhow!(std::io::ErrorKind::NotFound).to_string()
);
}
#[test]

View File

@@ -237,6 +237,60 @@ function create_coco_pod_yaml_with_annotations() {
fi
}
# Sealed secrets (signed JWS ES256). Pre-created with guest-components secret CLI; see
# https://github.com/confidential-containers/guest-components/blob/main/confidential-data-hub/docs/SEALED_SECRET.md
# Tests provision the signing public key to KBS and use these pre-created sealed secret strings.
#
# To regenerate the signing key and sealed secrets:
# Install required dependencies, clone guest-components repository and change to guest-components/confidential-data-hub
# Create private and public JWK, for example:
# python3 -c "
# from jwcrypto import jwk
# k = jwk.JWK.generate(kty='EC', crv='P-256', alg='ES256', use='sig', kid='sealed-secret-test-key')
# with open('signing-key-private.jwk', 'w') as f:
# f.write(k.export_private())
# with open('signing-key-public.jwk', 'w') as f:
# f.write(k.export_public())
# print('Created signing-key-private.jwk and signing-key-public.jwk')
# "
#
# Build the secret CLI:
# cargo build -p confidential-data-hub --bin secret
#
# Create the sealed secret test secret:
# cargo run -p confidential-data-hub --bin secret -q -- seal \
# --signing-kid "kbs:///default/signing-key/sealed-secret" \
# --signing-jwk-path ./signing-key-private.jwk \
# vault --resource-uri "kbs:///default/sealed-secret/test" --provider kbs
#
# Create the NIM test instruct secret:
# cargo run -p confidential-data-hub --bin secret -q -- seal \
# --signing-kid "kbs:///default/signing-key/sealed-secret" \
# --signing-jwk-path ./signing-key-private.jwk \
# vault --resource-uri "kbs:///default/ngc-api-key/instruct" --provider kbs
#
# Create the NIM test embedqa secret:
# cargo run -p confidential-data-hub --bin secret -q -- seal \
# --signing-kid "kbs:///default/signing-key/sealed-secret" \
# --signing-jwk-path ./signing-key-private.jwk \
# vault --resource-uri "kbs:///default/ngc-api-key/embedqa" --provider kbs
#
# Public JWK (no private key) used to verify the pre-created sealed secrets. Must match the key pair
# that was used to sign SEALED_SECRET_PRECREATED_*.
SEALED_SECRET_SIGNING_PUBLIC_JWK='{"alg":"ES256","crv":"P-256","kid":"sealed-secret-test-key","kty":"EC","use":"sig","x":"4jH376AuwTUCIx65AJ_56D7SZzWf7sGcEA7_Csq21UM","y":"rjdceysnSa5ZfzWOPGCURMUuHndxBAGUu4ISTIVN0yA"}'
# Pre-created sealed secret for k8s-sealed-secret.bats (points to kbs:///default/sealed-secret/test)
export SEALED_SECRET_PRECREATED_TEST="sealed.eyJiNjQiOnRydWUsImFsZyI6IkVTMjU2Iiwia2lkIjoia2JzOi8vL2RlZmF1bHQvc2lnbmluZy1rZXkvc2VhbGVkLXNlY3JldCJ9.eyJ2ZXJzaW9uIjoiMC4xLjAiLCJ0eXBlIjoidmF1bHQiLCJuYW1lIjoia2JzOi8vL2RlZmF1bHQvc2VhbGVkLXNlY3JldC90ZXN0IiwicHJvdmlkZXIiOiJrYnMiLCJwcm92aWRlcl9zZXR0aW5ncyI6e30sImFubm90YXRpb25zIjp7fX0.ZI2fTv5ramHqHQa9DKBFD5hlJ_Mjf6cEIcpsNGshpyhEiKklML0abfH600TD7LAFHf53oDIJmEcVsDtJ20UafQ"
# Pre-created sealed secrets for k8s-nvidia-nim.bats (point to kbs:///default/ngc-api-key/instruct and embedqa)
export SEALED_SECRET_PRECREATED_NIM_INSTRUCT="sealed.eyJiNjQiOnRydWUsImFsZyI6IkVTMjU2Iiwia2lkIjoia2JzOi8vL2RlZmF1bHQvc2lnbmluZy1rZXkvc2VhbGVkLXNlY3JldCJ9.eyJ2ZXJzaW9uIjoiMC4xLjAiLCJ0eXBlIjoidmF1bHQiLCJuYW1lIjoia2JzOi8vL2RlZmF1bHQvbmdjLWFwaS1rZXkvaW5zdHJ1Y3QiLCJwcm92aWRlciI6ImticyIsInByb3ZpZGVyX3NldHRpbmdzIjp7fSwiYW5ub3RhdGlvbnMiOnt9fQ.wpqvVFUaQymqgf54h70shZWDpk2NLW305wALz09YF0GKFBKBQiQB2sRwvn9Jk_rSju3YGLYxPO2Ub8qUbiMCuA"
export SEALED_SECRET_PRECREATED_NIM_EMBEDQA="sealed.eyJiNjQiOnRydWUsImFsZyI6IkVTMjU2Iiwia2lkIjoia2JzOi8vL2RlZmF1bHQvc2lnbmluZy1rZXkvc2VhbGVkLXNlY3JldCJ9.eyJ2ZXJzaW9uIjoiMC4xLjAiLCJ0eXBlIjoidmF1bHQiLCJuYW1lIjoia2JzOi8vL2RlZmF1bHQvbmdjLWFwaS1rZXkvZW1iZWRxYSIsInByb3ZpZGVyIjoia2JzIiwicHJvdmlkZXJfc2V0dGluZ3MiOnt9LCJhbm5vdGF0aW9ucyI6e319.4C1uqtVXi_qZT8vh_yZ4KpsRdgr2s4hU6ElKj18Hq1DJi_Iji61yuKsS6S1jWdb7drdoKKACvMD6RmCd85SJOQ"
# Provision the signing public key to KBS so CDH can verify the pre-created sealed secrets.
function setup_sealed_secret_signing_public_key() {
kbs_set_resource "default" "signing-key" "sealed-secret" "${SEALED_SECRET_SIGNING_PUBLIC_JWK}"
}
function get_initdata_with_cdh_image_section() {
CDH_IMAGE_SECTION=${1:-""}

View File

@@ -588,7 +588,6 @@ function main() {
install-kata-tools) install_kata_tools "${2:-}" ;;
install-kbs-client) install_kbs_client ;;
get-cluster-credentials) get_cluster_credentials ;;
deploy-csi-driver) return 0 ;;
deploy-kata) deploy_kata ;;
deploy-kata-aks) deploy_kata "aks" ;;
deploy-kata-kcli) deploy_kata "kcli" ;;
@@ -613,7 +612,6 @@ function main() {
cleanup-garm) cleanup "garm" ;;
cleanup-zvsi) cleanup "zvsi" ;;
cleanup-snapshotter) cleanup_snapshotter ;;
delete-csi-driver) return 0 ;;
delete-coco-kbs) delete_coco_kbs ;;
delete-cluster) cleanup "aks" ;;
delete-cluster-kcli) delete_cluster_kcli ;;

View File

@@ -54,27 +54,8 @@ NGC_API_KEY_BASE64=$(
)
export NGC_API_KEY_BASE64
# Sealed secret format for TEE pods (vault type pointing to KBS resource)
# Format: sealed.<base64url JWS header>.<base64url payload>.<base64url signature>
# IMPORTANT: JWS uses base64url encoding WITHOUT padding (no trailing '=')
# We use tr to convert standard base64 (+/) to base64url (-_) and remove padding (=)
# For vault type, header and signature can be placeholders since the payload
# contains the KBS resource path where the actual secret is stored.
#
# Vault type sealed secret payload for instruct pod:
# {
# "version": "0.1.0",
# "type": "vault",
# "name": "kbs:///default/ngc-api-key/instruct",
# "provider": "kbs",
# "provider_settings": {},
# "annotations": {}
# }
NGC_API_KEY_SEALED_SECRET_INSTRUCT_PAYLOAD=$(
echo -n '{"version":"0.1.0","type":"vault","name":"kbs:///default/ngc-api-key/instruct","provider":"kbs","provider_settings":{},"annotations":{}}' |
base64 -w0 | tr '+/' '-_' | tr -d '='
)
NGC_API_KEY_SEALED_SECRET_INSTRUCT="sealed.fakejwsheader.${NGC_API_KEY_SEALED_SECRET_INSTRUCT_PAYLOAD}.fakesignature"
# pre-created signed sealed secrets for TEE pods (from confidential_common.sh)
NGC_API_KEY_SEALED_SECRET_INSTRUCT="${SEALED_SECRET_PRECREATED_NIM_INSTRUCT}"
export NGC_API_KEY_SEALED_SECRET_INSTRUCT
# Base64 encode the sealed secret for use in Kubernetes Secret data field
@@ -82,20 +63,7 @@ export NGC_API_KEY_SEALED_SECRET_INSTRUCT
NGC_API_KEY_SEALED_SECRET_INSTRUCT_BASE64=$(echo -n "${NGC_API_KEY_SEALED_SECRET_INSTRUCT}" | base64 -w0)
export NGC_API_KEY_SEALED_SECRET_INSTRUCT_BASE64
# Vault type sealed secret payload for embedqa pod:
# {
# "version": "0.1.0",
# "type": "vault",
# "name": "kbs:///default/ngc-api-key/embedqa",
# "provider": "kbs",
# "provider_settings": {},
# "annotations": {}
# }
NGC_API_KEY_SEALED_SECRET_EMBEDQA_PAYLOAD=$(
echo -n '{"version":"0.1.0","type":"vault","name":"kbs:///default/ngc-api-key/embedqa","provider":"kbs","provider_settings":{},"annotations":{}}' |
base64 -w0 | tr '+/' '-_' | tr -d '='
)
NGC_API_KEY_SEALED_SECRET_EMBEDQA="sealed.fakejwsheader.${NGC_API_KEY_SEALED_SECRET_EMBEDQA_PAYLOAD}.fakesignature"
NGC_API_KEY_SEALED_SECRET_EMBEDQA="${SEALED_SECRET_PRECREATED_NIM_EMBEDQA}"
export NGC_API_KEY_SEALED_SECRET_EMBEDQA
NGC_API_KEY_SEALED_SECRET_EMBEDQA_BASE64=$(echo -n "${NGC_API_KEY_SEALED_SECRET_EMBEDQA}" | base64 -w0)
@@ -113,27 +81,6 @@ setup_langchain_flow() {
[[ "$(pip show beautifulsoup4 2>/dev/null | awk '/^Version:/{print $2}')" = "4.13.4" ]] || pip install beautifulsoup4==4.13.4
}
# Create Docker config for genpolicy so it can authenticate to nvcr.io when
# pulling image manifests (avoids "UnauthorizedError" from genpolicy's registry pull).
# Genpolicy (src/tools/genpolicy) uses docker_credential::get_credential() in
# src/tools/genpolicy/src/registry.rs build_auth(). The docker_credential crate
# reads config from DOCKER_CONFIG (directory) + "/config.json", so we set
# DOCKER_CONFIG to a directory containing config.json with nvcr.io auth.
setup_genpolicy_registry_auth() {
if [[ -z "${NGC_API_KEY:-}" ]]; then
return
fi
local auth_dir
auth_dir="${BATS_SUITE_TMPDIR}/.docker-genpolicy"
mkdir -p "${auth_dir}"
# Docker config format: auths -> registry -> auth (base64 of "user:password")
echo -n "{\"auths\":{\"nvcr.io\":{\"username\":\"\$oauthtoken\",\"password\":\"${NGC_API_KEY}\",\"auth\":\"$(echo -n "\$oauthtoken:${NGC_API_KEY}" | base64 -w0)\"}}}" \
> "${auth_dir}/config.json"
export DOCKER_CONFIG="${auth_dir}"
# REGISTRY_AUTH_FILE (containers-auth.json format) is the same structure for auths
export REGISTRY_AUTH_FILE="${auth_dir}/config.json"
}
# Create initdata TOML file for genpolicy with CDH configuration.
# This file is used by genpolicy via --initdata-path. Genpolicy will add the
# generated policy.rego to it and set it as the cc_init_data annotation.
@@ -243,10 +190,9 @@ setup_file() {
add_requests_to_policy_settings "${policy_settings_dir}" "ReadStreamRequest"
if [ "${TEE}" = "true" ]; then
# So genpolicy can pull nvcr.io image manifests when generating policy (avoids UnauthorizedError).
setup_genpolicy_registry_auth
setup_kbs_credentials
# provision signing public key to KBS so that CDH can verify pre-created, signed secret.
setup_sealed_secret_signing_public_key
# Overwrite the empty default-initdata.toml with our CDH configuration.
# This must happen AFTER create_tmp_policy_settings_dir() copies the empty
# file and BEFORE auto_generate_policy() runs.

View File

@@ -48,25 +48,13 @@ setup() {
"${kernel_params_annotation}" \
"${kernel_params_value}"
# provision signing public key to KBS so that CDH can verify pre-created, signed secret.
setup_sealed_secret_signing_public_key
# Setup k8s secret
kubectl delete secret sealed-secret --ignore-not-found
kubectl delete secret not-sealed-secret --ignore-not-found
# Sealed secret format is defined at: https://github.com/confidential-containers/guest-components/blob/main/confidential-data-hub/docs/SEALED_SECRET.md#vault
# sealed.BASE64URL(UTF8(JWS Protected Header)) || '.
# || BASE64URL(JWS Payload) || '.'
# || BASE64URL(JWS Signature)
# test payload:
# {
# "version": "0.1.0",
# "type": "vault",
# "name": "kbs:///default/sealed-secret/test",
# "provider": "kbs",
# "provider_settings": {},
# "annotations": {}
# }
kubectl create secret generic sealed-secret --from-literal='secret=sealed.fakejwsheader.eyJ2ZXJzaW9uIjoiMC4xLjAiLCJ0eXBlIjoidmF1bHQiLCJuYW1lIjoia2JzOi8vL2RlZmF1bHQvc2VhbGVkLXNlY3JldC90ZXN0IiwicHJvdmlkZXIiOiJrYnMiLCJwcm92aWRlcl9zZXR0aW5ncyI6e30sImFubm90YXRpb25zIjp7fX0.fakesignature'
kubectl create secret generic sealed-secret --from-literal="secret=${SEALED_SECRET_PRECREATED_TEST}"
kubectl create secret generic not-sealed-secret --from-literal='secret=not_sealed_secret'
if ! is_confidential_hardware; then
@@ -79,10 +67,10 @@ setup() {
@test "Cannot Unseal Env Secrets with CDH without key" {
k8s_create_pod "${K8S_TEST_ENV_YAML}"
kubectl logs secret-test-pod-cc
kubectl logs secret-test-pod-cc | grep -q "UNPROTECTED_SECRET = not_sealed_secret"
cmd="kubectl logs secret-test-pod-cc | grep -q \"PROTECTED_SECRET = unsealed_secret\""
run $cmd
logs=$(kubectl logs secret-test-pod-cc)
echo "$logs"
grep -q "UNPROTECTED_SECRET = not_sealed_secret" <<< "$logs"
run grep -q "PROTECTED_SECRET = unsealed_secret" <<< "$logs"
[ "$status" -eq 1 ]
}
@@ -91,18 +79,20 @@ setup() {
kbs_set_resource "default" "sealed-secret" "test" "unsealed_secret"
k8s_create_pod "${K8S_TEST_ENV_YAML}"
kubectl logs secret-test-pod-cc
kubectl logs secret-test-pod-cc | grep -q "UNPROTECTED_SECRET = not_sealed_secret"
kubectl logs secret-test-pod-cc | grep -q "PROTECTED_SECRET = unsealed_secret"
logs=$(kubectl logs secret-test-pod-cc)
echo "$logs"
grep -q "UNPROTECTED_SECRET = not_sealed_secret" <<< "$logs"
grep -q "PROTECTED_SECRET = unsealed_secret" <<< "$logs"
}
@test "Unseal File Secrets with CDH" {
kbs_set_resource "default" "sealed-secret" "test" "unsealed_secret"
k8s_create_pod "${K8S_TEST_FILE_YAML}"
kubectl logs secret-test-pod-cc
kubectl logs secret-test-pod-cc | grep -q "UNPROTECTED_SECRET = not_sealed_secret"
kubectl logs secret-test-pod-cc | grep -q "PROTECTED_SECRET = unsealed_secret"
logs=$(kubectl logs secret-test-pod-cc)
echo "$logs"
grep -q "UNPROTECTED_SECRET = not_sealed_secret" <<< "$logs"
grep -q "PROTECTED_SECRET = unsealed_secret" <<< "$logs"
}
teardown() {

View File

@@ -19,6 +19,8 @@ setup() {
mountpoint="/mnt/temp-encrypted"
host_df="$(exec_host "${node}" df -PT -B1 "$(get_kubelet_data_dir)" | tail -n +2)"
info "host_df output:"
info "${host_df}"
host_cap_bytes="$(echo "${host_df}" | awk '{print $3}')"
yaml_file="${pod_config_dir}/pod-trusted-ephemeral-data-storage.yaml"
@@ -36,7 +38,7 @@ setup() {
# With long device names, df adds line breaks by default, so we pass -P to prevent that.
emptydir_df="$(kubectl exec "${pod_name}" -- df -PT -B1 "${mountpoint}" | tail -n +2)"
info "df output:"
info "emptydir_df output:"
info "${emptydir_df}"
dm_device="$(echo "${emptydir_df}" | awk '{print $1}')"
@@ -46,17 +48,18 @@ setup() {
# The output of the cryptsetup command will contain something like this:
#
# /dev/mapper/encrypted_disk_N6PxO is active and is in use.
# type: LUKS2
# cipher: aes-xts-plain64
# /dev/mapper/741ed4bf-3073-49ed-9b7a-d6fa7cce0db1 is active and is in use.
# type: n/a
# cipher: aes-xts-plain
# keysize: 768 bits
# key location: keyring
# integrity: hmac(sha256)
# integrity keysize: 256 bits
# device: /dev/vda
# integrity tag size: 32 bytes
# device: /dev/sdd
# sector size: 4096
# offset: 0 sectors
# size: 2031880 sectors
# size: 300052568 sectors
# mode: read/write
crypt_status="$(kubectl exec "${pod_name}" -- cryptsetup status "${dm_device}")"
info "cryptsetup status output:"
@@ -65,16 +68,15 @@ setup() {
# Check filesystem type and capacity.
[[ "${fs_type}" == "ext4" ]]
# Allow up to 7% LUKS metadata overhead.
(( emptydir_cap_bytes >= host_cap_bytes * 93 / 100 ))
# Allow up to 15% LUKS + ext4 metadata overhead.
(( emptydir_avail_bytes >= host_cap_bytes * 85 / 100 ))
# Allow up to 4% metadata overhead.
(( emptydir_cap_bytes >= host_cap_bytes * 96 / 100 ))
# Allow up to 10% metadata overhead.
(( emptydir_avail_bytes >= host_cap_bytes * 90 / 100 ))
# Check encryption settings.
grep -q "${dm_device} is active and is in use" <<< "${crypt_status}"
grep -Eq "type: +LUKS2" <<< "${crypt_status}"
grep -Eq "cipher: +aes-xts-plain64" <<< "${crypt_status}"
grep -Eq "type: +n/a" <<< "${crypt_status}" # The LUKS header is detached.
grep -Eq "cipher: +aes-xts-plain" <<< "${crypt_status}"
grep -Eq "integrity: +hmac\(sha256\)" <<< "${crypt_status}"
# Check I/O.

View File

@@ -51,6 +51,27 @@ kernel_params = "${new_params}"
EOF
}
# Create Docker config for genpolicy so it can authenticate to nvcr.io when
# pulling image manifests (avoids "UnauthorizedError" from genpolicy's registry pull).
# Genpolicy (src/tools/genpolicy) uses docker_credential::get_credential() in
# src/tools/genpolicy/src/registry.rs build_auth(). The docker_credential crate
# reads config from DOCKER_CONFIG (directory) + "/config.json", so we set
# DOCKER_CONFIG to a directory containing config.json with nvcr.io auth.
setup_genpolicy_registry_auth() {
if [[ -z "${NGC_API_KEY:-}" ]]; then
return
fi
local auth_dir
auth_dir="${kubernetes_dir}/.docker-genpolicy"
mkdir -p "${auth_dir}"
# Docker config format: auths -> registry -> auth (base64 of "user:password")
echo -n "{\"auths\":{\"nvcr.io\":{\"username\":\"\$oauthtoken\",\"password\":\"${NGC_API_KEY}\",\"auth\":\"$(echo -n "\$oauthtoken:${NGC_API_KEY}" | base64 -w0)\"}}}" \
> "${auth_dir}/config.json"
export DOCKER_CONFIG="${auth_dir}"
# REGISTRY_AUTH_FILE (containers-auth.json format) is the same structure for auths
export REGISTRY_AUTH_FILE="${auth_dir}/config.json"
}
cleanup() {
true
}
@@ -84,6 +105,9 @@ if [[ "${ENABLE_NVRC_TRACE:-true}" == "true" ]]; then
enable_nvrc_trace
fi
# So genpolicy can pull nvcr.io image manifests when generating policy (avoids UnauthorizedError).
setup_genpolicy_registry_auth
# Use common bats test runner with proper reporting
export BATS_TEST_FAIL_FAST="${K8S_TEST_FAIL_FAST}"
run_bats_tests "${kubernetes_dir}" K8S_TEST_NV

View File

@@ -103,6 +103,7 @@ long_options=(
[no-arch]="Run/list all tests except architecture-specific ones"
[only-arch]="Only run/list architecture-specific tests"
[repo:]="Specify GitHub URL of repo to use (github.com/user/repo)"
[repo-path:]="Specify path to repository to check (default: \$GOPATH/src/\$repo)"
[scripts]="Check script files"
[vendor]="Check vendor files"
[versions]="Check versions files"
@@ -596,19 +597,6 @@ check_url()
local curl_ua_args
[ -n "$user_agent" ] && curl_ua_args="-A '$user_agent'"
{ run_url_check_cmd "$url" "$curl_out" "$curl_ua_args"; ret=$?; } || true
# A transitory error, or the URL is incorrect,
# but capture either way.
if [ "$ret" -ne 0 ]; then
errors+=("Failed to check URL '$url' (user agent: '$user_agent', return code $ret)")
# Try again with another UA since it appears that some return codes
# indicate the server was unhappy with the details
# presented by the client.
continue
fi
local http_statuses
http_statuses=$(grep -E "^HTTP" "$curl_out" |\
@@ -798,111 +786,13 @@ static_check_docs()
# Convert the list of files into an grep(1) alternation pattern.
exclude_pattern=$(echo "${exclude_doc_regexs[@]}"|sed 's, ,|,g')
# Every document in the repo (except a small handful of exceptions)
# should be referenced by another document.
for doc in $md_docs_to_check
do
# Check the ignore list for markdown files that do not need to
# be referenced by others.
echo "$doc"|grep -q -E "(${exclude_pattern})" && continue
grep -q "$doc" "$md_links" || die "Document $doc is not referenced"
done
info "Checking document code blocks"
local doc_to_script_cmd="${cidir}/kata-doc-to-script.sh"
for doc in $docs
do
bash "${doc_to_script_cmd}" -csv "$doc"
# Look for URLs in the document
urls=$("${doc_to_script_cmd}" -i "$doc" - | "$cmd")
# Gather URLs
for url in $urls
do
printf "%s\t%s\n" "${url}" "${doc}" >> "$url_map"
done
done
# Get unique list of URLs
urls=$(awk '{print $1}' "$url_map" | sort -u)
info "Checking all document URLs"
local invalid_urls_dir=$(mktemp -d)
files_to_remove+=("${invalid_urls_dir}")
for url in $urls
do
if [ "$specific_branch" != "true" ]
then
# If the URL is new on this PR, it cannot be checked.
echo "$new_urls" | grep -q -E "\<${url}\>" && \
info "ignoring new (but correct) URL: $url" && continue
fi
# Ignore local URLs. The only time these are used is in
# examples (meaning these URLs won't exist).
echo "$url" | grep -q "^file://" && continue
echo "$url" | grep -q "^http://localhost" && continue
# Ignore the install guide URLs that contain a shell variable
echo "$url" | grep -q "\\$" && continue
# This prefix requires the client to be logged in to github, so ignore
echo "$url" | grep -q 'https://github.com/pulls' && continue
# Sigh.
echo "$url"|grep -q 'https://example.com' && continue
# Google APIs typically require an auth token.
echo "$url"|grep -q 'https://www.googleapis.com' && continue
# Git repo URL check
if echo "$url"|grep -q '^https.*git'
then
timeout "${KATA_NET_TIMEOUT}" git ls-remote "$url" > /dev/null 2>&1 && continue
fi
# Check the URL, saving it if invalid
#
# Each URL is checked in a separate process as each unique URL
# requires us to hit the network.
check_url "$url" "$invalid_urls_dir" &
done
# Synchronisation point
wait
# Combine all the separate invalid URL files into one
local invalid_files=$(ls "$invalid_urls_dir")
if [ -n "$invalid_files" ]; then
pushd "$invalid_urls_dir" &>/dev/null
cat $(echo "$invalid_files"|tr '\n' ' ') > "$invalid_urls"
popd &>/dev/null
fi
if [ -s "$invalid_urls" ]
then
local files
cat "$invalid_urls" | while read url
do
files=$(grep "^${url}" "$url_map" | awk '{print $2}' | sort -u)
echo >&2 -e "ERROR: Invalid URL '$url' found in the following files:\n"
for file in $files
do
echo >&2 "$file"
done
done
exit 1
fi
# Now, spell check the docs
cmd="${test_dir}/cmd/check-spelling/kata-spell-check.sh"
@@ -1516,6 +1406,8 @@ main()
local func=
repo_path=""
while [ $# -gt 1 ]
do
case "$1" in
@@ -1536,6 +1428,7 @@ main()
--only-arch) handle_funcs="arch-specific" ;;
--rego) func=static_check_rego ;;
--repo) repo="$2"; shift ;;
--repo-path) repo_path="$2"; shift ;;
--scripts) func=static_check_shell ;;
--vendor) func=static_check_vendor;;
--versions) func=static_check_versions ;;
@@ -1568,7 +1461,10 @@ main()
test_path="${test_path:-"${repo}/tests"}"
test_dir="${GOPATH}/src/${test_path}"
repo_path=$GOPATH/src/$repo
if [ -z "$repo_path" ]
then
repo_path=$GOPATH/src/$repo
fi
announce

View File

@@ -61,12 +61,19 @@ install_userspace_components() {
eval "${APT_INSTALL}" nvidia-imex nvidia-firmware \
libnvidia-cfg1 libnvidia-gl libnvidia-extra \
libnvidia-decode libnvidia-fbc1 libnvidia-encode \
libnvidia-nscq
libnvidia-nscq libnvidia-compute nvidia-settings
apt-mark hold nvidia-imex nvidia-firmware \
libnvidia-cfg1 libnvidia-gl libnvidia-extra \
libnvidia-decode libnvidia-fbc1 libnvidia-encode \
libnvidia-nscq
libnvidia-nscq libnvidia-compute nvidia-settings
# Needed for confidential-data-hub runtime dependencies
eval "${APT_INSTALL}" cryptsetup-bin dmsetup \
libargon2-1 e2fsprogs
apt-mark hold cryptsetup-bin dmsetup libargon2-1 \
e2fsprogs
}
setup_apt_repositories() {

View File

@@ -151,14 +151,8 @@ chisseled_nvswitch() {
cp -a "${stage_one}"/usr/share/nvidia/nvswitch usr/share/nvidia/.
libdir=usr/lib/"${machine_arch}"-linux-gnu
cp -a "${stage_one}/${libdir}"/libnvidia-nscq.so.* lib/"${machine_arch}"-linux-gnu/.
# Logs will be redirected to console(stderr)
# if the specified log file can't be opened or the path is empty.
# LOG_FILE_NAME=/var/log/fabricmanager.log -> setting to empty for stderr -> kmsg
sed -i 's|^LOG_FILE_NAME=.*|LOG_FILE_NAME=|' usr/share/nvidia/nvswitch/fabricmanager.cfg
# NVLINK SubnetManager dependencies
local nvlsm=usr/share/nvidia/nvlsm
mkdir -p "${nvlsm}"
@@ -166,6 +160,8 @@ chisseled_nvswitch() {
cp -a "${stage_one}"/opt/nvidia/nvlsm/lib/libgrpc_mgr.so lib/.
cp -a "${stage_one}"/opt/nvidia/nvlsm/sbin/nvlsm sbin/.
cp -a "${stage_one}/${nvlsm}"/*.conf "${nvlsm}"/.
# Redirect all the logs to syslog instead of logging to file
sed -i 's|^LOG_USE_SYSLOG=.*|LOG_USE_SYSLOG=1|' usr/share/nvidia/nvswitch/fabricmanager.cfg
}
chisseled_dcgm() {
@@ -211,9 +207,8 @@ chisseled_compute() {
cp -aL "${stage_one}/${libdir}"/ld-linux-* "${libdir}"/.
libdir=usr/lib/"${machine_arch}"-linux-gnu
cp -a "${stage_one}/${libdir}"/libnvidia-ml.so.* lib/"${machine_arch}"-linux-gnu/.
cp -a "${stage_one}/${libdir}"/libnv* lib/"${machine_arch}"-linux-gnu/.
cp -a "${stage_one}/${libdir}"/libcuda.so.* lib/"${machine_arch}"-linux-gnu/.
cp -a "${stage_one}/${libdir}"/libnvidia-cfg.so.* lib/"${machine_arch}"-linux-gnu/.
# basic GPU admin tools
cp -a "${stage_one}"/usr/bin/nvidia-persistenced bin/.
@@ -245,6 +240,8 @@ chisseled_init() {
usr/bin etc/modprobe.d etc/ssl/certs
ln -sf ../run var/run
ln -sf ../run var/log
ln -sf ../run var/cache
# Needed for various RUST static builds with LIBC=gnu
libdir=lib/"${machine_arch}"-linux-gnu
@@ -311,6 +308,44 @@ compress_rootfs() {
chmod +x "${libdir}"/ld-linux-*
}
copy_cdh_runtime_deps() {
local libdir="lib/${machine_arch}-linux-gnu"
# Shared libraries required by /usr/local/bin/confidential-data-hub.
# Note: libcryptsetup loads some optional helpers (e.g. libpopt/libssh) only
# when specific features are used. The current CDH path (LUKS2 + mkfs.ext4)
# does not require those optional libs.
cp -a "${stage_one}/${libdir}"/libcryptsetup.so.12* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libuuid.so.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libdevmapper.so.1.02.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libselinux.so.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libpcre2-8.so.0* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libudev.so.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libcap.so.2* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libcrypto.so.3* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libz.so.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libzstd.so.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libjson-c.so.5* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libblkid.so.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libargon2.so.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libgcc_s.so.1* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libm.so.6* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libc.so.6* "${libdir}/."
# e2fsprogs (mkfs.ext4) runtime libs
cp -a "${stage_one}/${libdir}"/libext2fs.so.2* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libe2p.so.2* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libss.so.2* "${libdir}/."
cp -a "${stage_one}/${libdir}"/libcom_err.so.2* "${libdir}/."
# mkfs.ext4 and dd are used by CDH secure_mount
mkdir -p sbin etc usr/bin bin
cp -a "${stage_one}/sbin/mke2fs" sbin/.
cp -a "${stage_one}/sbin/mkfs.ext4" sbin/.
cp -a "${stage_one}/etc/mke2fs.conf" etc/.
cp -a "${stage_one}/usr/bin/dd" bin/.
}
coco_guest_components() {
if [[ "${type}" != "confidential" ]]; then
return
@@ -333,7 +368,7 @@ coco_guest_components() {
cp -a "${stage_one}/${pause_dir}"/config.json "${pause_dir}/."
cp -a "${stage_one}/${pause_dir}"/rootfs/pause "${pause_dir}/rootfs/."
info "TODO: nvidia: luks-encrypt-storage is a bash script, we do not have a shell!"
copy_cdh_runtime_deps
}
setup_nvidia_gpu_rootfs_stage_two() {

View File

@@ -15,13 +15,13 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: "3.27.0"
version: "3.28.0"
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "3.27.0"
appVersion: "3.28.0"
dependencies:
- name: node-feature-discovery

View File

@@ -96,9 +96,9 @@ scheduling:
"qemu-snp-runtime-rs" (dict "memory" "2048Mi" "cpu" "1.0")
"qemu-tdx" (dict "memory" "2048Mi" "cpu" "1.0")
"qemu-tdx-runtime-rs" (dict "memory" "2048Mi" "cpu" "1.0")
"qemu-nvidia-gpu" (dict "memory" "4096Mi" "cpu" "1.0")
"qemu-nvidia-gpu-snp" (dict "memory" "20480Mi" "cpu" "1.0")
"qemu-nvidia-gpu-tdx" (dict "memory" "20480Mi" "cpu" "1.0")
"qemu-nvidia-gpu" (dict "memory" "10240Mi" "cpu" "1.0")
"qemu-nvidia-gpu-snp" (dict "memory" "10240Mi" "cpu" "1.0")
"qemu-nvidia-gpu-tdx" (dict "memory" "10240Mi" "cpu" "1.0")
"qemu-cca" (dict "memory" "2048Mi" "cpu" "1.0")
"stratovirt" (dict "memory" "130Mi" "cpu" "250m")
"remote" (dict "memory" "120Mi" "cpu" "250m")

View File

@@ -110,9 +110,6 @@ cloud-hypervisor-tarball:
cloud-hypervisor-glibc-tarball:
${MAKE} $@-build
csi-kata-directvolume-tarball: copy-scripts-for-the-tools-build
${MAKE} $@-build
firecracker-tarball:
${MAKE} $@-build
@@ -194,15 +191,9 @@ rootfs-initrd-tarball: agent-tarball
rootfs-image-nvidia-gpu-tarball: agent-tarball busybox-tarball kernel-nvidia-gpu-tarball
${MAKE} $@-build
rootfs-initrd-nvidia-gpu-tarball: agent-tarball busybox-tarball kernel-nvidia-gpu-tarball
${MAKE} $@-build
rootfs-image-nvidia-gpu-confidential-tarball: agent-tarball busybox-tarball pause-image-tarball coco-guest-components-tarball kernel-nvidia-gpu-tarball
${MAKE} $@-build
rootfs-initrd-nvidia-gpu-confidential-tarball: agent-tarball busybox-tarball pause-image-tarball coco-guest-components-tarball kernel-nvidia-gpu-tarball
${MAKE} $@-build
rootfs-cca-confidential-image-tarball: agent-tarball pause-image-tarball coco-guest-components-tarball kernel-cca-confidential-tarball
${MAKE} $@-build

View File

@@ -108,7 +108,6 @@ options:
coco-guest-components
cloud-hypervisor
cloud-hypervisor-glibc
csi-kata-directvolume
firecracker
genpolicy
kata-ctl
@@ -608,16 +607,6 @@ install_image_nvidia_gpu() {
install_image "nvidia-gpu"
}
# Install NVIDIA GPU initrd
install_initrd_nvidia_gpu() {
export AGENT_POLICY
export MEASURED_ROOTFS="no"
local version=$(get_from_kata_deps .externals.nvidia.driver.version)
EXTRA_PKGS="apt curl ${EXTRA_PKGS}"
NVIDIA_GPU_STACK=${NVIDIA_GPU_STACK:-"driver=${version},compute,dcgm,nvswitch"}
install_initrd "nvidia-gpu"
}
# Instal NVIDIA GPU confidential image
install_image_nvidia_gpu_confidential() {
export CONFIDENTIAL_GUEST="yes"
@@ -629,18 +618,6 @@ install_image_nvidia_gpu_confidential() {
install_image "nvidia-gpu-confidential"
}
# Install NVIDIA GPU confidential initrd
install_initrd_nvidia_gpu_confidential() {
export CONFIDENTIAL_GUEST="yes"
export AGENT_POLICY
export MEASURED_ROOTFS="no"
local version=$(get_from_kata_deps .externals.nvidia.driver.version)
EXTRA_PKGS="apt curl ${EXTRA_PKGS}"
NVIDIA_GPU_STACK=${NVIDIA_GPU_STACK:-"driver=${version},compute,dcgm,nvswitch"}
install_initrd "nvidia-gpu-confidential"
}
install_se_image() {
info "Create IBM SE image configured with AA_KBC=${AA_KBC}"
"${se_image_builder}" --destdir="${destdir}"
@@ -1205,7 +1182,6 @@ install_tools_helper() {
tool_binary=${tool}
[ ${tool} = "agent-ctl" ] && tool_binary="kata-agent-ctl"
[ ${tool} = "csi-kata-directvolume" ] && tool_binary="directvolplugin"
[ ${tool} = "trace-forwarder" ] && tool_binary="kata-trace-forwarder"
local tool_build_dir="src/tools/${tool}"
@@ -1248,7 +1224,6 @@ install_tools_helper() {
info "Install static ${tool_binary}"
mkdir -p "${destdir}/opt/kata/bin/"
[ ${tool} = "csi-kata-directvolume" ] && tool_binary="csi-kata-directvolume"
install -D --mode "${binary_permissions}" "${binary}" "${destdir}/opt/kata/bin/${tool_binary}"
}
@@ -1260,10 +1235,6 @@ install_genpolicy() {
install_tools_helper "genpolicy"
}
install_csi_kata_directvolume() {
install_tools_helper "csi-kata-directvolume"
}
install_kata_ctl() {
install_tools_helper "kata-ctl"
}
@@ -1338,8 +1309,6 @@ handle_build() {
cloud-hypervisor-glibc) install_clh_glibc ;;
csi-kata-directvolume) install_csi_kata_directvolume ;;
firecracker) install_firecracker ;;
genpolicy) install_genpolicy ;;
@@ -1392,12 +1361,8 @@ handle_build() {
rootfs-image-nvidia-gpu) install_image_nvidia_gpu ;;
rootfs-initrd-nvidia-gpu) install_initrd_nvidia_gpu ;;
rootfs-image-nvidia-gpu-confidential) install_image_nvidia_gpu_confidential ;;
rootfs-initrd-nvidia-gpu-confidential) install_initrd_nvidia_gpu_confidential ;;
rootfs-cca-confidential-image) install_image_confidential ;;
rootfs-cca-confidential-initrd) install_initrd_confidential ;;
@@ -1556,7 +1521,6 @@ main() {
agent-ctl
cloud-hypervisor
coco-guest-components
csi-kata-directvolume
firecracker
genpolicy
kata-ctl

View File

@@ -611,6 +611,7 @@ install_kata() {
fi
install --mode 0644 -D ./.config "${install_path}/config-${kernel_version}-${config_version}${suffix}"
install --mode 0644 -D ./System.map "${install_path}/System.map-${kernel_version}-${config_version}${suffix}"
ln -sf "${vmlinuz}" "${install_path}/vmlinuz${suffix}.container"
ln -sf "${vmlinux}" "${install_path}/vmlinux${suffix}.container"

View File

@@ -1 +1 @@
185
186

View File

@@ -25,6 +25,7 @@ RUN apt-get update && \
g++ \
gcc \
git \
libcryptsetup-dev \
libssl-dev \
libtss2-dev \
make \

View File

@@ -34,7 +34,6 @@ build_coco_guest_components_from_source() {
strip "target/${RUST_ARCH}-unknown-linux-${LIBC}/release/api-server-rest"
DESTDIR="${DESTDIR}/usr/local/bin" TEE_PLATFORM=${TEE_PLATFORM} make install
install -D -m0755 "confidential-data-hub/hub/src/storage/scripts/luks-encrypt-storage" "${DESTDIR}/usr/local/bin/luks-encrypt-storage"
install -D -m0644 "confidential-data-hub/hub/src/image/ocicrypt_config.json" "${DESTDIR}/etc/ocicrypt_config.json"
popd
}

View File

@@ -19,6 +19,8 @@ paths:
- "^ci/openshift-ci/": []
- "^\\.github/workflows/static-checks": ["static"]
- "^\\.github/workflows/": []
- "^docs/": ["static"]
- "^mkdocs\\.yaml$": ["static"]
- "\\.md$": ["static"]
# TODO: Expand filters
# Sources
@@ -123,7 +125,6 @@ mapping:
- Kata Containers CI / kata-containers-ci-on-push / build-kata-static-tarball-amd64 / build-asset (virtiofsd, test)
- Kata Containers CI / kata-containers-ci-on-push / build-kata-static-tarball-amd64 / create-kata-tarball
- Kata Containers CI / kata-containers-ci-on-push / build-kata-static-tarball-amd64 / build-tools-asset (agent-ctl, test)
- Kata Containers CI / kata-containers-ci-on-push / build-kata-static-tarball-amd64 / build-tools-asset (csi-kata-directvolume, test)
- Kata Containers CI / kata-containers-ci-on-push / build-kata-static-tarball-amd64 / build-tools-asset (genpolicy, test)
- Kata Containers CI / kata-containers-ci-on-push / build-kata-static-tarball-amd64 / build-tools-asset (kata-ctl, test)
- Kata Containers CI / kata-containers-ci-on-push / build-kata-static-tarball-amd64 / build-tools-asset (kata-manager, test)

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.1"
version: "v0.1.3"
url: "https://github.com/NVIDIA/nvrc/releases/download/"
nvidia:
@@ -288,18 +288,18 @@ externals:
coco-guest-components:
description: "Provides attested key unwrapping for image decryption"
url: "https://github.com/confidential-containers/guest-components/"
version: "9aae2eae6a03ab97d6561bbe74f8b99843836bba"
version: "ab95914ac84c32a43102463cc0ae330710af47be"
toolchain: "1.90.0"
coco-trustee:
description: "Provides attestation and secret delivery components"
url: "https://github.com/confidential-containers/trustee"
version: "3b2356a52e0d8a58730a1977e235a7e7f2007b5e"
version: "f5cb8fc1b51b652fc24e2d6b8742cf417805352e"
# image / ita_image and image_tag / ita_image_tag must be in sync
image: "ghcr.io/confidential-containers/staged-images/kbs"
image_tag: "3b2356a52e0d8a58730a1977e235a7e7f2007b5e"
image_tag: "f5cb8fc1b51b652fc24e2d6b8742cf417805352e"
ita_image: "ghcr.io/confidential-containers/staged-images/kbs-ita-as"
ita_image_tag: "3b2356a52e0d8a58730a1977e235a7e7f2007b5e-x86_64"
ita_image_tag: "f5cb8fc1b51b652fc24e2d6b8742cf417805352e-x86_64"
toolchain: "1.90.0"
containerd:
@@ -479,12 +479,12 @@ languages:
description: "Rust language"
notes: "'version' is the default minimum version used by this project."
# Keep in sync with rust-toolchain.toml
version: "1.91"
version: "1.92"
meta:
description: |
'newest-version' is the latest version known to work when
building Kata
newest-version: "1.91"
newest-version: "1.92"
golangci-lint:
description: "golangci-lint"