From e04a4326ecfd8a4e51913e457aeeb6f0b26708ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Fri, 29 May 2026 23:55:17 +0200 Subject: [PATCH 1/9] tools: build kata-monitor image from shim-v2-go tarball MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build kata-monitor images by extracting the binary from the shim-v2-go tarball and shipping it on top of gcr.io/distroless/static-debian13. Because the binary is built inside an Ubuntu (glibc) toolchain it cannot run on a pure musl/alpine base — users hit __fprintf_chk / __vfprintf_chk relocation errors. To get a small, distroless runtime image we use the same pattern as tools/packaging/kata-deploy/Dockerfile: copy the glibc libraries the binary needs (plus the dynamic linker) via ldd from a glibc base image. In order to do so, we also added a helper script to build and publish architecture-specific monitor images from tarball artifacts. Reported-by: Steve Linde Signed-off-by: Fabiano Fidêncio Assisted-by: OpenAI Codex --- tools/packaging/kata-monitor/Dockerfile | 86 ++++++++++++++----- .../build-and-upload-from-tarball.sh | 51 +++++++++++ 2 files changed, 117 insertions(+), 20 deletions(-) create mode 100755 tools/packaging/kata-monitor/build-and-upload-from-tarball.sh diff --git a/tools/packaging/kata-monitor/Dockerfile b/tools/packaging/kata-monitor/Dockerfile index d71eaaff3d..f23802396e 100644 --- a/tools/packaging/kata-monitor/Dockerfile +++ b/tools/packaging/kata-monitor/Dockerfile @@ -1,28 +1,74 @@ # Copyright (c) 2020 Eric Ernst +# Copyright (c) 2026 NVIDIA # SPDX-License-Identifier: Apache-2.0 -ARG GO_VERSION -FROM golang:${GO_VERSION}-alpine AS builder +# +# Build context: extracted kata-static shim-v2-go tarball root. +# +# Expected file in context: +# ./opt/kata/bin/kata-monitor +# +# The kata-monitor binary is built inside an Ubuntu (glibc) toolchain +# as part of the shim-v2-go static build, so it is dynamically linked +# against glibc. We assemble its runtime dependencies via `ldd` from +# a glibc base image and copy them into a distroless/static runtime +# image, matching the same pattern used by +# tools/packaging/kata-deploy/Dockerfile. -RUN apk add --no-cache bash curl git make build-base -WORKDIR /go/src/github.com/kata-containers/kata-containers/src/runtime +# Stage 1: discover and copy the glibc libraries the binary needs. +# hadolint ignore=DL3007 +FROM debian:trixie-slim AS runtime-assembler -COPY src/runtime/go.* . -RUN --mount=type=cache,target=/go/pkg/mod \ - --mount=type=cache,target=/root/.cache/go-build \ - go mod download +SHELL ["/bin/bash", "-o", "pipefail", "-c"] -COPY . /go/src/github.com/kata-containers/kata-containers -RUN --mount=type=cache,target=/go/pkg/mod \ - --mount=type=cache,target=/root/.cache/go-build \ - make SKIP_GO_VERSION_CHECK=true monitor +COPY opt/kata/bin/kata-monitor /tmp/kata-monitor -# run tests -RUN --mount=type=cache,target=/go/pkg/mod \ - --mount=type=cache,target=/root/.cache/go-build \ - cd pkg/kata-monitor/ && go test -c -o /tmp/tests -RUN /tmp/tests +RUN \ + set -eux; \ + mkdir -p /output/lib /output/lib64; \ + echo "Libraries needed by kata-monitor on $(uname -m):"; \ + ldd /tmp/kata-monitor || true; \ + # Copy each shared library reported by ldd ("=>" lines). + ldd /tmp/kata-monitor 2>/dev/null | grep "=>" | awk '{print $3}' | sort -u | \ + while read -r lib; do \ + if [ -n "${lib}" ] && [ -f "${lib}" ]; then \ + dest_dir="/output$(dirname "${lib}")"; \ + mkdir -p "${dest_dir}"; \ + cp -Ln "${lib}" "${dest_dir}/" || true; \ + echo " Copied lib: ${lib}"; \ + fi; \ + done; \ + # Copy the dynamic linker too: ldd does not include it in the "=>" + # lines. Cover all four target architectures: + # x86_64 -> /lib64/ld-linux-x86-64.so.2 + # aarch64 -> /lib/ld-linux-aarch64.so.1 + # s390x -> /lib/ld64.so.1 + # ppc64le -> /lib64/ld64.so.2 + for ld in /lib*/ld-linux-*.so.* /lib*/ld64.so.*; do \ + [ -f "${ld}" ] || continue; \ + dest_dir="/output$(dirname "${ld}")"; \ + mkdir -p "${dest_dir}"; \ + cp -Ln "${ld}" "${dest_dir}/" || true; \ + echo " Copied linker: ${ld}"; \ + done + +# Stage 2: final distroless image. +# +# We deliberately track the rolling `latest` tag rather than pinning a +# digest. distroless/static-debian13 publishes no semver tags and is +# rebuilt frequently to pick up base-image CVE fixes, so following +# `latest` keeps the kata-monitor runtime on the newest patched base. +# The image only carries the handful of glibc libraries we copy in plus +# the kata-monitor binary, so the blast radius of an unexpected base +# bump is tiny. hadolint's "pin the version" check is therefore not +# something we want here. +# hadolint ignore=DL3007 +FROM gcr.io/distroless/static-debian13:latest + +COPY --from=runtime-assembler /output/lib/ /lib/ +COPY --from=runtime-assembler /output/lib64/ /lib64/ +COPY opt/kata/bin/kata-monitor /usr/bin/kata-monitor + +EXPOSE 8090 -FROM alpine:3.14 -COPY --from=builder /go/src/github.com/kata-containers/kata-containers/src/runtime/kata-monitor /usr/bin/kata-monitor -CMD ["-h"] ENTRYPOINT ["/usr/bin/kata-monitor"] +CMD ["--help"] diff --git a/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh b/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh new file mode 100755 index 0000000000..30b2257566 --- /dev/null +++ b/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2026 NVIDIA +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -o errexit +set -o nounset +set -o pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +repo_root_dir="$(cd "${script_dir}/../../.." && pwd)" + +image_ref="${1:?image ref is required (e.g. quay.io/org/repo:tag)}" +shim_tarball="${2:?path to kata-static-shim-v2-go.tar.zst is required}" +push_image="${3:-true}" + +case "$(uname -m)" in + x86_64) platform_arch="amd64" ;; + aarch64) platform_arch="arm64" ;; + s390x) platform_arch="s390x" ;; + ppc64le) platform_arch="ppc64le" ;; + *) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;; +esac + +tmpdir="$(mktemp -d)" +cleanup() { + rm -rf "${tmpdir}" +} +trap cleanup EXIT + +tar --zstd -xf "${shim_tarball}" -C "${tmpdir}" + +if [[ ! -x "${tmpdir}/opt/kata/bin/kata-monitor" ]]; then + echo "kata-monitor binary not found in ${shim_tarball}" >&2 + exit 1 +fi + +push_flag=() +if [[ "${push_image}" == "true" ]]; then + push_flag+=(--push) +fi + +docker buildx build \ + --platform "linux/${platform_arch}" \ + --provenance false --sbom false \ + -f "${repo_root_dir}/tools/packaging/kata-monitor/Dockerfile" \ + --tag "${image_ref}" \ + "${push_flag[@]}" \ + "${tmpdir}" From 0d6234e7be1075aa651cd574d226837a388d6555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Sat, 30 May 2026 10:19:39 +0200 Subject: [PATCH 2/9] ci: share kata image publishing workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unify kata-deploy and kata-monitor image publishing behind a single reusable workflow, and rename workflow files to generic kata-images names. Signed-off-by: Fabiano Fidêncio Assisted-by: OpenAI Codex --- .github/workflows/ci.yaml | 84 ++++++- .github/workflows/payload-after-push.yaml | 118 +++++++++- .../publish-kata-deploy-payload.yaml | 113 --------- .github/workflows/publish-kata-images.yaml | 214 ++++++++++++++++++ .github/workflows/release-kata-images.yaml | 111 +++++++++ .github/workflows/release.yaml | 12 +- .../build-and-upload-from-tarball.sh | 28 ++- 7 files changed, 554 insertions(+), 126 deletions(-) delete mode 100644 .github/workflows/publish-kata-deploy-payload.yaml create mode 100644 .github/workflows/publish-kata-images.yaml create mode 100644 .github/workflows/release-kata-images.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 33f305158a..b89957464b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -70,7 +70,7 @@ jobs: permissions: contents: read packages: write - uses: ./.github/workflows/publish-kata-deploy-payload.yaml + uses: ./.github/workflows/publish-kata-images.yaml with: tarball-suffix: -${{ inputs.tag }} registry: ghcr.io @@ -83,6 +83,25 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + publish-kata-monitor-image-amd64: + needs: build-kata-static-tarball-amd64 + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-kata-images.yaml + with: + tarball-suffix: -${{ inputs.tag }} + registry: ghcr.io + repo: ${{ github.repository_owner }}/kata-monitor-ci + tag: ${{ inputs.tag }}-amd64 + commit-hash: ${{ inputs.commit-hash }} + target-branch: ${{ inputs.target-branch }} + runner: ubuntu-22.04 + arch: amd64 + image-kind: monitor + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + build-kata-static-tarball-arm64: permissions: contents: read @@ -102,7 +121,7 @@ jobs: permissions: contents: read packages: write - uses: ./.github/workflows/publish-kata-deploy-payload.yaml + uses: ./.github/workflows/publish-kata-images.yaml with: tarball-suffix: -${{ inputs.tag }} registry: ghcr.io @@ -115,6 +134,25 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + publish-kata-monitor-image-arm64: + needs: build-kata-static-tarball-arm64 + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-kata-images.yaml + with: + tarball-suffix: -${{ inputs.tag }} + registry: ghcr.io + repo: ${{ github.repository_owner }}/kata-monitor-ci + tag: ${{ inputs.tag }}-arm64 + commit-hash: ${{ inputs.commit-hash }} + target-branch: ${{ inputs.target-branch }} + runner: ubuntu-24.04-arm + arch: arm64 + image-kind: monitor + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + build-kata-static-tarball-s390x: permissions: contents: read @@ -146,7 +184,7 @@ jobs: permissions: contents: read packages: write - uses: ./.github/workflows/publish-kata-deploy-payload.yaml + uses: ./.github/workflows/publish-kata-images.yaml with: tarball-suffix: -${{ inputs.tag }} registry: ghcr.io @@ -159,12 +197,31 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + publish-kata-monitor-image-s390x: + needs: build-kata-static-tarball-s390x + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-kata-images.yaml + with: + tarball-suffix: -${{ inputs.tag }} + registry: ghcr.io + repo: ${{ github.repository_owner }}/kata-monitor-ci + tag: ${{ inputs.tag }}-s390x + commit-hash: ${{ inputs.commit-hash }} + target-branch: ${{ inputs.target-branch }} + runner: ubuntu-24.04-s390x + arch: s390x + image-kind: monitor + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + publish-kata-deploy-payload-ppc64le: needs: build-kata-static-tarball-ppc64le permissions: contents: read packages: write - uses: ./.github/workflows/publish-kata-deploy-payload.yaml + uses: ./.github/workflows/publish-kata-images.yaml with: tarball-suffix: -${{ inputs.tag }} registry: ghcr.io @@ -177,6 +234,25 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + publish-kata-monitor-image-ppc64le: + needs: build-kata-static-tarball-ppc64le + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-kata-images.yaml + with: + tarball-suffix: -${{ inputs.tag }} + registry: ghcr.io + repo: ${{ github.repository_owner }}/kata-monitor-ci + tag: ${{ inputs.tag }}-ppc64le + commit-hash: ${{ inputs.commit-hash }} + target-branch: ${{ inputs.target-branch }} + runner: ubuntu-24.04-ppc64le + arch: ppc64le + image-kind: monitor + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + build-and-publish-tee-confidential-unencrypted-image: name: build-and-publish-tee-confidential-unencrypted-image permissions: diff --git a/.github/workflows/payload-after-push.yaml b/.github/workflows/payload-after-push.yaml index a6042cf4cf..1bde58ea51 100644 --- a/.github/workflows/payload-after-push.yaml +++ b/.github/workflows/payload-after-push.yaml @@ -72,7 +72,7 @@ jobs: permissions: contents: read packages: write - uses: ./.github/workflows/publish-kata-deploy-payload.yaml + uses: ./.github/workflows/publish-kata-images.yaml with: commit-hash: ${{ github.sha }} registry: quay.io @@ -81,6 +81,7 @@ jobs: target-branch: ${{ github.ref_name }} runner: ubuntu-22.04 arch: amd64 + image-kind: deploy secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} @@ -89,7 +90,7 @@ jobs: permissions: contents: read packages: write - uses: ./.github/workflows/publish-kata-deploy-payload.yaml + uses: ./.github/workflows/publish-kata-images.yaml with: commit-hash: ${{ github.sha }} registry: quay.io @@ -98,6 +99,7 @@ jobs: target-branch: ${{ github.ref_name }} runner: ubuntu-24.04-arm arch: arm64 + image-kind: deploy secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} @@ -106,7 +108,7 @@ jobs: permissions: contents: read packages: write - uses: ./.github/workflows/publish-kata-deploy-payload.yaml + uses: ./.github/workflows/publish-kata-images.yaml with: commit-hash: ${{ github.sha }} registry: quay.io @@ -115,6 +117,7 @@ jobs: target-branch: ${{ github.ref_name }} runner: s390x arch: s390x + image-kind: deploy secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} @@ -123,7 +126,7 @@ jobs: permissions: contents: read packages: write - uses: ./.github/workflows/publish-kata-deploy-payload.yaml + uses: ./.github/workflows/publish-kata-images.yaml with: commit-hash: ${{ github.sha }} registry: quay.io @@ -132,6 +135,79 @@ jobs: target-branch: ${{ github.ref_name }} runner: ubuntu-24.04-ppc64le arch: ppc64le + image-kind: deploy + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + + publish-kata-monitor-image-amd64: + needs: build-assets-amd64 + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-kata-images.yaml + with: + commit-hash: ${{ github.sha }} + registry: quay.io + repo: kata-containers/kata-monitor-ci + tag: kata-monitor-latest-amd64 + target-branch: ${{ github.ref_name }} + runner: ubuntu-22.04 + arch: amd64 + image-kind: monitor + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + + publish-kata-monitor-image-arm64: + needs: build-assets-arm64 + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-kata-images.yaml + with: + commit-hash: ${{ github.sha }} + registry: quay.io + repo: kata-containers/kata-monitor-ci + tag: kata-monitor-latest-arm64 + target-branch: ${{ github.ref_name }} + runner: ubuntu-24.04-arm + arch: arm64 + image-kind: monitor + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + + publish-kata-monitor-image-s390x: + needs: build-assets-s390x + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-kata-images.yaml + with: + commit-hash: ${{ github.sha }} + registry: quay.io + repo: kata-containers/kata-monitor-ci + tag: kata-monitor-latest-s390x + target-branch: ${{ github.ref_name }} + runner: s390x + arch: s390x + image-kind: monitor + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + + publish-kata-monitor-image-ppc64le: + needs: build-assets-ppc64le + permissions: + contents: read + packages: write + uses: ./.github/workflows/publish-kata-images.yaml + with: + commit-hash: ${{ github.sha }} + registry: quay.io + repo: kata-containers/kata-monitor-ci + tag: kata-monitor-latest-ppc64le + target-branch: ${{ github.ref_name }} + runner: ubuntu-24.04-ppc64le + arch: ppc64le + image-kind: monitor secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} @@ -162,6 +238,40 @@ jobs: KATA_DEPLOY_IMAGE_TAGS: "kata-containers-latest" KATA_DEPLOY_REGISTRIES: "quay.io/kata-containers/kata-deploy-ci" + publish-kata-monitor-manifest: + name: publish-kata-monitor-manifest + runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + needs: [publish-kata-monitor-image-amd64, publish-kata-monitor-image-arm64, publish-kata-monitor-image-s390x, publish-kata-monitor-image-ppc64le] + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Login to Kata Containers ghcr.io + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to Kata Containers quay.io + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 + with: + registry: quay.io + username: ${{ vars.QUAY_DEPLOYER_USERNAME }} + password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + + - name: Push multi-arch monitor manifest + run: | + ./tools/packaging/release/release.sh publish-multiarch-manifest + env: + KATA_DEPLOY_IMAGE_TAGS: "kata-monitor-latest" + KATA_DEPLOY_REGISTRIES: "quay.io/kata-containers/kata-monitor-ci ghcr.io/${{ github.repository_owner }}/kata-monitor-ci" + upload-helm-chart-tarball: name: upload-helm-chart-tarball needs: publish-manifest diff --git a/.github/workflows/publish-kata-deploy-payload.yaml b/.github/workflows/publish-kata-deploy-payload.yaml deleted file mode 100644 index aa8d1bbf87..0000000000 --- a/.github/workflows/publish-kata-deploy-payload.yaml +++ /dev/null @@ -1,113 +0,0 @@ -name: CI | Publish kata-deploy payload -on: - workflow_call: - inputs: - tarball-suffix: - required: false - type: string - registry: - required: true - type: string - repo: - required: true - type: string - tag: - required: true - type: string - commit-hash: - required: false - type: string - target-branch: - required: false - type: string - default: "" - runner: - default: 'ubuntu-22.04' - description: The runner to execute the workflow on. Defaults to 'ubuntu-22.04'. - required: false - type: string - arch: - description: The arch of the tarball. - required: true - type: string - secrets: - QUAY_DEPLOYER_PASSWORD: - required: true - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ inputs.arch }}-publish-deploy - cancel-in-progress: true - -permissions: {} - -jobs: - kata-payload: - name: kata-payload - permissions: - contents: read - packages: write - runs-on: ${{ inputs.runner }} - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - ref: ${{ inputs.commit-hash }} - fetch-depth: 0 - persist-credentials: false - - - name: Remove unnecessary directories to free up space - run: | - sudo rm -rf /usr/local/.ghcup - sudo rm -rf /opt/hostedtoolcache/CodeQL - sudo rm -rf /usr/local/lib/android - sudo rm -rf /usr/share/dotnet - sudo rm -rf /opt/ghc - sudo rm -rf /usr/local/share/boost - sudo rm -rf /usr/lib/jvm - sudo rm -rf /usr/share/swift - sudo rm -rf /usr/local/share/powershell - sudo rm -rf /usr/local/julia* - sudo rm -rf /opt/az - sudo rm -rf /usr/local/share/chromium - sudo rm -rf /opt/microsoft - sudo rm -rf /opt/google - sudo rm -rf /usr/lib/firefox - - - name: Rebase atop of the latest target branch - run: | - ./tests/git-helper.sh "rebase-atop-of-the-latest-target-branch" - env: - TARGET_BRANCH: ${{ inputs.target-branch }} - - - name: get-kata-artifacts for ${{ inputs.arch }} - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 - with: - pattern: kata-artifacts-${{ inputs.arch }}-*${{ inputs.tarball-suffix }} - path: tools/packaging/kata-deploy/local-build/build - merge-multiple: true - - - name: Login to Kata Containers quay.io - if: ${{ inputs.registry == 'quay.io' }} - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 - with: - registry: quay.io - username: ${{ vars.QUAY_DEPLOYER_USERNAME }} - password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} - - - name: Login to Kata Containers ghcr.io - if: ${{ inputs.registry == 'ghcr.io' }} - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: build-and-push-kata-payload for ${{ inputs.arch }} - id: build-and-push-kata-payload - env: - REGISTRY: ${{ inputs.registry }} - REPO: ${{ inputs.repo }} - TAG: ${{ inputs.tag }} - run: | - ./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \ - "${REGISTRY}/${REPO}" \ - "${TAG}" diff --git a/.github/workflows/publish-kata-images.yaml b/.github/workflows/publish-kata-images.yaml new file mode 100644 index 0000000000..560fb67e98 --- /dev/null +++ b/.github/workflows/publish-kata-images.yaml @@ -0,0 +1,214 @@ +name: CI | publish-kata-images +on: + workflow_call: + inputs: + tarball-suffix: + required: false + type: string + registry: + required: true + type: string + repo: + required: true + type: string + tag: + required: true + type: string + tags: + description: Space-separated list of tags; overrides `tag` when set. + required: false + type: string + default: "" + tag-suffix: + description: Optional suffix appended to each tag (for example, -amd64). + required: false + type: string + default: "" + commit-hash: + required: false + type: string + target-branch: + required: false + type: string + default: "" + runner: + default: 'ubuntu-22.04' + description: The runner to execute the workflow on. Defaults to 'ubuntu-22.04'. + required: false + type: string + arch: + description: The arch of the tarball. + required: true + type: string + image-kind: + description: Image kind to publish (`deploy` or `monitor`). + required: false + type: string + default: deploy + image-kinds-json: + description: JSON list of image kinds, e.g. ["deploy","monitor"]. + required: false + type: string + default: "" + artifact-name: + description: Optional artifact name to download instead of a pattern. + required: false + type: string + default: "" + push: + description: Whether to push image(s) to registry. + required: false + type: string + default: "true" + secrets: + QUAY_DEPLOYER_PASSWORD: + required: true + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ inputs.arch }}-${{ inputs.repo }}-${{ inputs.tag }}-${{ inputs.image-kind }}-publish-image + cancel-in-progress: true + +permissions: {} + +jobs: + publish: + name: kata-image + permissions: + contents: read + packages: write + runs-on: ${{ inputs.runner }} + strategy: + matrix: + image-kind: ${{ fromJson(inputs.image-kinds-json != '' && inputs.image-kinds-json || format('["{0}"]', inputs.image-kind)) }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ inputs.commit-hash }} + fetch-depth: 0 + persist-credentials: false + + - name: Remove unnecessary directories to free up space + run: | + sudo rm -rf /usr/local/.ghcup + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo rm -rf /usr/local/lib/android + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf /usr/local/share/boost + sudo rm -rf /usr/lib/jvm + sudo rm -rf /usr/share/swift + sudo rm -rf /usr/local/share/powershell + sudo rm -rf /usr/local/julia* + sudo rm -rf /opt/az + sudo rm -rf /usr/local/share/chromium + sudo rm -rf /opt/microsoft + sudo rm -rf /opt/google + sudo rm -rf /usr/lib/firefox + + - name: Rebase atop of the latest target branch + run: | + ./tests/git-helper.sh "rebase-atop-of-the-latest-target-branch" + env: + TARGET_BRANCH: ${{ inputs.target-branch }} + + - name: get-kata-artifacts for ${{ inputs.arch }} + if: ${{ inputs.artifact-name == '' && matrix.image-kind == 'deploy' }} + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + pattern: kata-artifacts-${{ inputs.arch }}-*${{ inputs.tarball-suffix }} + path: tools/packaging/kata-deploy/local-build/build + merge-multiple: true + + - name: get-kata-static-tarball for ${{ inputs.arch }} + if: ${{ inputs.artifact-name == '' && matrix.image-kind == 'monitor' }} + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: kata-static-tarball-${{ inputs.arch }}${{ inputs.tarball-suffix }} + path: tools/packaging/kata-deploy/local-build/build + + - name: get-kata-artifact by name for ${{ inputs.arch }} + if: ${{ inputs.artifact-name != '' }} + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: ${{ inputs.artifact-name }} + path: tools/packaging/kata-deploy/local-build/build + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + + - name: Login to Kata Containers quay.io + if: ${{ inputs.registry == 'quay.io' && inputs.push == 'true' }} + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 + with: + registry: quay.io + username: ${{ vars.QUAY_DEPLOYER_USERNAME }} + password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + + - name: Login to Kata Containers ghcr.io + if: ${{ (inputs.registry == 'ghcr.io' || inputs.registry == 'quay.io') && inputs.push == 'true' }} + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: build-and-push image for ${{ inputs.arch }} + id: build-and-push-kata-payload + env: + REGISTRY: ${{ inputs.registry }} + REPO: ${{ inputs.repo }} + TAG: ${{ inputs.tag }} + TAGS: ${{ inputs.tags }} + TAG_SUFFIX: ${{ inputs.tag-suffix }} + IMAGE_KIND: ${{ matrix.image-kind }} + PUSH_IMAGE: ${{ inputs.push }} + run: | + if [ "${TAGS}" != "" ]; then + tags="${TAGS}" + else + tags="${TAG}" + fi + + case "${IMAGE_KIND}" in + deploy) + for t in ${tags}; do + final_tag="${t}${TAG_SUFFIX}" + ./tools/packaging/kata-deploy/local-build/kata-deploy-build-and-upload-payload.sh \ + "${REGISTRY}/${REPO}" \ + "${final_tag}" + done + ;; + monitor) + registries="${REGISTRY}" + if [ "${REGISTRY}" = "quay.io" ]; then + registries="quay.io ghcr.io" + fi + + build_dir="tools/packaging/kata-deploy/local-build/build" + monitor_tarball="${build_dir}/kata-static.tar.zst" + + if [ ! -f "${monitor_tarball}" ] && [ -f "${build_dir}/kata-static-shim-v2-go.tar.zst" ]; then + # Backward compatibility with older artifacts. + monitor_tarball="${build_dir}/kata-static-shim-v2-go.tar.zst" + fi + + if [ ! -f "${monitor_tarball}" ]; then + echo "Neither kata-static.tar.zst nor kata-static-shim-v2-go.tar.zst found" >&2 + exit 1 + fi + + for r in ${registries}; do + for t in ${tags}; do + final_tag="${t}${TAG_SUFFIX}" + ./tools/packaging/kata-monitor/build-and-upload-from-tarball.sh \ + "${r}/${REPO}:${final_tag}" \ + "${monitor_tarball}" \ + "${PUSH_IMAGE}" + done + done + ;; + *) + echo "Invalid image-kind: ${IMAGE_KIND}" >&2 + exit 1 + ;; + esac diff --git a/.github/workflows/release-kata-images.yaml b/.github/workflows/release-kata-images.yaml new file mode 100644 index 0000000000..20bcfcc285 --- /dev/null +++ b/.github/workflows/release-kata-images.yaml @@ -0,0 +1,111 @@ +name: release-kata-images +on: + workflow_call: + inputs: + registries: + description: "Space-separated list of registries to push to." + required: false + type: string + default: "quay.io/kata-containers/kata-monitor ghcr.io/kata-containers/kata-monitor" + secrets: + QUAY_DEPLOYER_PASSWORD: + required: true + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-kata-monitor-release + cancel-in-progress: false + +permissions: {} + +jobs: + resolve-tags: + name: Resolve image tags + runs-on: ubuntu-22.04 + outputs: + tags: ${{ steps.tags.outputs.tags }} + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Resolve tags + id: tags + run: | + tag=$(echo "${GITHUB_REF}" | cut -d/ -f3-) + if [ "${tag}" = "main" ]; then + tag=$(./tools/packaging/release/release.sh release-version) + echo "tags=${tag} latest" >> "$GITHUB_OUTPUT" + else + echo "tags=${tag}" >> "$GITHUB_OUTPUT" + fi + + publish-monitor: + needs: resolve-tags + permissions: + contents: read + packages: write + strategy: + matrix: + include: + - arch: amd64 + tag_suffix: -amd64 + runner: ubuntu-22.04 + - arch: arm64 + tag_suffix: -arm64 + runner: ubuntu-24.04-arm + - arch: s390x + tag_suffix: -s390x + runner: ubuntu-24.04-s390x + - arch: ppc64le + tag_suffix: -ppc64le + runner: ubuntu-24.04-ppc64le + uses: ./.github/workflows/publish-kata-images.yaml + with: + commit-hash: ${{ github.sha }} + registry: quay.io + repo: kata-containers/kata-monitor + tag: latest + tags: ${{ needs.resolve-tags.outputs.tags }} + tag-suffix: ${{ matrix.tag_suffix }} + runner: ${{ matrix.runner }} + arch: ${{ matrix.arch }} + image-kind: monitor + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + + publish-multi-arch-manifest: + name: Publish multi-arch manifest + needs: [resolve-tags, publish-monitor] + runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Login to Kata Containers ghcr.io + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to Kata Containers quay.io + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 + with: + registry: quay.io + username: ${{ vars.QUAY_DEPLOYER_USERNAME }} + password: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + + - name: Publish multi-arch manifest + env: + TAGS: ${{ needs.resolve-tags.outputs.tags }} + REGISTRIES: ${{ inputs.registries }} + run: | + KATA_DEPLOY_IMAGE_TAGS="${TAGS}" \ + KATA_DEPLOY_REGISTRIES="${REGISTRIES}" \ + ./tools/packaging/release/release.sh publish-multiarch-manifest diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e0cada5303..5802645a9c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -81,6 +81,16 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + publish-kata-monitor-image: + name: publish-kata-monitor-image + needs: [build-and-push-assets-amd64, build-and-push-assets-arm64, build-and-push-assets-s390x, build-and-push-assets-ppc64le] + permissions: + contents: read + packages: write + uses: ./.github/workflows/release-kata-images.yaml + secrets: + QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} + publish-multi-arch-images: name: publish-multi-arch-images runs-on: ubuntu-22.04 @@ -295,7 +305,7 @@ jobs: publish-release: name: publish-release - needs: [ build-and-push-assets-amd64, build-and-push-assets-arm64, build-and-push-assets-s390x, build-and-push-assets-ppc64le, publish-multi-arch-images, upload-multi-arch-static-tarball, upload-versions-yaml, upload-cargo-vendored-tarball, upload-libseccomp-tarball ] + needs: [ build-and-push-assets-amd64, build-and-push-assets-arm64, build-and-push-assets-s390x, build-and-push-assets-ppc64le, publish-multi-arch-images, publish-kata-monitor-image, upload-multi-arch-static-tarball, upload-versions-yaml, upload-cargo-vendored-tarball, upload-libseccomp-tarball ] runs-on: ubuntu-22.04 permissions: contents: write # needed for the `gh release` commands diff --git a/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh b/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh index 30b2257566..834ddf0320 100755 --- a/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh +++ b/tools/packaging/kata-monitor/build-and-upload-from-tarball.sh @@ -13,7 +13,7 @@ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" repo_root_dir="$(cd "${script_dir}/../../.." && pwd)" image_ref="${1:?image ref is required (e.g. quay.io/org/repo:tag)}" -shim_tarball="${2:?path to kata-static-shim-v2-go.tar.zst is required}" +source_tarball="${2:?path to kata-static.tar.zst is required}" push_image="${3:-true}" case "$(uname -m)" in @@ -30,13 +30,33 @@ cleanup() { } trap cleanup EXIT -tar --zstd -xf "${shim_tarball}" -C "${tmpdir}" +# Extract only kata-monitor from the source tarball. +monitor_entry="" +while IFS= read -r entry; do + case "${entry}" in + opt/kata/bin/kata-monitor|./opt/kata/bin/kata-monitor) + monitor_entry="${entry}" + break + ;; + esac +done < <(tar --zstd -tf "${source_tarball}") -if [[ ! -x "${tmpdir}/opt/kata/bin/kata-monitor" ]]; then - echo "kata-monitor binary not found in ${shim_tarball}" >&2 +if [[ -z "${monitor_entry}" ]]; then + echo "kata-monitor binary entry not found in ${source_tarball}" >&2 exit 1 fi +tar --zstd -xf "${source_tarball}" -C "${tmpdir}" "${monitor_entry}" +monitor_entry="${monitor_entry#./}" +monitor_binary="${tmpdir}/${monitor_entry}" + +if [[ ! -f "${monitor_binary}" ]]; then + echo "kata-monitor binary extraction failed from ${source_tarball}" >&2 + exit 1 +fi + +chmod +x "${monitor_binary}" + push_flag=() if [[ "${push_image}" == "true" ]]; then push_flag+=(--push) From 2b6efda67d9049f0567de5b071b6693b62e78905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Wed, 3 Jun 2026 12:47:58 +0200 Subject: [PATCH 3/9] docs: document the standalone kata-monitor image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kata-monitor is published as a standalone container image starting with 3.32.0; point users at it from the metrics design doc and the Prometheus-on-Kubernetes how-to, and switch the DaemonSet manifest to the dedicated image (keeping the runtime endpoint/listen settings and hostPath cleanups). Signed-off-by: Fabiano Fidêncio Assisted-by: OpenAI Codex --- docs/design/kata-2-0-metrics.md | 7 ++++++ docs/how-to/data/kata-monitor-daemonset.yml | 27 ++++++++++++--------- docs/how-to/how-to-set-prometheus-in-k8s.md | 14 +++++++++++ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/docs/design/kata-2-0-metrics.md b/docs/design/kata-2-0-metrics.md index df7a5a7ef5..8faebf9c8b 100644 --- a/docs/design/kata-2-0-metrics.md +++ b/docs/design/kata-2-0-metrics.md @@ -46,6 +46,13 @@ For a quick evaluation, you can check out [this how to](../how-to/how-to-set-pro ### Kata monitor +Starting with Kata Containers 3.32.0, the `kata-monitor` binary is also published as a standalone, multi-arch container image alongside every release: + +- Released image: `quay.io/kata-containers/kata-monitor:` (mirrored to `ghcr.io/kata-containers/kata-monitor`). The `latest` tag always points at the most recent release. +- Testing image (tracking `main`): `quay.io/kata-containers/kata-monitor-ci:latest` (mirrored to `ghcr.io/kata-containers/kata-monitor-ci`). + +See the [how-to on running `kata-monitor` in a Kubernetes cluster](../how-to/how-to-set-prometheus-in-k8s.md) for a complete deployment example. + The `kata-monitor` management agent should be started on each node where the Kata containers runtime is installed. `kata-monitor` will: > **Note**: a *node* running Kata containers will be either a single host system or a worker node belonging to a K8s cluster capable of running Kata pods. diff --git a/docs/how-to/data/kata-monitor-daemonset.yml b/docs/how-to/data/kata-monitor-daemonset.yml index 6fea21cc3d..94646dee91 100644 --- a/docs/how-to/data/kata-monitor-daemonset.yml +++ b/docs/how-to/data/kata-monitor-daemonset.yml @@ -23,12 +23,19 @@ spec: annotations: prometheus.io/scrape: "true" spec: - hostNetwork: true containers: - name: kata-monitor - image: quay.io/kata-containers/kata-monitor:2.0.0 + # The `kata-monitor` image is published as part of every Kata + # Containers release starting with 3.32.0. Pinning to a specific + # release tag (e.g. `3.32.0`) is strongly recommended for + # production deployments. Use + # `quay.io/kata-containers/kata-monitor-ci:latest` to track the + # tip of `main`. + image: quay.io/kata-containers/kata-monitor:latest args: + - -listen-address=0.0.0.0:8090 - -log-level=debug + - -runtime-endpoint=unix:///run/containerd/containerd.sock ports: - containerPort: 8090 resources: @@ -39,23 +46,19 @@ spec: cpu: 200m memory: 300Mi volumeMounts: - - name: containerdtask - mountPath: /run/containerd/io.containerd.runtime.v2.task/ - readOnly: true - - name: containerdsocket - mountPath: /run/containerd/containerd.sock + - name: containerd-sock + mountPath: /run/containerd readOnly: true - name: sbs mountPath: /run/vc/sbs/ readOnly: true terminationGracePeriodSeconds: 30 volumes: - - name: containerdtask + - name: containerd-sock hostPath: - path: /run/containerd/io.containerd.runtime.v2.task/ - - name: containerdsocket - hostPath: - path: /run/containerd/containerd.sock + path: /run/containerd + type: Directory - name: sbs hostPath: path: /run/vc/sbs/ + type: DirectoryOrCreate diff --git a/docs/how-to/how-to-set-prometheus-in-k8s.md b/docs/how-to/how-to-set-prometheus-in-k8s.md index 0d2e281baa..7ee451b4d6 100644 --- a/docs/how-to/how-to-set-prometheus-in-k8s.md +++ b/docs/how-to/how-to-set-prometheus-in-k8s.md @@ -49,6 +49,14 @@ go_gc_duration_seconds{quantile="0.75"} 0.000229911 ## Configure `kata-monitor` +`kata-monitor` is published as a standalone, multi-arch container image as +part of every Kata Containers release. Two flavours are available: + +| Image | Purpose | +|---|---| +| `quay.io/kata-containers/kata-monitor:` (also mirrored to `ghcr.io/kata-containers/kata-monitor`) | Released image, built and pushed by the Kata Containers release workflow. A `latest` tag tracks the most recent release. | +| `quay.io/kata-containers/kata-monitor-ci:latest` (also mirrored to `ghcr.io/kata-containers/kata-monitor-ci`) | Testing image, rebuilt and pushed from every commit landing on `main`. Use this only for evaluation against unreleased changes. | + `kata-monitor` can be started on the cluster as follows: ``` @@ -57,6 +65,12 @@ $ kubectl apply -f https://raw.githubusercontent.com/kata-containers/kata-contai This will create a new namespace `kata-system` and a `daemonset` in it. +> **Note**: The bundled `daemonset` uses `quay.io/kata-containers/kata-monitor:latest`. +> For production deployments, pin the image to a specific release tag +> (e.g. `quay.io/kata-containers/kata-monitor:3.32.0`) matching the Kata +> Containers version installed on your nodes. The dedicated +> `kata-monitor` image is published starting with Kata Containers 3.32.0. + Once the `daemonset` is running, Prometheus should discover `kata-monitor` as a target. You can open `http://:30909/service-discovery` and find `kubernetes-pods` under the `Service Discovery` list From 5731d30554e2d6290539d0e559a3ed80a1f60842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Sat, 30 May 2026 10:45:20 +0200 Subject: [PATCH 4/9] helm: add optional kata-monitor deployment to kata-deploy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a disabled-by-default kata-monitor DaemonSet to the kata-deploy Helm chart, including image/configuration values so operators can enable monitor shipping as part of the same deployment workflow when needed. Signed-off-by: Fabiano Fidêncio Assisted-by: OpenAI Codex --- .../kata-deploy/templates/_helpers.tpl | 16 +++++ .../kata-deploy/templates/kata-monitor.yaml | 69 +++++++++++++++++++ .../helm-chart/kata-deploy/values.yaml | 21 ++++++ 3 files changed, 106 insertions(+) create mode 100644 tools/packaging/kata-deploy/helm-chart/kata-deploy/templates/kata-monitor.yaml diff --git a/tools/packaging/kata-deploy/helm-chart/kata-deploy/templates/_helpers.tpl b/tools/packaging/kata-deploy/helm-chart/kata-deploy/templates/_helpers.tpl index 4529e5d402..cd885522e0 100644 --- a/tools/packaging/kata-deploy/helm-chart/kata-deploy/templates/_helpers.tpl +++ b/tools/packaging/kata-deploy/helm-chart/kata-deploy/templates/_helpers.tpl @@ -375,6 +375,22 @@ When reference already contains "@" (digest) or tag is empty, use reference as-i {{- end -}} {{- end -}} +{{/* +kata-monitor image reference for optional monitor DaemonSet. +Supports tag (reference:tag) and digest (reference@sha256:...) formats. +When reference contains "@" (digest), use reference as-is; otherwise use +reference:tag (tag defaults to Chart.AppVersion). +*/}} +{{- define "kata-deploy.monitorImage" -}} +{{- $ref := .Values.monitor.image.reference -}} +{{- $tag := default .Chart.AppVersion .Values.monitor.image.tag | toString -}} +{{- if contains "@" $ref -}} +{{- $ref -}} +{{- else -}} +{{- printf "%s:%s" $ref $tag -}} +{{- end -}} +{{- end -}} + {{/* Get snapshotter setup list from structured config */}} diff --git a/tools/packaging/kata-deploy/helm-chart/kata-deploy/templates/kata-monitor.yaml b/tools/packaging/kata-deploy/helm-chart/kata-deploy/templates/kata-monitor.yaml new file mode 100644 index 0000000000..567bb99cf8 --- /dev/null +++ b/tools/packaging/kata-deploy/helm-chart/kata-deploy/templates/kata-monitor.yaml @@ -0,0 +1,69 @@ +{{- if .Values.monitor.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/name: kata-monitor + app.kubernetes.io/instance: {{ .Release.Name }} + name: kata-monitor + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: kata-monitor + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: kata-monitor + app.kubernetes.io/instance: {{ .Release.Name }} + annotations: + prometheus.io/scrape: "true" + spec: +{{- with .Values.imagePullSecrets }} + imagePullSecrets: +{{- toYaml . | nindent 6 }} +{{- end }} +{{- with .Values.nodeSelector }} + nodeSelector: +{{- toYaml . | nindent 8 }} +{{- end }} +{{- with .Values.tolerations }} + tolerations: +{{- toYaml . | nindent 8 }} +{{- end }} +{{- with .Values.priorityClassName }} + priorityClassName: {{ . | quote }} +{{- end }} + containers: + - name: kata-monitor + image: {{ include "kata-deploy.monitorImage" . }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + securityContext: +{{- toYaml .Values.monitor.securityContext | nindent 10 }} + args: + - -listen-address={{ .Values.monitor.listenAddress }} + - -log-level={{ .Values.monitor.logLevel }} + - -runtime-endpoint={{ .Values.monitor.runtimeEndpoint }} + ports: + - containerPort: {{ .Values.monitor.port }} + resources: +{{- toYaml .Values.monitor.resources | nindent 10 }} + volumeMounts: + - name: containerd-sock + mountPath: /run/containerd + readOnly: true + - name: sbs + mountPath: /run/vc/sbs/ + readOnly: true + terminationGracePeriodSeconds: 30 + volumes: + - name: containerd-sock + hostPath: + path: /run/containerd + type: Directory + - name: sbs + hostPath: + path: /run/vc/sbs/ + type: DirectoryOrCreate +{{- end }} diff --git a/tools/packaging/kata-deploy/helm-chart/kata-deploy/values.yaml b/tools/packaging/kata-deploy/helm-chart/kata-deploy/values.yaml index 4b8ec918c3..7b0e9fa74a 100644 --- a/tools/packaging/kata-deploy/helm-chart/kata-deploy/values.yaml +++ b/tools/packaging/kata-deploy/helm-chart/kata-deploy/values.yaml @@ -10,6 +10,27 @@ kubectlImage: reference: quay.io/kata-containers/kubectl tag: latest +monitor: + enabled: false + image: + reference: quay.io/kata-containers/kata-monitor + tag: "" + listenAddress: "0.0.0.0:8090" + runtimeEndpoint: "unix:///run/containerd/containerd.sock" + logLevel: "info" + port: 8090 + securityContext: + privileged: false + runAsUser: 0 + runAsGroup: 0 + resources: + limits: + cpu: 200m + memory: 300Mi + requests: + cpu: 200m + memory: 300Mi + k8sDistribution: "k8s" # k8s, k3s, rke2, k0s, microk8s # Containerd configuration overrides From d5bc1177c03e108bc969658991de3dba90786aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Wed, 3 Jun 2026 13:02:55 +0200 Subject: [PATCH 5/9] tests: focus kata-monitor CI on containerd active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the stale CRI-O matrix entry (its cri-tools pin was several releases behind) along with the exclude that hid the containerd job, and pin the remaining job to containerd's "active" track (currently v2.2) via CONTAINERD_VERSION. Signed-off-by: Fabiano Fidêncio Assisted-by: OpenAI Codex --- .github/workflows/run-kata-monitor-tests.yaml | 13 +++------- tests/functional/kata-monitor/gha-run.sh | 24 ++++++------------- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/.github/workflows/run-kata-monitor-tests.yaml b/.github/workflows/run-kata-monitor-tests.yaml index bbb4772e6b..c39c1d9ac0 100644 --- a/.github/workflows/run-kata-monitor-tests.yaml +++ b/.github/workflows/run-kata-monitor-tests.yaml @@ -28,23 +28,16 @@ jobs: vmm: - qemu container_engine: - - crio - containerd - # TODO: enable when https://github.com/kata-containers/kata-containers/issues/9853 is fixed - #include: - # - container_engine: containerd - # containerd_version: latest - exclude: - # TODO: enable with containerd when https://github.com/kata-containers/kata-containers/issues/9761 is fixed - - container_engine: containerd - vmm: qemu + containerd_version: + - active concurrency: group: ${{ github.workflow }}-${{ github.job }}-${{ github.event.pull_request.number || github.ref }}-${{ toJSON(matrix) }} cancel-in-progress: true runs-on: ubuntu-22.04 env: CONTAINER_ENGINE: ${{ matrix.container_engine }} - #CONTAINERD_VERSION: ${{ matrix.containerd_version }} + CONTAINERD_VERSION: ${{ matrix.containerd_version }} KATA_HYPERVISOR: ${{ matrix.vmm }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/tests/functional/kata-monitor/gha-run.sh b/tests/functional/kata-monitor/gha-run.sh index 1877bc80f8..ec775e68fa 100755 --- a/tests/functional/kata-monitor/gha-run.sh +++ b/tests/functional/kata-monitor/gha-run.sh @@ -33,35 +33,25 @@ function install_dependencies() { ensure_yq - # Dependency list of projects that we can install them + # Dependency list of projects that we can install # directly from their releases on GitHub: # - cri-tools # - containerd # - cri-container-cni release tarball already includes CNI plugins + # - runc + # - cni-plugins cri_tools_version=$(get_from_kata_deps ".externals.critools.latest") declare -a github_deps github_deps[0]="cri_tools:${cri_tools_version}" # shellcheck disable=SC2154 - case "${CONTAINER_ENGINE}" in - containerd) - # shellcheck disable=SC2154 - github_deps[1]="cri_containerd:$(get_from_kata_deps ".externals.containerd.${CONTAINERD_VERSION}")" - github_deps[2]="runc:$(get_from_kata_deps ".externals.runc.latest")" - github_deps[3]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" - ;; - crio) - github_deps[1]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" - ;; - esac + github_deps[1]="cri_containerd:$(get_from_kata_deps ".externals.containerd.${CONTAINERD_VERSION}")" + github_deps[2]="runc:$(get_from_kata_deps ".externals.runc.latest")" + github_deps[3]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" for github_dep in "${github_deps[@]}"; do IFS=":" read -r -a dep <<< "${github_dep}" "install_${dep[0]}" "${dep[1]}" done - - if [[ "${CONTAINER_ENGINE}" = "crio" ]]; then - install_crio "${cri_tools_version#v}" - fi } function run() { @@ -69,7 +59,7 @@ function run() { info "Running cri-containerd tests using ${KATA_HYPERVISOR} hypervisor" enabling_hypervisor - bash -c "${kata_monitor_dir}/kata-monitor-tests.sh" + bash "${kata_monitor_dir}/kata-monitor-tests.sh" } function main() { From 63fec205feef4f0f65b148f055410e41c107d488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Wed, 3 Jun 2026 13:03:37 +0200 Subject: [PATCH 6/9] tests: run kata-monitor functional tests against the dedicated image MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exercise the published kata-monitor container image (the one built by publish-kata-monitor-payload-amd64) rather than the on-disk binary, so integration regressions like the recent glibc/musl mismatch surface at PR time. The kata-monitor-tests.sh script keeps the binary fallback for ad-hoc local runs. Signed-off-by: Fabiano Fidêncio Assisted-by: OpenAI Codex --- .github/workflows/ci.yaml | 3 +- .github/workflows/run-kata-monitor-tests.yaml | 13 ++++ .../kata-monitor/kata-monitor-tests.sh | 72 ++++++++++++++++--- 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b89957464b..51a036731c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -297,12 +297,13 @@ jobs: run-kata-monitor-tests: if: ${{ inputs.skip-test != 'yes' }} - needs: build-kata-static-tarball-amd64 + needs: [build-kata-static-tarball-amd64, publish-kata-monitor-image-amd64] uses: ./.github/workflows/run-kata-monitor-tests.yaml with: tarball-suffix: -${{ inputs.tag }} commit-hash: ${{ inputs.commit-hash }} target-branch: ${{ inputs.target-branch }} + kata-monitor-image: ghcr.io/${{ github.repository_owner }}/kata-monitor-ci:${{ inputs.tag }}-amd64 run-k8s-tests-on-aks: if: ${{ inputs.skip-test != 'yes' }} diff --git a/.github/workflows/run-kata-monitor-tests.yaml b/.github/workflows/run-kata-monitor-tests.yaml index c39c1d9ac0..aa32e82f7c 100644 --- a/.github/workflows/run-kata-monitor-tests.yaml +++ b/.github/workflows/run-kata-monitor-tests.yaml @@ -12,6 +12,14 @@ on: required: false type: string default: "" + kata-monitor-image: + description: >- + Container image reference for kata-monitor to be exercised by + the tests. When unset the tests fall back to running the + kata-monitor binary installed from the kata-static tarball. + required: false + type: string + default: "" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-kata-monitor @@ -39,6 +47,7 @@ jobs: CONTAINER_ENGINE: ${{ matrix.container_engine }} CONTAINERD_VERSION: ${{ matrix.containerd_version }} KATA_HYPERVISOR: ${{ matrix.vmm }} + KATA_MONITOR_IMAGE: ${{ inputs.kata-monitor-image }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -66,5 +75,9 @@ jobs: - name: Install kata run: bash tests/functional/kata-monitor/gha-run.sh install-kata kata-artifacts + - name: Pre-pull kata-monitor image + if: ${{ inputs.kata-monitor-image != '' }} + run: sudo docker pull "${KATA_MONITOR_IMAGE}" + - name: Run kata-monitor tests run: bash tests/functional/kata-monitor/gha-run.sh run diff --git a/tests/functional/kata-monitor/kata-monitor-tests.sh b/tests/functional/kata-monitor/kata-monitor-tests.sh index 2134fb08d2..41da8c3c61 100755 --- a/tests/functional/kata-monitor/kata-monitor-tests.sh +++ b/tests/functional/kata-monitor/kata-monitor-tests.sh @@ -27,7 +27,13 @@ readonly MONITOR_MIN_METRICS_NUM=200 readonly TIMEOUT="20s" CONTAINER_ENGINE=${CONTAINER_ENGINE:-"containerd"} CRICTL_RUNTIME=${CRICTL_RUNTIME:-"kata"} +# When KATA_MONITOR_IMAGE is set, kata-monitor runs inside that container +# image instead of as an on-disk binary. This is what CI does — it +# validates the actual image we ship. Manual runs without the env var +# keep the previous behaviour of executing ${KATA_MONITOR_BIN}. +KATA_MONITOR_IMAGE="${KATA_MONITOR_IMAGE:-}" KATA_MONITOR_BIN="${KATA_MONITOR_BIN:-$(command -v kata-monitor || true)}" +readonly KATA_MONITOR_CONTAINER_NAME="kata-monitor-test" KATA_MONITOR_PID="" TMPATH=$(mktemp -d -t kata-monitor-test-XXXXXXXXX) METRICS_FILE="${TMPATH}/metrics.txt" @@ -83,11 +89,59 @@ cleanup() { stop_workload stop_workload "${RUNC_CID}" "${RUNC_POD_ID}" + stop_kata_monitor + + rm -rf "${TMPATH}" +} + +start_kata_monitor() { + local args="$1" + + if [[ -n "${KATA_MONITOR_IMAGE}" ]]; then + # `--network host` keeps the default 127.0.0.1:8090 bind + # reachable from the host-side test code without having to + # publish a port. Mount /run/containerd so the monitor can + # reach containerd's CRI socket, plus the kata sandbox base + # path for the per-sandbox shim-monitor sockets. + + # Ensure /run/vc/sbs/ exists on the host so the readonly mount + # does not fail before the first kata sandbox is created. + sudo mkdir -p /run/vc/sbs + + # shellcheck disable=SC2086 + sudo docker run --rm -d \ + --name "${KATA_MONITOR_CONTAINER_NAME}" \ + --network host \ + -v /run/containerd:/run/containerd:ro \ + -v /run/vc/sbs:/run/vc/sbs:ro \ + "${KATA_MONITOR_IMAGE}" \ + ${args} --log-level trace > /dev/null + # Stream container logs into the same file the binary path + # writes to, so error_with_msg's dump works identically in + # both modes. The redirect target lives under our own + # ${TMPATH}, so SC2024 (sudo doesn't affect redirects) is a + # false positive here. + # shellcheck disable=SC2024 + sudo docker logs -f "${KATA_MONITOR_CONTAINER_NAME}" \ + > "${MONITOR_LOG_FILE}" 2>&1 & + return + fi + + [[ ! -x "${KATA_MONITOR_BIN}" ]] && error_with_msg "kata-monitor binary not found" + # shellcheck disable=SC2024,SC2086 + sudo "${KATA_MONITOR_BIN}" ${args} --log-level trace > "${MONITOR_LOG_FILE}" 2>&1 & + KATA_MONITOR_PID="$!" +} + +stop_kata_monitor() { + if [[ -n "${KATA_MONITOR_IMAGE}" ]]; then + sudo docker stop "${KATA_MONITOR_CONTAINER_NAME}" > /dev/null 2>&1 || true + return + fi + [[ -n "${KATA_MONITOR_PID}" ]] \ && [[ -d "/proc/${KATA_MONITOR_PID}" ]] \ && kill -9 "${KATA_MONITOR_PID}" - - rm -rf "${TMPATH}" } create_sandbox_json() { @@ -243,15 +297,13 @@ main() { ########################### title "start kata-monitor" - [[ ! -x "${KATA_MONITOR_BIN}" ]] && error_with_msg "kata-monitor binary not found" - - [[ "${CONTAINER_ENGINE}" = "crio" ]] && args="--runtime-endpoint /run/crio/crio.sock" - CURRENT_TASK="start kata-monitor" - # shellcheck disable=SC2024,SC2086 - sudo "${KATA_MONITOR_BIN}" ${args} --log-level trace > "${MONITOR_LOG_FILE}" 2>&1 & - KATA_MONITOR_PID="$!" - echo_ok "${CURRENT_TASK} (${KATA_MONITOR_PID})" + start_kata_monitor "${args}" + if [[ -n "${KATA_MONITOR_IMAGE}" ]]; then + echo_ok "${CURRENT_TASK} (image ${KATA_MONITOR_IMAGE})" + else + echo_ok "${CURRENT_TASK} (pid ${KATA_MONITOR_PID})" + fi ########################### title "kata-monitor cache update checks" From 285d5daa23584feb92c3a580f1769941e29cf2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Wed, 3 Jun 2026 12:57:53 +0200 Subject: [PATCH 7/9] tests: install latest cri-tools dynamically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve the cri-tools release at install time instead of pinning a version in versions.yaml: install_cri_tools now queries the GitHub releases API for the absolute latest stable tag, and the kata-monitor, cri-containerd and nydus jobs call it directly. Also write /etc/crictl.yaml during containerd setup so crictl stops emitting deprecation warnings about the legacy default endpoints. Signed-off-by: Fabiano Fidêncio Assisted-by: OpenAI Codex --- tests/common.bash | 33 +++++++++++++++++++-- tests/functional/kata-monitor/gha-run.sh | 13 ++++---- tests/integration/cri-containerd/gha-run.sh | 10 ++++--- tests/integration/nydus/gha-run.sh | 14 +++++---- versions.yaml | 8 ----- 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/tests/common.bash b/tests/common.bash index 0df6f58a52..15c132e72e 100644 --- a/tests/common.bash +++ b/tests/common.bash @@ -1089,6 +1089,19 @@ function install_cri_containerd() { | sudo tee /etc/containerd/config.toml > /dev/null ensure_containerd_conf_d_rootful_api_sockets + # Drop a default /etc/crictl.yaml pointing at the freshly-installed + # containerd socket so crictl does not probe — and warn loudly about + # — the legacy default endpoints (dockershim, CRI-O, cri-dockerd) on + # every invocation. cri-tools v1.30+ deprecated the implicit default + # endpoint discovery, which means every crictl call without this + # config emits noisy validation errors for sockets that do not exist + # on the runner. + sudo tee /etc/crictl.yaml > /dev/null <<-EOF + runtime-endpoint: unix:///run/containerd/containerd.sock + image-endpoint: unix:///run/containerd/containerd.sock + timeout: 10 + EOF + # Always write the service file pointing at the just-installed binary and # reload systemd so the correct binary is used on the next start. # The runner image may have a pre-installed containerd unit pointing at a @@ -1129,12 +1142,26 @@ EOF sudo systemctl daemon-reload } -# base_version: The version to be intalled in the ${major}.${minor} format +# Installs cri-tools (crictl). When a base_version (${major}.${minor}) is +# supplied the matching latest patch release is used; otherwise — and this is +# the default in CI — the absolute latest stable release published on GitHub +# is fetched. cri-tools is intentionally not pinned in versions.yaml so we +# always exercise a crictl that speaks current CRI protocol revisions. function install_cri_tools() { - base_version="${1}" + base_version="${1:-}" project="kubernetes-sigs/cri-tools" - version=$(get_latest_patch_release_from_a_github_project "${project}" "${base_version}") + if [[ -n "${base_version}" ]]; then + version=$(get_latest_patch_release_from_a_github_project "${project}" "${base_version}") + else + version=$(curl \ + ${GH_TOKEN:+--header "Authorization: Bearer ${GH_TOKEN}"} \ + --fail-with-body \ + --show-error \ + --silent \ + "https://api.github.com/repos/${project}/releases/latest" \ + | jq -r .tag_name) + fi tarball_name="crictl-${version}-linux-$("${repo_root_dir}"/tests/kata-arch.sh -g).tar.gz" diff --git a/tests/functional/kata-monitor/gha-run.sh b/tests/functional/kata-monitor/gha-run.sh index ec775e68fa..b1f697c9d5 100755 --- a/tests/functional/kata-monitor/gha-run.sh +++ b/tests/functional/kata-monitor/gha-run.sh @@ -35,23 +35,24 @@ function install_dependencies() { # Dependency list of projects that we can install # directly from their releases on GitHub: - # - cri-tools # - containerd # - cri-container-cni release tarball already includes CNI plugins # - runc # - cni-plugins - cri_tools_version=$(get_from_kata_deps ".externals.critools.latest") declare -a github_deps - github_deps[0]="cri_tools:${cri_tools_version}" # shellcheck disable=SC2154 - github_deps[1]="cri_containerd:$(get_from_kata_deps ".externals.containerd.${CONTAINERD_VERSION}")" - github_deps[2]="runc:$(get_from_kata_deps ".externals.runc.latest")" - github_deps[3]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" + github_deps[0]="cri_containerd:$(get_from_kata_deps ".externals.containerd.${CONTAINERD_VERSION}")" + github_deps[1]="runc:$(get_from_kata_deps ".externals.runc.latest")" + github_deps[2]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" for github_dep in "${github_deps[@]}"; do IFS=":" read -r -a dep <<< "${github_dep}" "install_${dep[0]}" "${dep[1]}" done + + # cri-tools is resolved at install time to the absolute latest + # release, so it is not pinned via versions.yaml. + install_cri_tools } function run() { diff --git a/tests/integration/cri-containerd/gha-run.sh b/tests/integration/cri-containerd/gha-run.sh index 155716ae95..7eefc1d720 100755 --- a/tests/integration/cri-containerd/gha-run.sh +++ b/tests/integration/cri-containerd/gha-run.sh @@ -51,19 +51,21 @@ function install_dependencies() { # directly from their releases on GitHub: # - containerd # - cri-container-cni release tarball already includes CNI plugins - # - cri-tools declare -a github_deps # shellcheck disable=SC2154 github_deps[0]="cri_containerd:$(get_from_kata_deps ".externals.containerd.${CONTAINERD_VERSION}")" - github_deps[1]="cri_tools:$(get_from_kata_deps ".externals.critools.latest")" - github_deps[2]="runc:$(get_from_kata_deps ".externals.runc.latest")" - github_deps[3]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" + github_deps[1]="runc:$(get_from_kata_deps ".externals.runc.latest")" + github_deps[2]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" for github_dep in "${github_deps[@]}"; do IFS=":" read -r -a dep <<< "${github_dep}" "install_${dep[0]}" "${dep[1]}" done + # cri-tools is resolved at install time to the absolute latest + # release, so it is not pinned via versions.yaml. + install_cri_tools + # Clone containerd as we'll need to build it in order to run the tests # base_version: The version to be intalled in the ${major}.${minor} format clone_cri_containerd "$(get_from_kata_deps ".externals.containerd.${CONTAINERD_VERSION}")" diff --git a/tests/integration/nydus/gha-run.sh b/tests/integration/nydus/gha-run.sh index 1f8b28c866..1e7d3aa8af 100755 --- a/tests/integration/nydus/gha-run.sh +++ b/tests/integration/nydus/gha-run.sh @@ -33,22 +33,24 @@ function install_dependencies() { # directly from their releases on GitHub: # - containerd # - cri-container-cni release tarball already includes CNI plugins - # - cri-tools # - nydus # - nydus-snapshotter declare -a github_deps # shellcheck disable=SC2154 github_deps[0]="cri_containerd:$(get_from_kata_deps ".externals.containerd.${CONTAINERD_VERSION}")" - github_deps[1]="cri_tools:$(get_from_kata_deps ".externals.critools.latest")" - github_deps[2]="nydus:$(get_from_kata_deps ".externals.nydus.version")" - github_deps[3]="nydus_snapshotter:$(get_from_kata_deps ".externals.nydus-snapshotter.version")" - github_deps[4]="runc:$(get_from_kata_deps ".externals.runc.latest")" - github_deps[5]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" + github_deps[1]="nydus:$(get_from_kata_deps ".externals.nydus.version")" + github_deps[2]="nydus_snapshotter:$(get_from_kata_deps ".externals.nydus-snapshotter.version")" + github_deps[3]="runc:$(get_from_kata_deps ".externals.runc.latest")" + github_deps[4]="cni_plugins:$(get_from_kata_deps ".externals.cni-plugins.version")" for github_dep in "${github_deps[@]}"; do IFS=":" read -r -a dep <<< "${github_dep}" "install_${dep[0]}" "${dep[1]}" done + + # cri-tools is resolved at install time to the absolute latest + # release, so it is not pinned via versions.yaml. + install_cri_tools } function run() { diff --git a/versions.yaml b/versions.yaml index d9317b13f6..765a46fe61 100644 --- a/versions.yaml +++ b/versions.yaml @@ -315,14 +315,6 @@ externals: minimum: "v1.7" latest: "v2.3" - critools: - description: "CLI tool for Container Runtime Interface (CRI)" - url: "https://github.com/kubernetes-sigs/cri-tools" - version: "1.23.0" - # As we don't want to disrupt what we have on the `tests` repo, let's - # create a "latest" entry and use that for the GitHub actions tests. - latest: "v1.29" - runc: description: "CLI tool for spawning and running containers" url: "https://github.com/opencontainers/runc" From 92a9691470fa601e4474cb9d0152ae5c0e66706f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Wed, 3 Jun 2026 12:58:31 +0200 Subject: [PATCH 8/9] tests: add kata-monitor helm chart k8s test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a single-job k8s test that installs the kata-deploy helm chart with monitor.enabled=true, pointed at the per-PR kata-monitor image built earlier in the same run, and exercises both the rollout and the user-visible behaviour: * the kata-monitor DaemonSet rolls out and the pod stays up without container restarts; * a real kata-runtime probe pod is scheduled, then /metrics and /sandboxes are scraped through the apiserver pod-proxy to prove kata-monitor sees the sandbox (non-zero running-shim count plus at least one per-sandbox kata_shim_* metric); * after the probe pod is deleted, /metrics drops back to a zero running-shim count. Signed-off-by: Fabiano Fidêncio Assisted-by: OpenAI Codex --- .github/workflows/ci.yaml | 14 ++ .../workflows/run-kata-monitor-k8s-tests.yaml | 110 +++++++++ tests/functional/kata-monitor/gha-run.sh | 15 ++ .../functional/kata-monitor/kata-monitor.bats | 233 ++++++++++++++++++ .../run-kata-monitor-helm-tests.sh | 26 ++ 5 files changed, 398 insertions(+) create mode 100644 .github/workflows/run-kata-monitor-k8s-tests.yaml create mode 100644 tests/functional/kata-monitor/kata-monitor.bats create mode 100644 tests/functional/kata-monitor/run-kata-monitor-helm-tests.sh diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 51a036731c..ca3aeb8e12 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -305,6 +305,20 @@ jobs: target-branch: ${{ inputs.target-branch }} kata-monitor-image: ghcr.io/${{ github.repository_owner }}/kata-monitor-ci:${{ inputs.tag }}-amd64 + run-kata-monitor-k8s-tests: + if: ${{ inputs.skip-test != 'yes' }} + needs: [publish-kata-deploy-payload-amd64, publish-kata-monitor-image-amd64] + uses: ./.github/workflows/run-kata-monitor-k8s-tests.yaml + with: + registry: ghcr.io + repo: ${{ github.repository_owner }}/kata-deploy-ci + tag: ${{ inputs.tag }}-amd64 + pr-number: ${{ inputs.pr-number }} + commit-hash: ${{ inputs.commit-hash }} + target-branch: ${{ inputs.target-branch }} + kata-monitor-image-reference: ghcr.io/${{ github.repository_owner }}/kata-monitor-ci + kata-monitor-image-tag: ${{ inputs.tag }}-amd64 + run-k8s-tests-on-aks: if: ${{ inputs.skip-test != 'yes' }} needs: publish-kata-deploy-payload-amd64 diff --git a/.github/workflows/run-kata-monitor-k8s-tests.yaml b/.github/workflows/run-kata-monitor-k8s-tests.yaml new file mode 100644 index 0000000000..8a62d0e24b --- /dev/null +++ b/.github/workflows/run-kata-monitor-k8s-tests.yaml @@ -0,0 +1,110 @@ +name: CI | Run kata-monitor k8s tests +on: + workflow_call: + inputs: + registry: + description: Registry of the kata-deploy image under test. + required: true + type: string + repo: + description: Repository of the kata-deploy image under test. + required: true + type: string + tag: + description: Tag of the kata-deploy image under test. + required: true + type: string + pr-number: + required: true + type: string + commit-hash: + required: false + type: string + target-branch: + required: false + type: string + default: "" + kata-monitor-image-reference: + description: Registry/repo of the kata-monitor image to exercise. + required: true + type: string + kata-monitor-image-tag: + description: Tag of the kata-monitor image to exercise. + required: true + type: string + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-kata-monitor-k8s + cancel-in-progress: true + +permissions: {} + +jobs: + run-kata-monitor-k8s-tests: + name: run-kata-monitor-k8s-tests + strategy: + fail-fast: false + matrix: + vmm: + - qemu + k8s: + - vanilla + concurrency: + group: ${{ github.workflow }}-run-kata-monitor-k8s-tests-${{ github.event.pull_request.number || github.ref }}-${{ toJSON(matrix) }} + cancel-in-progress: true + runs-on: ubuntu-24.04 + env: + DOCKER_REGISTRY: ${{ inputs.registry }} + DOCKER_REPO: ${{ inputs.repo }} + DOCKER_TAG: ${{ inputs.tag }} + GH_PR_NUMBER: ${{ inputs.pr-number }} + KATA_HYPERVISOR: ${{ matrix.vmm }} + KUBERNETES: ${{ matrix.k8s }} + CONTAINER_ENGINE: containerd + CONTAINER_ENGINE_VERSION: active + KATA_MONITOR_IMAGE_REFERENCE: ${{ inputs.kata-monitor-image-reference }} + KATA_MONITOR_IMAGE_TAG: ${{ inputs.kata-monitor-image-tag }} + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ inputs.commit-hash }} + fetch-depth: 0 + persist-credentials: false + + - name: Rebase atop of the latest target branch + run: | + ./tests/git-helper.sh "rebase-atop-of-the-latest-target-branch" + env: + TARGET_BRANCH: ${{ inputs.target-branch }} + + - name: Remove unnecessary directories to free up space + run: | + sudo rm -rf /usr/local/.ghcup + sudo rm -rf /opt/hostedtoolcache/CodeQL + sudo rm -rf /usr/local/lib/android + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf /usr/local/share/boost + sudo rm -rf /usr/lib/jvm + sudo rm -rf /usr/share/swift + sudo rm -rf /usr/local/share/powershell + sudo rm -rf /usr/local/julia* + sudo rm -rf /opt/az + sudo rm -rf /usr/local/share/chromium + sudo rm -rf /opt/microsoft + sudo rm -rf /opt/google + sudo rm -rf /usr/lib/firefox + + - name: Deploy ${{ matrix.k8s }} + run: bash tests/functional/kata-deploy/gha-run.sh deploy-k8s + + - name: Install `bats` + run: bash tests/functional/kata-deploy/gha-run.sh install-bats + + - name: Run tests + run: bash tests/functional/kata-monitor/gha-run.sh run-helm-tests + + - name: Report tests + if: always() + run: bash tests/functional/kata-monitor/gha-run.sh report-helm-tests diff --git a/tests/functional/kata-monitor/gha-run.sh b/tests/functional/kata-monitor/gha-run.sh index b1f697c9d5..ca0757bb65 100755 --- a/tests/functional/kata-monitor/gha-run.sh +++ b/tests/functional/kata-monitor/gha-run.sh @@ -63,12 +63,27 @@ function run() { bash "${kata_monitor_dir}/kata-monitor-tests.sh" } +function run_helm_tests() { + # shellcheck disable=SC2154 + info "Running kata-monitor helm-chart tests" + + pushd "${kata_monitor_dir}" + bash run-kata-monitor-helm-tests.sh + popd +} + +function report_helm_tests() { + report_bats_tests "${kata_monitor_dir}" +} + function main() { action="${1:-}" case "${action}" in install-dependencies) install_dependencies ;; install-kata) install_kata ;; run) run ;; + run-helm-tests) run_helm_tests ;; + report-helm-tests) report_helm_tests ;; *) >&2 die "Invalid argument" ;; esac } diff --git a/tests/functional/kata-monitor/kata-monitor.bats b/tests/functional/kata-monitor/kata-monitor.bats new file mode 100644 index 0000000000..e2ad9ed4f7 --- /dev/null +++ b/tests/functional/kata-monitor/kata-monitor.bats @@ -0,0 +1,233 @@ +#!/usr/bin/env bats +# +# Copyright (c) 2026 NVIDIA Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# +# kata-monitor helm chart functional test. +# +# Validates that the optional kata-monitor DaemonSet shipped by the +# kata-deploy helm chart actually rolls out, exercises the per-PR +# kata-monitor image, and exposes per-sandbox Prometheus metrics for a +# live kata pod. +# +# Required environment variables (mirroring kata-deploy.bats): +# DOCKER_REGISTRY - Registry for kata-deploy image +# DOCKER_REPO - Repository name for kata-deploy image +# DOCKER_TAG - kata-deploy image tag to test +# KATA_HYPERVISOR - Hypervisor to test (qemu, ...) +# KUBERNETES - K8s distribution (k3s, k0s, ...) +# KATA_MONITOR_IMAGE_REFERENCE - Registry/repo for the kata-monitor image +# KATA_MONITOR_IMAGE_TAG - kata-monitor image tag to test +# + +load "${BATS_TEST_DIRNAME}/../../common.bash" +repo_root_dir="${BATS_TEST_DIRNAME}/../../../" +load "${repo_root_dir}/tests/gha-run-k8s-common.sh" + +# Reuse the helm install/uninstall helpers maintained alongside the +# kata-deploy bats tests. +source "${BATS_TEST_DIRNAME}/../kata-deploy/lib/helm-deploy.bash" + +# Cache update polling interval is short on the monitor side; 30s is +# generous enough to absorb both the cache refresh and any apiserver +# proxy latency without dragging the test runtime up. +KATA_MONITOR_CACHE_TIMEOUT_S="${KATA_MONITOR_CACHE_TIMEOUT_S:-30}" + +# Pod name used to give kata-monitor a real sandbox to surface metrics +# about. Kept fixed so teardown can clean it up unconditionally. +KATA_MONITOR_PROBE_POD="kata-monitor-probe" + +setup() { + ensure_helm + + : "${KATA_MONITOR_IMAGE_REFERENCE:?KATA_MONITOR_IMAGE_REFERENCE must be set}" + : "${KATA_MONITOR_IMAGE_TAG:?KATA_MONITOR_IMAGE_TAG must be set}" +} + +# Hit `path` (e.g. /metrics or /sandboxes) on one of the kata-monitor +# pods via the apiserver pod-proxy. Stdout is the response body; stderr +# / non-zero exit propagate kubectl failures. +kata_monitor_get() { + local path="$1" + local pod + + pod="$(kubectl -n "${HELM_NAMESPACE}" get pods \ + -l app.kubernetes.io/name=kata-monitor \ + -o jsonpath='{.items[0].metadata.name}')" + [[ -n "${pod}" ]] || { echo "no kata-monitor pod found" >&2; return 1; } + + kubectl -n "${HELM_NAMESPACE}" get --raw \ + "/api/v1/namespaces/${HELM_NAMESPACE}/pods/${pod}:8090/proxy${path}" +} + +# Block until `predicate` returns 0 against the fresh /metrics output, +# or until ${KATA_MONITOR_CACHE_TIMEOUT_S} elapses. The predicate is a +# bash function name receiving the metrics body on stdin. +wait_for_metrics() { + local predicate="$1" + local body + local deadline=$((SECONDS + KATA_MONITOR_CACHE_TIMEOUT_S)) + + while (( SECONDS < deadline )); do + if body="$(kata_monitor_get /metrics 2>/dev/null)" \ + && printf '%s' "${body}" | "${predicate}"; then + return 0 + fi + sleep 1 + done + + echo "Timed out waiting for kata-monitor /metrics predicate '${predicate}'" >&2 + echo "Last response was:" >&2 + printf '%s\n' "${body:-}" | head -50 >&2 + return 1 +} + +predicate_has_running_shim() { + # Match `kata_monitor_running_shim_count ` where N >= 1. + grep -E '^kata_monitor_running_shim_count [1-9][0-9]* *$' >/dev/null +} + +predicate_no_running_shim() { + grep -E '^kata_monitor_running_shim_count 0 *$' >/dev/null +} + +predicate_has_shim_metric() { + # Any kata_shim_* metric line with a non-empty sandbox_id label is + # enough to prove the per-sandbox scrape path works end-to-end. + grep -E '^kata_shim_[a-z_]+\{[^}]*sandbox_id="[0-9a-f-]+' >/dev/null +} + +@test "kata-monitor helm chart rolls out and exposes per-sandbox metrics" { + pushd "${repo_root_dir}" + + local helm_timeout="${KATA_DEPLOY_TIMEOUT:-600s}" + local rollout_timeout="${KATA_MONITOR_ROLLOUT_TIMEOUT:-300s}" + + echo "Installing kata-deploy with monitor.enabled=true ..." + echo " kata-monitor image: ${KATA_MONITOR_IMAGE_REFERENCE}:${KATA_MONITOR_IMAGE_TAG}" + + HELM_TIMEOUT="${helm_timeout}" deploy_kata "" \ + --set monitor.enabled=true \ + --set "monitor.image.reference=${KATA_MONITOR_IMAGE_REFERENCE}" \ + --set "monitor.image.tag=${KATA_MONITOR_IMAGE_TAG}" + + echo "" + echo "::group::kata-monitor DaemonSet rollout" + kubectl -n "${HELM_NAMESPACE}" rollout status ds/kata-monitor \ + --timeout="${rollout_timeout}" + echo "::endgroup::" + + kubectl -n "${HELM_NAMESPACE}" wait pod \ + -l app.kubernetes.io/name=kata-monitor \ + --for=condition=Ready --timeout="${rollout_timeout}" + + # Enabling monitor.enabled=true in the same chart deploys kata-monitor + # alongside kata-deploy, and kata-deploy reconfigures and restarts + # containerd as part of installing kata. That bounce drops the first + # kata-monitor instance's containerd connection and costs it a one-off + # restart, which is expected and not a regression. Now that kata-deploy + # is Ready (so containerd is settled), restart the DaemonSet and assert + # the fresh pods stay up without restarts — a genuine crash loop (e.g. + # the recent glibc/musl mismatch) still fails here because it would + # never reach Ready or would keep restarting. + kubectl -n "${HELM_NAMESPACE}" rollout restart ds/kata-monitor + kubectl -n "${HELM_NAMESPACE}" rollout status ds/kata-monitor \ + --timeout="${rollout_timeout}" + + echo "" + echo "::group::kata-monitor pods" + kubectl -n "${HELM_NAMESPACE}" get pods -l app.kubernetes.io/name=kata-monitor -o wide + echo "::endgroup::" + + kubectl -n "${HELM_NAMESPACE}" wait pod \ + -l app.kubernetes.io/name=kata-monitor \ + --for=condition=Ready --timeout="${rollout_timeout}" + + local restarts + restarts="$(kubectl -n "${HELM_NAMESPACE}" get pods \ + -l app.kubernetes.io/name=kata-monitor \ + -o jsonpath='{range .items[*]}{.status.containerStatuses[0].restartCount}{"\n"}{end}')" + while IFS= read -r r; do + [[ -z "${r}" ]] && continue + [[ "${r}" -eq 0 ]] || { + echo "kata-monitor pod restarted ${r} time(s) after containerd settled; failing" + return 1 + } + done <<< "${restarts}" + + # Give kata-monitor something real to surface metrics about: a kata + # pod that just sleeps. Reuses the same image as kata-deploy.bats's + # verification pod for cache-warmth on the runner. + local probe_yaml + probe_yaml=$(mktemp) + cat > "${probe_yaml}" <&2 + return 1 + } + + # Tear the probe pod down and prove kata-monitor's cache flushes + # the sandbox out — mirrors is_sandbox_missing_iterate in the + # host-level test. + echo "" + echo "Deleting probe pod and asserting cache invalidates ..." + kubectl delete "pod/${KATA_MONITOR_PROBE_POD}" --wait=true --timeout=60s + + wait_for_metrics predicate_no_running_shim + echo "kata-monitor /metrics dropped the probe sandbox after deletion" + + popd +} + +teardown() { + # Best-effort cleanup — the @test deletes the probe pod on the + # happy path, but a failure between create and delete would leave + # it behind. + kubectl delete "pod/${KATA_MONITOR_PROBE_POD}" --ignore-not-found --wait=false 2>/dev/null || true + + uninstall_kata +} diff --git a/tests/functional/kata-monitor/run-kata-monitor-helm-tests.sh b/tests/functional/kata-monitor/run-kata-monitor-helm-tests.sh new file mode 100644 index 0000000000..b0159839d9 --- /dev/null +++ b/tests/functional/kata-monitor/run-kata-monitor-helm-tests.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright (c) 2026 NVIDIA Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e +set -o pipefail + +kata_monitor_dir=$(dirname "$(readlink -f "$0")") +# shellcheck source=/dev/null +source "${kata_monitor_dir}/../../common.bash" + +# Setting to "yes" enables fail fast, stopping execution at the first failed test. +export BATS_TEST_FAIL_FAST="${BATS_TEST_FAIL_FAST:-no}" + +if [[ -n "${KATA_MONITOR_HELM_TEST_UNION:-}" ]]; then + KATA_MONITOR_HELM_TEST_UNION=("${KATA_MONITOR_HELM_TEST_UNION}") +else + KATA_MONITOR_HELM_TEST_UNION=( \ + "kata-monitor.bats" \ + ) +fi + +run_bats_tests "${kata_monitor_dir}" KATA_MONITOR_HELM_TEST_UNION From 620d641458ac661739cd08636227c34972483039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= Date: Wed, 3 Jun 2026 23:37:24 +0200 Subject: [PATCH 9/9] ci: rename kata-deploy publish jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These jobs build and push the kata-deploy OCI image, so call them publish-kata-deploy-image-* instead of *-payload-*, matching the kata-monitor image jobs and making the workflow easier to read. Signed-off-by: Fabiano Fidêncio --- .github/workflows/ci.yaml | 28 +++++++++++------------ .github/workflows/payload-after-push.yaml | 10 ++++---- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ca3aeb8e12..d103aa5ad9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -65,7 +65,7 @@ jobs: secrets: KBUILD_SIGN_PIN: ${{ secrets.KBUILD_SIGN_PIN }} - publish-kata-deploy-payload-amd64: + publish-kata-deploy-image-amd64: needs: build-kata-static-tarball-amd64 permissions: contents: read @@ -116,7 +116,7 @@ jobs: secrets: KBUILD_SIGN_PIN: ${{ secrets.KBUILD_SIGN_PIN }} - publish-kata-deploy-payload-arm64: + publish-kata-deploy-image-arm64: needs: build-kata-static-tarball-arm64 permissions: contents: read @@ -179,7 +179,7 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} - publish-kata-deploy-payload-s390x: + publish-kata-deploy-image-s390x: needs: build-kata-static-tarball-s390x permissions: contents: read @@ -216,7 +216,7 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} - publish-kata-deploy-payload-ppc64le: + publish-kata-deploy-image-ppc64le: needs: build-kata-static-tarball-ppc64le permissions: contents: read @@ -307,7 +307,7 @@ jobs: run-kata-monitor-k8s-tests: if: ${{ inputs.skip-test != 'yes' }} - needs: [publish-kata-deploy-payload-amd64, publish-kata-monitor-image-amd64] + needs: [publish-kata-deploy-image-amd64, publish-kata-monitor-image-amd64] uses: ./.github/workflows/run-kata-monitor-k8s-tests.yaml with: registry: ghcr.io @@ -321,7 +321,7 @@ jobs: run-k8s-tests-on-aks: if: ${{ inputs.skip-test != 'yes' }} - needs: publish-kata-deploy-payload-amd64 + needs: publish-kata-deploy-image-amd64 uses: ./.github/workflows/run-k8s-tests-on-aks.yaml permissions: @@ -342,7 +342,7 @@ jobs: run-k8s-tests-on-free-runner: if: ${{ inputs.skip-test != 'yes' }} - needs: publish-kata-deploy-payload-amd64 + needs: publish-kata-deploy-image-amd64 permissions: contents: read uses: ./.github/workflows/run-k8s-tests-on-free-runner.yaml @@ -357,7 +357,7 @@ jobs: run-k8s-tests-on-arm64: if: ${{ inputs.skip-test != 'yes' }} - needs: publish-kata-deploy-payload-arm64 + needs: publish-kata-deploy-image-arm64 uses: ./.github/workflows/run-k8s-tests-on-arm64.yaml with: registry: ghcr.io @@ -370,7 +370,7 @@ jobs: run-kata-coco-tests-on-arm64: if: ${{ inputs.skip-test != 'yes' }} needs: - - publish-kata-deploy-payload-arm64 + - publish-kata-deploy-image-arm64 - build-and-publish-tee-confidential-unencrypted-image uses: ./.github/workflows/run-kata-coco-tests-arm64-k8s.yaml with: @@ -386,7 +386,7 @@ jobs: run-k8s-tests-on-nvidia-gpu: if: ${{ inputs.skip-test != 'yes' }} - needs: publish-kata-deploy-payload-amd64 + needs: publish-kata-deploy-image-amd64 uses: ./.github/workflows/run-k8s-tests-on-nvidia-gpu.yaml with: tarball-suffix: -${{ inputs.tag }} @@ -404,7 +404,7 @@ jobs: run-kata-coco-tests: if: ${{ inputs.skip-test != 'yes' }} needs: - - publish-kata-deploy-payload-amd64 + - publish-kata-deploy-image-amd64 - build-and-publish-tee-confidential-unencrypted-image uses: ./.github/workflows/run-kata-coco-tests.yaml permissions: @@ -428,7 +428,7 @@ jobs: run-k8s-tests-on-zvsi: if: ${{ inputs.skip-test != 'yes' }} - needs: [publish-kata-deploy-payload-s390x, build-and-publish-tee-confidential-unencrypted-image] + needs: [publish-kata-deploy-image-s390x, build-and-publish-tee-confidential-unencrypted-image] uses: ./.github/workflows/run-k8s-tests-on-zvsi.yaml with: registry: ghcr.io @@ -442,7 +442,7 @@ jobs: run-k8s-tests-on-ppc64le: if: ${{ inputs.skip-test != 'yes' }} - needs: publish-kata-deploy-payload-ppc64le + needs: publish-kata-deploy-image-ppc64le uses: ./.github/workflows/run-k8s-tests-on-ppc64le.yaml with: registry: ghcr.io @@ -454,7 +454,7 @@ jobs: run-kata-deploy-tests: if: ${{ inputs.skip-test != 'yes' }} - needs: [publish-kata-deploy-payload-amd64] + needs: [publish-kata-deploy-image-amd64] uses: ./.github/workflows/run-kata-deploy-tests.yaml with: registry: ghcr.io diff --git a/.github/workflows/payload-after-push.yaml b/.github/workflows/payload-after-push.yaml index 1bde58ea51..d7f956e28d 100644 --- a/.github/workflows/payload-after-push.yaml +++ b/.github/workflows/payload-after-push.yaml @@ -67,7 +67,7 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} - publish-kata-deploy-payload-amd64: + publish-kata-deploy-image-amd64: needs: build-assets-amd64 permissions: contents: read @@ -85,7 +85,7 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} - publish-kata-deploy-payload-arm64: + publish-kata-deploy-image-arm64: needs: build-assets-arm64 permissions: contents: read @@ -103,7 +103,7 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} - publish-kata-deploy-payload-s390x: + publish-kata-deploy-image-s390x: needs: build-assets-s390x permissions: contents: read @@ -121,7 +121,7 @@ jobs: secrets: QUAY_DEPLOYER_PASSWORD: ${{ secrets.QUAY_DEPLOYER_PASSWORD }} - publish-kata-deploy-payload-ppc64le: + publish-kata-deploy-image-ppc64le: needs: build-assets-ppc64le permissions: contents: read @@ -217,7 +217,7 @@ jobs: permissions: contents: read packages: write - needs: [publish-kata-deploy-payload-amd64, publish-kata-deploy-payload-arm64, publish-kata-deploy-payload-s390x, publish-kata-deploy-payload-ppc64le] + needs: [publish-kata-deploy-image-amd64, publish-kata-deploy-image-arm64, publish-kata-deploy-image-s390x, publish-kata-deploy-image-ppc64le] steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2