Commit Graph

19382 Commits

Author SHA1 Message Date
Fabiano Fidêncio
c029e9ed5b build: split NVIDIA rootfs into base-nvidia image + gpu addon
Carve the monolithic NVIDIA GPU rootfs into a driver-agnostic
base-nvidia image (NVRC init + agent + base libs + in-tree modules)
and a driver-versioned gpu addon (GPU userspace, configs, firmware,
NVIDIA modules) laid out for /run/kata-addons/gpu. Both halves are
produced from the same chiseled tree via a partition-after step, so
the monolith build stays byte-identical and continues to ship.

The shared stage-one (driver install) is reused across the monolith,
base and addon variants; base-nvidia is cached without the driver/ctk
versions so one base image can back multiple driver addons.
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
b1b8ce0cd3 build: build NVRC from a pinned git ref
Add a Kata static-build component for NVRC (tools/packaging/static-build/nvrc)
that clones the NVRC repository at a pinned git reference and builds a static
musl binary, mirroring the coco-guest-components build. This lets the
composable-image work track NVRC changes from source instead of depending on a
signed upstream release.

  - versions.yaml: add repo/ref/toolchain to externals.nvrc (and bump the
    version); the existing url is kept for the signed-release path.
  - lib.sh: add get_nvrc_image_name for the builder image.
  - kata-deploy-binaries.sh: add the nvrc build target, install_nvrc and its
    tarball path; get_latest_nvidia_nvrc_version now tracks ref+toolchain so
    the dependent NVIDIA images rebuild when the ref changes.
  - nvidia_rootfs.sh: consume kata-static-nvrc.tar.zst instead of downloading
    and cosign-verifying the release; the Sigstore .cert/.sig are now copied
    only when present (i.e. the signed-release path), since a source build
    emits just the binary.

Signed-off-by: Fabiano Fidêncio <fidencio@nvidia.com>
Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
cada9c18d4 build: ship CoCo addon component manifest in addon image
Generate etc/kata-addons/components.toml inside the CoCo addon rootfs
before building the image, so the manifest becomes part of the
dm-verity-measured erofs image.

The manifest declares the addon's path-only components (ocicrypt config,
pause bundle) and the launchable processes (attestation-agent,
confidential-data-hub, api-server-rest) with paths relative to the addon
mount point (/run/kata-addons/coco) and `${var}` placeholders resolved
by kata-agent at runtime. This is the data the agent consumes to launch
the CoCo guest components without per-bundle code changes.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
9747a8bb91 agent: resolve and launch CoCo guest components via addon manifest
Make the agent's handling of CoCo guest components data-driven so that a
new addon bundle can be introduced without changing agent code.

Add a new `addon` module defining a generic component manifest contract.
When a CoCo addon image is mounted at /run/kata-addons/coco/, the agent
reads etc/kata-addons/components.toml from it to discover:

- path-only components (looked up by id under the `[paths]` table), used
  for the ocicrypt config and the pause bundle, and
- launchable processes (`[[process]]` entries) describing the binary
  path, args, optional args, config file, environment, socket to wait on
  and timeout.

`${var}` tokens in process fields are substituted from a fixed,
documented context the agent builds at runtime (attestation socket/uri,
config paths, rest-api features, initdata toml path, launch timeout,
resolved ocicrypt config path). Referencing an unknown variable is a
hard error, and manifest paths are validated against traversal, so the
contract stays fail-closed.

Processes are gated by a numeric `level` mapped from
guest_components_procs (AttestationAgent < ConfidentialDataHub <
ApiServerRest), preserving the existing implication semantics.

When no addon is mounted, launch_plan() returns None and the agent uses
a built-in plan that reproduces the legacy behaviour byte-for-byte
(binaries under /usr/local/bin, /etc/ocicrypt_config.json, /pause_bundle).
Monolithic / non-split confidential images are therefore unaffected.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
407ffa2e5a ci: adjust workflows to rootfs-image-coco-addon
Add rootfs-image-coco-addon to the build-asset-rootfs matrix in the
amd64, arm64 and s390x static tarball workflows so the CoCo addon image
is built as part of CI alongside the other rootfs images.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
ed769282ca build: add CoCo addon image build and remove CoCo deps from confidential image
Add install_image_coco_addon() to kata-deploy-binaries.sh which:
- Unpacks the CoCo guest components and pause image tarballs into a
  temporary rootfs directory (under the repo root so Docker-in-Docker
  volume mounts resolve correctly)
- Calls image_builder.sh with USE_DOCKER=1, FS_TYPE=erofs,
  MEASURED_ROOTFS=yes, SKIP_DAX_HEADER=yes, and SKIP_ROOTFS_CHECK=yes
  to produce kata-containers-coco-addon.img + root_hash_coco-addon.txt

Add the rootfs-image-coco-addon-tarball Makefile target with
dependencies on pause-image-tarball and coco-guest-components-tarball.

Remove pause-image-tarball and coco-guest-components-tarball from the
standard confidential image dependencies -- those components now live
exclusively in the CoCo addon image.  NVIDIA confidential images
retain them until the NVIDIA addon split lands.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
41361ce93e config: switch CoCo templates from monolithic image to base + addon
Update all six CoCo configuration templates (coco-dev, snp, tdx for
both Go and Rust runtimes) to use the standard base image instead of
the monolithic confidential image, and add an [[extra_images]] section
for the CoCo addon:

  image = "@IMAGEPATH@"          (was @IMAGECONFIDENTIALPATH@)

  [[hypervisor.qemu.extra_images]]
  name = "coco"
  path = "@COCOIMAGEPATH@"
  verity_params = "@COCOVERITYPARAMS@"

Add COCOIMAGENAME (kata-containers-coco-addon.img), COCOIMAGEPATH, and
COCOVERITYPARAMS to both runtime Makefiles so the placeholders are
substituted at install time.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
83e814c056 image-builder: support building addon images without /sbin/init check
Addon images (e.g. the CoCo guest components addon) are not full root
filesystems -- they contain only the binaries and configuration that
get bind-mounted into the real rootfs at boot.  The existing
check_rootfs() validation requires /sbin/init and systemd, which are
not present in addon images.

Add a SKIP_ROOTFS_CHECK environment variable that, when set to "yes",
bypasses the check_rootfs() call.  Forward the variable into the
container environment when using the Docker-based build path so it
works in both direct and containerised invocations.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
fbb25065d9 rootfs-builder: enable kata-addon-mount@coco.service in systemd targets
Create a symlink to enable kata-addon-mount@coco.service in
kata-containers.target.wants during rootfs construction for
systemd-based (non-AGENT_INIT) guests.

The unit's ConditionPathExists guard ensures it only activates when
the virtio-addon-coco block device is actually present in the VM,
so enabling it unconditionally in the base image is safe.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
c44f8336c9 agent: add systemd template unit for addon image mount/unmount
Add a systemd template unit kata-addon-mount@.service and companion
helper scripts (kata-addon-mount.sh, kata-addon-umount.sh) that handle
the guest-side setup of addon block device images.

The mount script:
- Discovers the block device via /dev/disk/by-id/virtio-addon-<name>
- Reads verity parameters from kata.addon.<name>.verity_params on the
  kernel command line
- Creates a dm-verity device and mounts the EROFS filesystem
- Bind-mounts addon directories (usr/local/bin, etc, pause_bundle)
  into the rootfs

The unit uses ConditionPathExists to only activate when the
corresponding virtio-blk device is present, and is ordered before
kata-agent.service so addon binaries are available when the agent
starts.

The agent Makefile is updated to install the unit and scripts.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
75acd74912 runtime: add extra_images cold-plug support for Go runtime
Mirror the Rust runtime's extra_images support in the Go runtime:

- hypervisor.go: add ExtraImage struct and ExtraImages field to
  HypervisorConfig.
- config.go: parse [[hypervisor.qemu.extra_images]] TOML sections
  via toExtraImages(), validating that every addon has a non-empty
  name and valid dm-verity parameters.
- qemu.go: in buildDevices(), attach each extra image as a virtio-blk
  drive with ID addon-<name>; in kernelParameters(), append
  kata.addon.<name>.verity_params=... for each extra image.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
0ffcaf5544 runtime-rs: add serial_override to BlockConfig and wire extra_images cold-plug
Add a serial_override field to BlockConfig and DeviceVirtioBlk so that
addon images get a deterministic QEMU serial (addon-<name>) instead of
the auto-generated image-<id>.  This lets the guest discover each addon
via /dev/disk/by-id/virtio-addon-<name>.

Wire up the full cold-plug path for extra_images:

- sandbox.rs: iterate boot_info.extra_images, create read-only
  BlockConfig entries with the correct serial_override, and push them
  as ResourceConfig::ExtraImage.
- resource lib.rs / manager_inner.rs: handle the new ExtraImage variant
  by delegating to the existing block device path.
- cmdline_generator.rs: use serial_override when present for the QEMU
  serial= parameter; append kata.addon.<name>.verity_params=... to the
  kernel command line for each extra image.
- inner.rs: propagate serial_override from BlockConfig to the cmdline
  generator's add_block_device().

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Fabiano Fidêncio
002b2f4780 kata-types: add ExtraImage struct and extra_images field to BootInfo
Introduce the ExtraImage type to describe addon block-device images
(e.g. CoCo guest components) that are cold-plugged into the VM
alongside the main rootfs.

Each ExtraImage carries a short name (used as the virtio-blk serial
and in kernel cmdline verity parameters), a host-side path, and
dm-verity parameters (required -- addon images must be integrity-
protected).

A new extra_images Vec is added to BootInfo so that both the Rust
and Go runtimes can iterate the configured addons when building the
VM device list and kernel command line.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:18:33 +02:00
Hyounggyu Choi
59fd29fb33 Merge pull request #13225 from BbolroC/use-tar-in-exporting-kate-deploy-files
packaging: Optimize kata-deploy build export using tar output
2026-06-15 14:47:01 +02:00
Hyounggyu Choi
46b8e9f027 packaging: Optimize kata-deploy build export using tar output
Replace `type=local` with `type=tar` in kata-deploy build to reduce
export time and avoid build hangs during the export-to-client-directory
phase.

Update callers to extract binaries directly from the tar archive instead
of copying from an intermediate directory.

Signed-off-by: Hyounggyu Choi <Hyounggyu.Choi@ibm.com>
2026-06-15 11:52:33 +02:00
Fabiano Fidêncio
50d68d1f5f Merge pull request #13116 from thejasn/thn/fix-oom-event-deadlock
agent: fix get_oom_event deadlock after connection restart
2026-06-15 11:05:46 +02:00
Steve Horsman
ea999aa033 Merge pull request #13221 from manuelh-dev/mahuber/nydus-root-export
kata-deploy: export nydus snapshotter root
2026-06-15 08:55:08 +01:00
Thejas N
7807aa3d62 agent: fix get_oom_event deadlock after connection restart
When the agent-protocol-forwarder's inbound connection restarts (e.g.
during a Cloud API Adaptor restart in peer pod environments), the shim
re-sends a GetOOMEvent request through the new connection. Since the
forwarder→agent Unix socket survives the restart, the old handler from
the previous connection remains alive, holding the event_rx lock while
blocked in recv().await.

The new handler acquires the sandbox lock, then attempts to acquire the
event_rx lock — which is held by the old handler. Because the sandbox
lock is still held during this wait, every subsequent RPC
(ExecProcess, WaitProcess, StatsContainer, SignalProcess, etc.) blocks
on the sandbox lock, rendering the pod completely unresponsive.

The root cause is a lock ordering violation: get_oom_event held the
sandbox lock while acquiring the event_rx lock. Fix this by scoping the
sandbox lock acquisition so it is dropped before the event_rx lock is
acquired. The sandbox lock is only needed to clone the Arc<Mutex<Receiver>>
— once cloned, it can be released immediately.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Thejas N <thn@redhat.com>
2026-06-15 07:47:18 +02:00
Fabiano Fidêncio
37c4a0b6a2 Merge pull request #13128 from nikolasgkou/fix/guest-protection-fallback
runtime-rs: don't fail VM start when guest protection detection errors
2026-06-13 08:56:56 +02:00
Fabiano Fidêncio
5efc761002 Merge pull request #13211 from glingy/patch-1
runtime-rs: Fix queue_size of zero in block_rootfs
2026-06-12 22:37:18 +02:00
Fabiano Fidêncio
1b60563a34 Merge pull request #13120 from LandonTClipp/runtime-config
chore(docs): Clarify dropIn runtime configuration
2026-06-12 22:34:58 +02:00
LandonTClipp
6005f8a499 chore(docs): Add cspell makefile target for local testing
This makes it easier to check the spellchecker is happy before
submitting it as a PR.

Signed-off-by: LandonTClipp <lclipp@coreweave.com>
2026-06-12 22:24:18 +02:00
LandonTClipp
03c283edec chore(docs): Clarify dropIn runtime configuration
Clean the runtime configuration section by focusing first on the helm
configuration. Then, pivot into a further explanation on how the runtime
can be directly configured. Link to where these config parameters are
explained more in-depth.

Add open-in-new-tab (already downloaded in requirements.txt) in the
mkdocs plugin config so that links don't open in the same tab.

Signed-off-by: LandonTClipp <lclipp@coreweave.com>
2026-06-12 22:24:18 +02:00
nikolasgkou
80b8f592a0 runtime-rs: skip guest protection detection for non-confidential guests
prepare_protection_device_config() called available_guest_protection()
unconditionally and propagated any error before the "confidential_guest
is not set" case was handled.

On AMD hosts where the kvm_amd `sev` module parameter is "Y" but the CPU
does not expose the SEV-SNP CPUID bit (8000_001f EAX[4]) -- e.g. consumer
Ryzen -- available_guest_protection() returns Err("SEV not supported"),
which blocked every non-confidential VM from booting even though no
protection was requested.

When confidential_guest is not set there is no reason to probe the host,
so return Ok(None) before calling available_guest_protection(). Detection
(and any error it produces) now runs only when a confidential guest is
actually requested.

Signed-off-by: nikolasgkou <nikolasgkou@disroot.org>
2026-06-12 22:20:13 +02:00
Fabiano Fidêncio
47b327ea35 Merge pull request #13155 from fidencio/topic/kata-deploy-no-daemonset
kata-deploy: add a Job-based deployment mode (alternative to the privileged DaemonSet)
2026-06-12 21:55:11 +02:00
Manuel Huber
639420e7f5 kata-deploy: export nydus snapshotter root
containerd uses the proxy plugin root export when reporting CRI image
filesystem paths. Without this export, the CRI plugin falls back to
/var/lib/containerd/io.containerd.snapshotter.v1.<snapshotter>.

For nydus-for-kata-tee this fallback does not match the actual
snapshotter root under /var/lib/nydus-for-kata-tee.
Kubelet/cAdvisor then fails stats collection when it tries to inspect
the nonexistent fallback path.

Export the nydus proxy snapshotter root so containerd reports the real
filesystem path for resource accounting.

When using trusted ephemeral storage or a new ephemeral storage wip
feature for providing plain disks, resource accounting would not kick
in and pods which exhausted their emptyDir sizeLimits would not get
evicted.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
2026-06-12 19:06:01 +02:00
Fabiano Fidêncio
c5d5fc6ee8 Merge pull request #13213 from burgerdev/grpc-probes
genpolicy: add missing probe fields
2026-06-12 19:04:53 +02:00
Fabiano Fidêncio
aa27490801 kata-deploy: track distroless static base by tag, not digest
The kata-deploy main image pinned its gcr.io/distroless/static-debian13
base by sha256 digest. distroless does not publish versioned tags, so a
pinned digest just goes stale with no clear upgrade path. Track the
rolling tag instead (guarded with a hadolint DL3007 ignore plus a comment
explaining why), matching the kata-deploy-job-dispatcher image base.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Fabiano Fidêncio
aebadb1ab2 docs: document kata-deploy job deployment mode
Document the new opt-in deploymentMode: job alongside the default
DaemonSet model in the maintained docs (not just the chart README):

  - helm-configuration.md: add a "Deployment Modes (DaemonSet vs Job)"
    section covering the dispatcher-driven staged install/cleanup
    pipelines, why a dispatcher is used instead of Helm-rendered per-node
    Jobs (O(1) release, guaranteed coverage, paced rollout, explicit
    privilege split), the "re-run helm upgrade to cover newly added
    nodes" model (no always-on reconcile component), and the
    node-selection precedence (job.nodes > job.nodeSelector +
    job.nodeSelectorExpressions) that defaults to worker nodes.
  - installation.md: note that the DaemonSet is the default but no longer
    the only model, linking to the section above.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Fabiano Fidêncio
c23fe11529 kata-deploy: make verification Job aware of job deployment mode
The verification Job assumed the DaemonSet model: it waited for the
DaemonSet to exist, for its pods, and for `rollout status daemonset/...`,
then required every node in the cluster to be labeled. None of that holds
for deploymentMode: job, where install happens via the dispatcher and the
per-node Jobs it fans out, and only the targeted (worker) nodes get
labeled.

Make the hook mode-aware:
  - Hook weight: in job mode the install dispatcher runs as a
    post-install hook at weight 5, so verification now runs at weight 10
    (after it); daemonset mode keeps weight 0 (the DaemonSet is a normal
    resource).
  - Readiness wait: in job mode, wait for the install dispatcher Job to
    complete and then for the per-node install Jobs
    (kata-deploy/stage=install) to finish (with the same CRI-restart
    retry logic) instead of a DaemonSet rollout.
  - Label check: in job mode, verify exactly the nodes the dispatcher
    targeted are labeled, rather than comparing the labeled count against
    all nodes in the cluster.
  - Grant the verification ClusterRole read access to batch/jobs (used by
    the job-mode waits; harmless in daemonset mode).

The daemonset code path is unchanged and the default render (no
verification.pod) is byte-for-byte identical.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Fabiano Fidêncio
3d732986d2 kata-deploy: add per-node staged cleanup for job mode
Add the uninstall counterpart to the install dispatcher for
deploymentMode: job. On `helm uninstall`, a single pre-delete hook Job
runs the kata-deploy-job-dispatcher, which enumerates the targeted nodes
live and fans out one node-pinned cleanup Job per node that runs the
install pipeline in reverse and exits:

  unlabel -> revert-cri   (initContainers, run sequentially)
  remove-artifacts        (main container)

Running as a pre-delete hook means the dispatcher ServiceAccount/RBAC and
the kata-deploy host-mutation RBAC still exist while the Jobs run, so the
unlabel stage retains node get/patch access. revert-cri and
remove-artifacts are host-only operations (privileged nsenter / host
mount) and need no extra cluster RBAC.

Ordering mirrors install in reverse: unlabel first so the scheduler stops
placing kata workloads here, then revert the CRI config + restart the
runtime, then remove the on-host artifacts. Each stage is idempotent and
skips when already undone, so partially-installed nodes and re-runs are
safe.

Uninstall node selection is deliberately SEPARATE from install (a
dedicated job.cleanup.* block) and defaults to every node carrying the
katacontainers.io/kata-runtime label (set by the install label stage)
rather than re-evaluating the install selector. Because the cleanup
dispatcher resolves nodes live when it runs, this stays robust to
install-time selector drift (relabeled nodes, etc.) while remaining fully
overridable via job.cleanup.nodes / job.cleanup.nodeSelector /
job.cleanup.nodeSelectorExpressions. The default (daemonset) mode is
unaffected.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Fabiano Fidêncio
54878fa373 kata-deploy: add job deployment mode driven by the job-dispatcher
Phase 2 of the DaemonSet -> staged-Job migration: add an opt-in
`deploymentMode: job` that installs Kata via short-lived, per-node
install Jobs instead of the long-running DaemonSet. The DaemonSet remains
the default and is now gated behind `deploymentMode == daemonset`.

Rather than render one Job per node into the Helm release (which grows
the release secret O(nodes) and offers no rollout pacing), job mode ships
a single tiny post-install/post-upgrade hook Job that runs the
kata-deploy-job-dispatcher. The dispatcher enumerates the selected nodes
LIVE from the API server and stamps out one node-pinned install Job per
node from a constant-size ConfigMap of Job templates, keeping at most
`job.parallelism` in flight and refilling as they finish. This guarantees
per-node coverage with a paced rollout while the Helm release stays O(1)
regardless of fleet size. New nodes are picked up by re-running
`helm upgrade`; there is no always-on component.

Each per-node Job runs the staged install pipeline as ordered
initContainers and exits:

  host-check -> artifacts -> cri   (initContainers, run sequentially)
  label                            (main container)

The privilege split is explicit: the dispatcher pod is a pure
control-plane client (lists nodes, manages Jobs in its own namespace) and
runs fully unprivileged under a dedicated, least-privilege ServiceAccount
(kata-rbac.yaml); only the per-node Jobs it creates carry the privileged
kata-deploy host-mutation rights.

Node selection (templates/_helpers.tpl: nodeLabelSelector / perNodeJob):
  - job.nodes: explicit node-name list passed to the dispatcher, and
  - job.nodeSelector (equality map) ANDed with
  - job.nodeSelectorExpressions (k8s label-selector requirements:
    In / NotIn / Exists / DoesNotExist),
compiled into a single label-selector string the dispatcher resolves
live. The default expressions target worker (non-control-plane) nodes, so
no custom node labeling is required; set the expressions to [] to target
all discovered nodes.

Reuses the commonEnv/commonVolume* helpers and adds the stageContainer,
serviceAccountName, dispatcherServiceAccountName, dispatcherImage and
perNodeJob helpers shared by the dispatcher and the staged Jobs. The
default (daemonset) render is unchanged.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Fabiano Fidêncio
28fce44b70 kata-deploy: extract shared pod env/volumes into helm helpers
Pull the kata-deploy container's environment block and host
volume/volumeMount definitions out of the DaemonSet template into
reusable named templates in _helpers.tpl:

  - kata-deploy.commonEnv
  - kata-deploy.commonVolumeMounts
  - kata-deploy.commonVolumes

These are derived purely from chart values and are independent of the
deployment model, so they can be shared verbatim by upcoming per-node
install/cleanup Jobs without duplicating the (large) env wiring.

Pure refactor: the rendered DaemonSet is byte-for-byte identical to
before (verified via normalized `helm template` diff across default and
multiInstallSuffix/userDropIn/customRuntimes permutations).

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Fabiano Fidêncio
225ff2209e kata-deploy: split install/cleanup into staged actions
Phase 1 of migrating kata-deploy from a DaemonSet to a staged JobSet
workflow: refactor the binary's install/cleanup flows into discrete,
independently invocable stages while keeping the existing DaemonSet
path fully working.

Add new staged subcommands that each run one step and exit, so a JobSet
can drive them as ordered initContainers/Jobs per node:

  install: host-check -> artifacts -> cri -> label
  cleanup (reverse): unlabel -> revert-cri -> remove-artifacts

`install` becomes a compatibility wrapper composing the install stages
in the canonical order, so the DaemonSet deployment model is unchanged.
The DaemonSet `cleanup` (with its DaemonSet-presence gating) is left
intact; the staged cleanup actions are added alongside it and skip that
gating since the JobSet workflow only schedules them on a real uninstall.

Each stage has an idempotent skip check so reruns are safe:
  - install label / cleanup unlabel: short-circuit via the node label
  - cleanup remove-artifacts: skip when the install dir is already gone
  - cleanup revert-cri: skip the disruptive runtime restart when the CRI
    drop-ins are already absent (new cri_drop_in_present helper)

Introduce a shared KATA_RUNTIME_LABEL constant and add rstest-based
tests covering the subcommand-name -> Action mapping, rejection of
unknown actions, and the visible/hidden help semantics.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Fabiano Fidêncio
d4205c7fcc kata-deploy: build and publish the kata-deploy-job-dispatcher image
Package and ship the dispatcher built in the previous commit so the
job-mode Helm chart has an image to run.

  - Dockerfile.components: build kata-deploy and kata-deploy-job-dispatcher
    from the same rust-builder stage (one compile), and run fmt/clippy/
    test for both crates.
  - job-dispatcher/Dockerfile: a minimal distroless/static image containing
    only the dispatcher binary and CA certs - it is an API client, so it
    needs nothing from the host.
  - local-build: kata-deploy-job-dispatcher becomes its own build component
    with its own static tarball
    (kata-deploy-static-kata-deploy-job-dispatcher.tar.zst); the shared
    rust-builder output is reused so the two components do not recompile
    the workspace locally. The payload script builds and pushes a separate
    "<kata-deploy registry>-job-dispatcher" image with the same tag scheme,
    and release.sh publishes its multi-arch manifest symmetrically.
  - CI: add kata-deploy-job-dispatcher to the build-kata-deploy-components
    matrices (its tarball is picked up by the existing kata-artifacts-*
    glob), and gate it in the kata-deploy rust static checks.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Fabiano Fidêncio
87d27e0cc8 kata-deploy-job-dispatcher: add generic per-node Job dispatcher
Add a small, deployment-agnostic dispatcher binary that runs exactly one
Kubernetes Job per selected node and paces the rollout, so callers get
guaranteed per-node coverage without encoding the fan-out in Helm.

Motivation: templating one Job per node into a Helm release does not
scale (the release Secret hits etcd's 1 MiB limit and hooks run
sequentially), and a single Indexed Job cannot guarantee per-node
coverage when paced - the scheduler ignores completed pods when
evaluating topology spread, so nodes get uneven numbers of pods. A tiny
dispatcher that enumerates nodes live and creates node-pinned Jobs itself
sidesteps both problems and keeps the Helm release O(1) in fleet size.

The dispatcher:
  - enumerates target nodes live (explicit --nodes list or
    --node-selector label selector), paginating the API;
  - stamps out one Job per node from a YAML template, pinning it with
    nodeName and an owner label for server-side filtering;
  - keeps at most --parallelism Jobs in flight, refilling as they finish,
    and sets an OwnerReference to the owner Job so the per-node Jobs are
    garbage-collected with it;
  - is a plain API client (kube): it never touches the host, so it can
    run fully unprivileged.

Node membership is resolved live on each run, not frozen at Helm
template-render time: re-running the dispatcher (e.g. via `helm upgrade`)
picks up nodes added since the last run and skips ones already done, as
the per-node stages are idempotent. The dispatcher is one-shot, however
- it does not watch the API, so nodes added while it is not running are
only covered by the next run.

job.rs holds the pure helpers (node-name sanitization, deterministic Job
naming, template instantiation, status interpretation) with rstest unit
tests; main.rs wires up the CLI and the fan-out loop.

Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com>
Assisted-by: Cursor <cursoragent@cursor.com>
2026-06-12 18:58:33 +02:00
Gregory Ling
d90178c179 runtime-rs: Fix queue_size of zero in block_rootfs
Fix BlockRootfs to save the queue_size, num_queues, logical_sector_size,
and physical_sector_size of the hypervisor's block device info in the
BlockConfig passed to the vm

Fixes #13210

Signed-off-by: Gregory Ling <17791817+glingy@users.noreply.github.com>
2026-06-12 18:24:50 +02:00
Zvonko Kaiser
a2ad9b458e Merge pull request #13215 from stevenhorsman/docs/python-cve-fixes-12th-june-2026
fix: pin idna and pymdown-extensions to remediate CVEs
2026-06-12 12:18:03 -04:00
Fabiano Fidêncio
b2376f849c Merge pull request #13203 from fidencio/topic/versions-bump-kernel
versions: Bump kernel to 6.18.35
2026-06-12 17:37:55 +02:00
Fabiano Fidêncio
56da8097c2 Merge pull request #13204 from fidencio/topic/versions-bump-qemu
versions: Bump QEMU to 11.0.1
2026-06-12 17:14:57 +02:00
Fabiano Fidêncio
110843d6e1 Merge pull request #13138 from manuelh-dev/mahuber/runt-rs-mem-file-removal
runtime(-rs): remove file_mem_backend config option
2026-06-12 17:13:04 +02:00
stevenhorsman
3c3f754f3f fix: pin idna and pymdown-extensions to remediate CVEs
Pin idna to 3.15 and pymdown-extensions to 10.21.3 to address
security vulnerabilities:

- GHSA-65pc-fj4g-8rjx (idna, severity 6.9)
- GHSA-62q4-447f-wv8h (pymdown-extensions, severity 4.3)
- GHSA-r6h4-mm7h-8pmq (pymdown-extensions, severity 2.7)

These dependencies were previously transitive and vulnerable.
They are now explicitly pinned to secure versions.

Generated-by: IBM Bob
Signed-off-by: stevenhorsman <steven@uk.ibm.com>
2026-06-12 13:28:58 +01:00
Markus Rudy
2e8f61a575 genpolicy: add missing probe fields
This commit adds fields for readiness/liveness/startup probes that were
missing so far, and adds probes to the ignored_fields test to ensure
these stay supported. None of these fields has an influence on the
generated policy, they just allow parsing valid k8s yaml.

Co-authored-by: Spyros Seimenis <sse@edgeless.systems>
Signed-off-by: Markus Rudy <mr@edgeless.systems>
2026-06-12 13:20:16 +02:00
Hyounggyu Choi
edead9e97b Merge pull request #13189 from stevenhorsman/osv-scanner-refactor
workflows: refactor osv-scanner workflows
2026-06-12 12:04:12 +02:00
Fabiano Fidêncio
e758f4b280 Merge pull request #13202 from gkurz/fix-generate-vendor
generate_vendor: Fix heavily broken logic
2026-06-12 11:48:50 +02:00
Fabiano Fidêncio
a016fd0485 Merge pull request #13198 from fidencio/topic/fix-ci-tee-static-sizing-overhead
tests: raise k8s memory/QoS pod limits for TEE runtime-rs CI
2026-06-12 11:46:56 +02:00
Fabiano Fidêncio
723f74e782 Merge pull request #13209 from fidencio/topic/fix-kata-monitor-runc-pod-runtime
tests: launch kata-monitor runc workload with explicit runtime
2026-06-12 11:40:19 +02:00
Fabiano Fidêncio
54bb736ab4 Merge pull request #13193 from BbolroC/set-nightly-for-qemu-coco-dev-runtime-rs-on-s390x
GHA: Set nightly/dev builds for qemu-coco-dev-runtime-rs on s390x
2026-06-12 11:21:33 +02:00
Greg Kurz
eac5dd2907 generate_vendor: Fix heavily broken logic
While checking the content of the vendor tarball artifact in the 3.31.0
release page, I realized that it is lacking most of the rust code and
all the go code. It turns out that the script is badly broken in many
ways :

1. Cargo workspace conflicts: Vendored dependencies were treated as
   workspace members, causing "current package believes it's in a
   workspace when it's not" errors. Fixed by adding vendor directory
   exclusions to root Cargo.toml.

2. Missing Go vendoring: Script only searched for Cargo.lock files,
   never processing go.mod files despite having a case statement for
   them. Fixed by adding go.mod to the find command with '-o -name go.mod'.

3. Wrong tar execution directory: Script ran tar from release/ directory
   but vendor_dir_list contained paths relative to repo root (./vendor,
   ./src/agent/vendor, etc.), causing "Cannot stat" errors. Fixed by
   moving tar command before final popd.

4. Relative tarball path: Since tar now runs from repo root, converted
   tarball path to absolute to ensure it's created in the release
   directory.

5. Vendored go.mod pollution: Added '-path ./vendor -prune' to find
   command to exclude vendor directory, preventing the script from
   finding go.mod files inside vendored Rust dependencies.

The fixes are simple enough they can be squashed into a single
commit.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Signed-off-by: Greg Kurz <groug@kaod.org>
2026-06-12 10:06:53 +02:00
Fupan Li
9553614f32 Merge pull request #12772 from Apokleos/nydus-standalone
runtime-rs: Nydus standalone mode support in runtime-rs
2026-06-12 10:36:17 +08:00