From c075a5484e23c01b5f4eea3214e7db80d7b98d91 Mon Sep 17 00:00:00 2001 From: Byron Marohn Date: Wed, 11 Jun 2025 16:17:39 -0700 Subject: [PATCH 1/4] Initial github actions for automated build & security scans device-plugins: - Improve build.sh to take proper --ver, --repo, and --push arguments - Add a workflow which runs build.sh, Trivy which scans both the source code and resulting docker image for vulnerable dependencies, and ClamAV to scan for malware. - Add a workflow to scan for static analysis problems with Coverity. Requires COVERITY_TOKEN secret to be present in the repository. qemu: - Add a workflow which builds the patched QEMU, based on kubevirt-patch/README.md. Also enable Trivy & ClamAV scans. This does not yet build or scan the full kubevirt environment. Signed-off-by: Byron Marohn --- .github/actions/setup-tools/action.yaml | 13 ++ .github/workflows/device_plugin.yaml | 104 +++++++++++++ .github/workflows/device_plugin_coverity.yaml | 103 ++++++++++++ .github/workflows/qemu.yaml | 146 ++++++++++++++++++ device-plugins-for-kubernetes/README.md | 8 +- device-plugins-for-kubernetes/build.sh | 74 ++++++++- kubevirt-patch/README.md | 29 ++-- 7 files changed, 448 insertions(+), 29 deletions(-) create mode 100644 .github/actions/setup-tools/action.yaml create mode 100644 .github/workflows/device_plugin.yaml create mode 100644 .github/workflows/device_plugin_coverity.yaml create mode 100644 .github/workflows/qemu.yaml diff --git a/.github/actions/setup-tools/action.yaml b/.github/actions/setup-tools/action.yaml new file mode 100644 index 0000000..4a540d6 --- /dev/null +++ b/.github/actions/setup-tools/action.yaml @@ -0,0 +1,13 @@ +name: 'Setup Tools' +description: 'Sets up required tools' + +runs: + using: "composite" + steps: + - name: Setup Go + uses: actions/setup-go@v5 + + - name: Install Trivy + shell: bash + run: | + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin diff --git a/.github/workflows/device_plugin.yaml b/.github/workflows/device_plugin.yaml new file mode 100644 index 0000000..0f04d4e --- /dev/null +++ b/.github/workflows/device_plugin.yaml @@ -0,0 +1,104 @@ +--- +# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +name: "Device Plugin: Build, Trivy & ClamAV Scan" +run-name: "Workflow (by @${{ github.actor }} via ${{ github.event_name }})" + +# Only run at most 1 workflow concurrently per PR, unlimited for branches +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +on: + pull_request: + branches: + - main + push: + branches: + - main + +jobs: + device-plugins-for-kubernetes: + permissions: + contents: read + runs-on: ubuntu-24.04 + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Setup Tools + uses: ./.github/actions/setup-tools + + - name: Build the device plugin and docker image + working-directory: device-plugins-for-kubernetes + continue-on-error: false + run: | + ./build.sh --ver "$GITHUB_SHA" --repo "localhost" + - name: trivy repo scan + continue-on-error: false + shell: bash + working-directory: device-plugins-for-kubernetes + run: | + trivy --version + which trivy + trivy image --download-db-only + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl + + # Use the downloaded template + trivy fs . --format template --template "@trivy-html.tpl" -o "trivy_code_scan_core.html" + + - name: Upload trivy reports + continue-on-error: false + uses: actions/upload-artifact@v4 + with: + name: trivy-code-scan-results-core + path: | + device-plugins-for-kubernetes/trivy_code_scan_core.html + + - name: Trivy Image Scan + continue-on-error: false + shell: bash + run: | + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl + trivy image "localhost/mf-device-plugin:$GITHUB_SHA" --ignore-unfixed --format template --template "@trivy-html.tpl" -o device-plugins-for-kubernetes/trivy_image_scan_core-backend.html + trivy image --quiet --format spdx-json --output device-plugins-for-kubernetes/trivy_image_scan_core-backend.spdx.json "localhost/mf-device-plugin:$GITHUB_SHA" + + - name: Upload Trivy Image Report + continue-on-error: false + uses: actions/upload-artifact@v4 + with: + name: Trivy image scan report-core + path: | + device-plugins-for-kubernetes/trivy_image_scan_core-backend.html + device-plugins-for-kubernetes/trivy_image_scan_core-backend.spdx.json + + - name: ClamAV Antivirus Scan + continue-on-error: false + shell: bash + run: | + echo "Starting ClamAV scan on device-plugins-for-kubernetes/..." + + docker run --rm \ + --mount type=bind,source=./device-plugins-for-kubernetes/,target=/scandir \ + clamav/clamav:stable \ + clamscan --recursive --log=/scandir/clamav-scan-report.log \ + /scandir + + SCAN_EXIT_CODE=$? + sudo chown $USER:$USER device-plugins-for-kubernetes/clamav-scan-report.log 2>/dev/null || true + + if [ $SCAN_EXIT_CODE -ne 0 ]; then + echo "ClamAV scan failed or found issues" + exit 1 + fi + + - name: Upload Antivirus Report + continue-on-error: true + if: always() + uses: actions/upload-artifact@v4 + with: + name: antivirus-report-core + path: device-plugins-for-kubernetes/clamav-scan-report.log diff --git a/.github/workflows/device_plugin_coverity.yaml b/.github/workflows/device_plugin_coverity.yaml new file mode 100644 index 0000000..fbe14a7 --- /dev/null +++ b/.github/workflows/device_plugin_coverity.yaml @@ -0,0 +1,103 @@ +name: "Device Plugin: Coverity Scan" +run-name: "Workflow (by @${{ github.actor }} via ${{ github.event_name }})" + +on: + # Allow this to also be manually scheduled against a specific branch + workflow_dispatch: + inputs: + branch: + description: 'Branch to run on' + required: true + default: 'main' + schedule: + # Run at 01:35 UTC every day + # Chosen arbitrarily and could be moved - 01:30 UTC is generally after workday ends in US and before it starts in India + - cron: "35 1 * * *" + # TODO REMOVE THIS - JUST FOR TESTING + pull_request: + branches: + - main + +permissions: read-all + +jobs: + coverity: + name: Coverity + + runs-on: ubuntu-24.04 + defaults: + run: + shell: bash -noprofile --norc -eo pipefail {0} + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Load coverity from cache + id: cache-coverity + uses: actions/cache@v4 + env: + cache-name: cache-coverity + with: + path: $HOME/coverity + # Update coverity each month + key: coverity-$(date +%Y%m) + + - name: Debug COVERITY_TOKEN + run: | + if [ -z "$COVERITY_TOKEN" ]; then + echo "COVERITY_TOKEN is not set" + exit 1 + else + echo "COVERITY_TOKEN is set" + fi + env: + COVERITY_TOKEN: ${{ secrets.COVERITY_TOKEN }} + + - name: Download coverity + if: ${{ steps.cache-coverity.outputs.cache-hit != 'true' }} + env: + COVERITY_TOKEN: ${{ secrets.COVERITY_TOKEN }} + run: | + cd $HOME + wget https://scan.coverity.com/download/linux64 --post-data "token=$COVERITY_TOKEN&project=open-edge-platform%2Fedge-desktop-virtualization" -O coverity.tgz + tar zxf coverity.tgz + mv -T cov-analysis-linux64-* coverity + + - name: Add coverity to PATH + run: | + echo "$HOME/coverity/bin" >> $GITHUB_PATH + + - name: Show coverity version + run: | + coverity --version + + - name: Run coverity build + working-directory: device-plugins-for-kubernetes + continue-on-error: false + run: | + cov-build --dir $HOME/cov-int ./build.sh --ver "$GITHUB_SHA" --repo "localhost" + + - name: Create coverity results tarball + run: | + cd $HOME + tail cov-int/build-log.txt + tar zcf cov-int.tgz cov-int + + - name: Create coverity build + env: + COVERITY_TOKEN: ${{ secrets.COVERITY_TOKEN }} + run: | + cd $HOME + echo "VERSION=$GITHUB_SHA" + ls -hal cov-int.tgz + echo "NOTE: If size above is > 500 MB, this will fail and need to be restructured to use the more advanced coverity API" + + curl --form token=$COVERITY_TOKEN \ + --form email=byron.marohn@intel.com \ + --form file=@cov-int.tgz \ + --form version="$VERSION" \ + --form description="Coverity build for edge-desktop-virtualization@$VERSION" \ + https://scan.coverity.com/builds?project=open-edge-platform%2Fedge-desktop-virtualization diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml new file mode 100644 index 0000000..d998c39 --- /dev/null +++ b/.github/workflows/qemu.yaml @@ -0,0 +1,146 @@ +--- +# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +name: "QEMU: Build, Trivy & ClamAV Scan" +run-name: "Workflow (by @${{ github.actor }} via ${{ github.event_name }})" + +# Only run at most 1 workflow concurrently per PR, unlimited for branches +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +on: + pull_request: + branches: + - main + push: + branches: + - main + +jobs: + qemu-build-and-scan: + permissions: + contents: read + runs-on: ubuntu-24.04 + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Setup Tools + uses: ./.github/actions/setup-tools + + - name: Cache QEMU source & build directory + id: cache-qemu + uses: actions/cache@v4 + env: + cache-name: cache-qemu + with: + path: workspace/qemu-8.2.1 + # Use the hash of the document this workflow is based on to decide whether the build should be re-run or not + key: qemu-binary-$(hashFiles('kubevirt-patch/README.md') + + - name: Build and patch QEMU + continue-on-error: false + if: ${{ steps.cache-qemu.outputs.cache-hit != 'true' }} + # Each logical block here is copied exactly from a code block in docs/kubevirt-patch-qemu-sriov.md + run: | + mkdir -p workspace + cd workspace + wget -N --no-check-certificate https://download.01.org/intel-linux-overlay/ubuntu/pool/main/q/qemu/qemu_8.2.1+ppa1-noble9.debian.tar.xz + mkdir qemu_8.2.1+ppa1-noble9.debian + tar -xf 'qemu_8.2.1+ppa1-noble9.debian.tar.xz' -C 'qemu_8.2.1+ppa1-noble9.debian' + + wget -N --no-check-certificate https://download.qemu.org/qemu-8.2.1.tar.xz + tar -xf qemu-8.2.1.tar.xz + cd qemu-8.2.1 + + cp -r ../qemu_8.2.1+ppa1-noble9.debian/debian/patches/sriov/ . + + git apply ./sriov/*.patch + + ./tests/lcitool/libvirt-ci/bin/lcitool --data-dir ./tests/lcitool dockerfile centos-stream-9 qemu > Dockerfile.centos-stream9 + perl -p -i -e 's|zstd &&|zstd libslirp-devel liburing-devel libbpf-devel libblkio-devel &&|g' Dockerfile.centos-stream9 + + docker build -t qemu_build:centos-stream9 -f Dockerfile.centos-stream9 . + cat < buildscript.sh + #!/bin/bash + set -x + set -e + cd /src + rm -rf build + ./configure --prefix=/usr --enable-kvm --disable-xen --enable-libusb --enable-debug-info --enable-debug --enable-sdl --enable-vhost-net --enable-spice --disable-debug-tcg --enable-opengl --enable-gtk --enable-virtfs --target-list=x86_64-softmmu --audio-drv-list=pa --firmwarepath=/usr/share/qemu-firmware:/usr/share/ipxe/qemu:/usr/share/seavgabios:/usr/share/seabios:/usr/share/qemu-kvm/ --disable-spice + mkdir -p build + cd build + ninja + ninja install + EOF + chmod +x buildscript.sh + + docker run \ + -v $(pwd):/src:Z \ + -w /src \ + --entrypoint=/src/buildscript.sh \ + --security-opt label=disable \ + qemu_build:centos-stream9 + + ls -la build/qemu-system-x86_64 + sha256sum build/qemu-system-x86_64 + + - name: Upload qemu-system-x86_64 artifact + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: qemu-system-x86_64 artifact + path: | + workspace/qemu-8.2.1/build/qemu-system-x86_64 + + - name: trivy qemu source scan + continue-on-error: true + shell: bash + run: | + cd workspace/qemu-8.2.1 + trivy --version + which trivy + trivy image --download-db-only + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl + + # Use the downloaded template + trivy fs . --format template --template "@trivy-html.tpl" --exit-code 1 --severity MEDIUM,HIGH,CRITICAL -o "trivy_code_scan_qemu.html" + + - name: Upload trivy reports + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: trivy-code-scan-results-core + path: | + workspace/qemu-8.2.1/trivy_code_scan_qemu.html + + - name: ClamAV QEMU Antivirus Scan + continue-on-error: true + shell: bash + run: | + echo "Starting ClamAV scan on workspace/qemu-8.2.1/build/..." + + docker run --rm \ + --mount type=bind,source=./workspace/qemu-8.2.1/build/,target=/scandir \ + clamav/clamav:stable \ + clamscan --recursive --log=/scandir/clamav-scan-report.log \ + /scandir + + SCAN_EXIT_CODE=$? + sudo chown $USER:$USER workspace/qemu-8.2.1/build/clamav-scan-report.log 2>/dev/null || true + + if [ $SCAN_EXIT_CODE -ne 0 ]; then + echo "ClamAV scan failed or found issues" + exit 1 + fi + + - name: Upload QEMU Antivirus Report + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: antivirus-qemu-report-core + path: workspace/qemu-8.2.1/build/clamav-scan-report.log diff --git a/device-plugins-for-kubernetes/README.md b/device-plugins-for-kubernetes/README.md index 10f4917..afb03a9 100644 --- a/device-plugins-for-kubernetes/README.md +++ b/device-plugins-for-kubernetes/README.md @@ -27,16 +27,16 @@ The device plugin handles the following key functions[1]: * Mounting necessary device nodes * Mounting necessary volumes -## Build +## Build ### Local Setup To test it in local system, have a docker registry running in your system. ```shell docker run -d -p 5000:5000 --name registry registry:2.7 ``` -This registry is accessible through port `5000`. To have the device-plugin up and running in your kubernetes system, you can run the `build.sh` file. This script will delete the existing device-plugin, if any, build, push to registry and create the deployment. You can adjust the resulting docker image tag & repository by changing the optional arguments `version` (default "v1") and `repo` (default "127.0.0.1:5000"). +This registry is accessible through port `5000`. To have the device-plugin up and running in your kubernetes system, you can run the `build.sh` file. This script will delete the existing device-plugin, if any, build, and optionally push to registry and create the deployment. You can adjust the resulting docker image tag & repository by changing the optional arguments `ver` (default "v1") and `repo` (default "127.0.0.1:5000"). Add `--push` to push to the repo after the image is successfully built. ```shell -./build.sh [version] [repo] +./build.sh --ver v1 --repo "127.0.0.1:5000" --push ``` ## Deploy @@ -76,7 +76,7 @@ kube-system device-plugin-maverikflats-device-plugin-zxkqm 1/1 Ru ## Verify setup -Upon having the device-plugin up and running, you should see the resources and resource count show up in your node(s). +Upon having the device-plugin up and running, you should see the resources and resource count show up in your node(s). ```shell ➜ kubectl describe node Name: npgarch diff --git a/device-plugins-for-kubernetes/build.sh b/device-plugins-for-kubernetes/build.sh index cb8dddd..18456d1 100755 --- a/device-plugins-for-kubernetes/build.sh +++ b/device-plugins-for-kubernetes/build.sh @@ -3,18 +3,76 @@ # Copyright (C) 2025 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -VER="${1:-v1}" -DOCKER_REPO="${2:-127.0.0.1:5000}" +# Default values +DEFAULT_VER="v1" +DEFAULT_DOCKER_REPO="127.0.0.1:5000" +DEFAULT_PUSH="false" +VER="$DEFAULT_VER" +DOCKER_REPO="$DEFAULT_DOCKER_REPO" +PUSH="$DEFAULT_PUSH" +# Function to display usage +usage() { + echo "Usage: $0 [--ver ] [--repo ] [--push]" + echo " --ver Specify the version (default: $DEFAULT_VER)" + echo " --repo Specify the Docker repository (default: $DEFAULT_DOCKER_REPO)" + echo " --push Push the built image to the Docker repository (default: no push)" + exit 1 +} + +# Parse arguments +while [[ $# -gt 0 ]]; do + case "$1" in + --ver) + VER="$2" + shift 2 + ;; + --repo) + DOCKER_REPO="$2" + shift 2 + ;; + --push) + PUSH="true" + shift + ;; + *) + echo "Error: Unknown argument: $1" + usage + ;; + esac +done + +# Check if 'go' is installed if ! command -v go > /dev/null ; then echo "Error: 'go' not found in PATH, is it installed?" exit 1 fi -if [[ $VER != "" ]]; then - rm -f device-plugin - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o device-plugin cmd/main.go - docker build --no-cache -t localhost:5000/mf-device-plugin:$VER . - docker push localhost:5000/mf-device-plugin:$VER - docker tag localhost:5000/mf-device-plugin:$VER $DOCKER_REPO/mf-device-plugin:$VER +# Build the device plugin +echo "Building the device plugin..." +rm -f device-plugin +CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o device-plugin cmd/main.go +if [[ $? -ne 0 ]]; then + echo "Error: Failed to build the device plugin" + exit 1 +fi + +# Build the Docker image +echo "Building the Docker image..." +docker build --no-cache -t "$DOCKER_REPO/mf-device-plugin:$VER" . +if [[ $? -ne 0 ]]; then + echo "Error: Failed to build the Docker image" + exit 1 fi + +# Push the Docker image if --push is specified +if [[ $PUSH == "true" ]]; then + echo "Pushing the Docker image to the repository..." + ! docker push "$DOCKER_REPO/mf-device-plugin:$VER" + if [[ $? -ne 0 ]]; then + echo "Error: Failed to push the Docker image" + exit 1 + fi +fi + +echo "Build successful." diff --git a/kubevirt-patch/README.md b/kubevirt-patch/README.md index df1d03f..d69de2e 100644 --- a/kubevirt-patch/README.md +++ b/kubevirt-patch/README.md @@ -45,14 +45,15 @@ QEMU emulator version 9.0.0 (qemu-kvm-9.0.0-10.el9) The SRIOV patches to QEMU are based on QEMU 8.2.1 -1. Download the the SR-IOV patches for QEMU +1. Download the SR-IOV patches for QEMU ```sh cd ~/workspace wget -N --no-check-certificate https://download.01.org/intel-linux-overlay/ubuntu/pool/main/q/qemu/qemu_8.2.1+ppa1-noble9.debian.tar.xz - tar -xvf qemu_8.2.1+ppa1-noble9.debian.tar.xz + mkdir qemu_8.2.1+ppa1-noble9.debian + tar -xf 'qemu_8.2.1+ppa1-noble9.debian.tar.xz' -C 'qemu_8.2.1+ppa1-noble9.debian' ``` 1. Download the same version of QEMU that matches the downloaded patches: @@ -60,7 +61,7 @@ The SRIOV patches to QEMU are based on QEMU 8.2.1 ```sh wget -N --no-check-certificate https://download.qemu.org/qemu-8.2.1.tar.xz - tar -xvf qemu-8.2.1.tar.xz + tar -xf qemu-8.2.1.tar.xz cd qemu-8.2.1 ``` @@ -75,8 +76,6 @@ The SRIOV patches to QEMU are based on QEMU 8.2.1 ```sh git apply ./sriov/*.patch - - cd ~/workspace ``` ### 2.1 Creating CentOS 9 containerized environment @@ -88,26 +87,22 @@ The original idea to build within the Centos container comes from this [link](ht 1. Generate the Centos 9 image to be used for QEMU build environment ```sh - cd qemu-8.2.1 - ./tests/lcitool/libvirt-ci/bin/lcitool --data-dir ./tests/lcitool dockerfile centos-stream-9 qemu > Dockerfile.centos-stream9 ``` 1. Patch `Dockerfile.centos-stream9` to include missing dependencies ```sh - vim Dockerfile.centos-stream9 + perl -p -i -e 's|zstd &&|zstd libslirp-devel liburing-devel libbpf-devel libblkio-devel &&|g' Dockerfile.centos-stream9 ``` + This makes the following changes to `Dockerfile.centos-stream9` + ```diff zlib-devel \ zlib-static \ - - zstd && - + zstd \ - + libslirp-devel \ - + liburing-devel \ - + libbpf-devel \ - + libblkio-devel && \ + - zstd && \ + + zstd libslirp-devel liburing-devel libbpf-devel libblkio-devel && \ dnf autoremove -y && \ dnf clean all -y && \ rpm -qa | sort > /packages.txt && \ @@ -177,7 +172,7 @@ The original idea to build within the Centos container comes from this [link](ht 13c2760bf012a8011ddbe0c595ec3dca24249debe32bc4d1e338ec8538ad7453 build/qemu-system-x86_64 ``` -## 3. Enabling Kubevirt with GTK display support libararies +## 3. Enabling Kubevirt with GTK display support libraries 1. Clone the kubevirt repo: @@ -346,7 +341,7 @@ The original idea to build within the Centos container comes from this [link](ht 5. Ensure Kubernetes is installed and local cluster is running. 6. Import the images into the container runtime ```sh - sudo ctr -n k8s.io images import sidecar-shim.tar + sudo ctr -n k8s.io images import sidecar-shim.tar sudo ctr -n k8s.io images import virt-api.tar sudo ctr -n k8s.io images import virt-controller.tar sudo ctr -n k8s.io images import virt-handler.tar @@ -404,4 +399,4 @@ The original idea to build within the Centos container comes from this [link](ht NAME AGE PHASE kubevirt.kubevirt.io/kubevirt 19d Deployed - ``` \ No newline at end of file + ``` From f77ab058c7cb37f7b1835ab2943202e1b5ccff7d Mon Sep 17 00:00:00 2001 From: Byron Marohn Date: Tue, 17 Jun 2025 23:59:11 -0700 Subject: [PATCH 2/4] Remove coverity run on pull requests, only run daily via cron Signed-off-by: Byron Marohn --- .github/workflows/device_plugin_coverity.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/device_plugin_coverity.yaml b/.github/workflows/device_plugin_coverity.yaml index fbe14a7..002578d 100644 --- a/.github/workflows/device_plugin_coverity.yaml +++ b/.github/workflows/device_plugin_coverity.yaml @@ -13,10 +13,6 @@ on: # Run at 01:35 UTC every day # Chosen arbitrarily and could be moved - 01:30 UTC is generally after workday ends in US and before it starts in India - cron: "35 1 * * *" - # TODO REMOVE THIS - JUST FOR TESTING - pull_request: - branches: - - main permissions: read-all From d04c799e30b373ef46c941a1b53994007cad8eb2 Mon Sep 17 00:00:00 2001 From: Byron Marohn Date: Wed, 18 Jun 2025 14:39:35 -0700 Subject: [PATCH 3/4] WIP: Add automated build for Kubevirt; release tarball packaging - kubevirt components should work, but currently run out of space on the github actions runner Additional improvements: - Add release tarball artifact for device-plugins-for-kubernetes - Add EDV_VERSION environment variable to all jobs for consistent Versioning - Add EDV_HOME environment variable to easily reference top-level code directory - Improve device-plugins-for-kubernetes/build.sh to update the version in the deployment manifest Signed-off-by: Byron Marohn --- .github/actions/setup-tools/action.yaml | 30 +++++ .github/workflows/device_plugin.yaml | 46 ++++++- .github/workflows/device_plugin_coverity.yaml | 15 ++- .../{qemu.yaml => qemu-kubevirt.yaml} | 126 ++++++++++++++++-- device-plugins-for-kubernetes/build.sh | 3 + kubevirt-patch/README.md | 17 +-- 6 files changed, 208 insertions(+), 29 deletions(-) rename .github/workflows/{qemu.yaml => qemu-kubevirt.yaml} (50%) diff --git a/.github/actions/setup-tools/action.yaml b/.github/actions/setup-tools/action.yaml index 4a540d6..ed18336 100644 --- a/.github/actions/setup-tools/action.yaml +++ b/.github/actions/setup-tools/action.yaml @@ -5,9 +5,39 @@ runs: using: "composite" steps: - name: Setup Go + continue-on-error: false uses: actions/setup-go@v5 - name: Install Trivy + continue-on-error: false shell: bash run: | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin + + - name: Set EDV_VERSION to the current git version for this actions run + continue-on-error: false + shell: bash + run: | + # Print the most recent commit + echo "Most recent commit:" + git log -1 + + if [[ $(git log | grep commit | wc -l) -lt 10 ]]; then + echo "Commit history is squashed, EDV_VERSION will be wrong. Calling action should checkout code with fetch-depth:0" + exit 1 + fi + + # Version based on commits since the most recent tag + # If the current commit is a tag, use that tag + # If not, use -- + # i.e. v1-11-gdc6c0bd + EDV_VERSION="$(git describe --tags --always)" + + echo "EDV_VERSION=$EDV_VERSION" + echo "EDV_VERSION=$EDV_VERSION" >> $GITHUB_ENV + + - name: Set EDV_HOME to the checked-out edge-desktop-virtualization source code + continue-on-error: false + shell: bash + run: | + echo "EDV_HOME=$(pwd)" >> $GITHUB_ENV diff --git a/.github/workflows/device_plugin.yaml b/.github/workflows/device_plugin.yaml index 0f04d4e..0fac3fd 100644 --- a/.github/workflows/device_plugin.yaml +++ b/.github/workflows/device_plugin.yaml @@ -17,6 +17,8 @@ on: push: branches: - main + tags: + - "*" jobs: device-plugins-for-kubernetes: @@ -28,15 +30,45 @@ jobs: uses: actions/checkout@v4 with: persist-credentials: false + fetch-depth: 0 # All history, not just latest commit + ref: ${{ github.event.pull_request.head.sha }} # Check out the actual commit, not a fake merge commit - - name: Setup Tools + - name: Setup Tools & Common Variables uses: ./.github/actions/setup-tools - name: Build the device plugin and docker image working-directory: device-plugins-for-kubernetes continue-on-error: false run: | - ./build.sh --ver "$GITHUB_SHA" --repo "localhost" + ./build.sh --ver "$EDV_VERSION" --repo "localhost:5000" + + - name: Build device plugin release tarball + working-directory: device-plugins-for-kubernetes + continue-on-error: false + run: | + mkdir device-plugin-artifacts + cd device-plugin-artifacts + + docker image pull busybox:latest + docker image tag busybox:latest localhost:5000/busybox:latest + docker image save -o busybox.tar localhost:5000/busybox:latest + + docker image save -o device-plugin.tar "localhost:5000/mf-device-plugin:$EDV_VERSION" + + cp -a ../deploy/manifests/maverikflats-device-plugin.yaml device-plugin.yaml + + tar czf intel-idv-device-plugin-$EDV_VERSION.tar.gz busybox.tar device-plugin.tar device-plugin.yaml + + ls -hal + + - name: Upload device plugin release tarball + continue-on-error: false + uses: actions/upload-artifact@v4 + with: + name: device-plugin artifacts + path: | + device-plugins-for-kubernetes/device-plugin-artifacts/intel-idv-device-plugin-${{ env.EDV_VERSION }}.tar.gz + - name: trivy repo scan continue-on-error: false shell: bash @@ -59,12 +91,12 @@ jobs: device-plugins-for-kubernetes/trivy_code_scan_core.html - name: Trivy Image Scan - continue-on-error: false + continue-on-error: true shell: bash run: | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl - trivy image "localhost/mf-device-plugin:$GITHUB_SHA" --ignore-unfixed --format template --template "@trivy-html.tpl" -o device-plugins-for-kubernetes/trivy_image_scan_core-backend.html - trivy image --quiet --format spdx-json --output device-plugins-for-kubernetes/trivy_image_scan_core-backend.spdx.json "localhost/mf-device-plugin:$GITHUB_SHA" + trivy image "localhost:5000/mf-device-plugin:$EDV_VERSION" --ignore-unfixed --format template --template "@trivy-html.tpl" -o device-plugins-for-kubernetes/trivy_image_scan_core-backend.html + trivy image --quiet --format spdx-json --output device-plugins-for-kubernetes/trivy_image_scan_core-backend.spdx.json "localhost:5000/mf-device-plugin:$EDV_VERSION" - name: Upload Trivy Image Report continue-on-error: false @@ -76,7 +108,7 @@ jobs: device-plugins-for-kubernetes/trivy_image_scan_core-backend.spdx.json - name: ClamAV Antivirus Scan - continue-on-error: false + continue-on-error: true shell: bash run: | echo "Starting ClamAV scan on device-plugins-for-kubernetes/..." @@ -96,7 +128,7 @@ jobs: fi - name: Upload Antivirus Report - continue-on-error: true + continue-on-error: false if: always() uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/device_plugin_coverity.yaml b/.github/workflows/device_plugin_coverity.yaml index 002578d..26f207d 100644 --- a/.github/workflows/device_plugin_coverity.yaml +++ b/.github/workflows/device_plugin_coverity.yaml @@ -13,6 +13,9 @@ on: # Run at 01:35 UTC every day # Chosen arbitrarily and could be moved - 01:30 UTC is generally after workday ends in US and before it starts in India - cron: "35 1 * * *" + push: + tags: + - "*" permissions: read-all @@ -30,6 +33,11 @@ jobs: uses: actions/checkout@v4 with: persist-credentials: false + fetch-depth: 0 # All history, not just latest commit + ref: ${{ github.event.pull_request.head.sha }} # Check out the actual commit, not a fake merge commit + + - name: Setup Tools & Common Variables + uses: ./.github/actions/setup-tools - name: Load coverity from cache id: cache-coverity @@ -74,7 +82,7 @@ jobs: working-directory: device-plugins-for-kubernetes continue-on-error: false run: | - cov-build --dir $HOME/cov-int ./build.sh --ver "$GITHUB_SHA" --repo "localhost" + cov-build --dir $HOME/cov-int ./build.sh --ver "$EDV_VERSION" --repo "localhost" - name: Create coverity results tarball run: | @@ -87,13 +95,12 @@ jobs: COVERITY_TOKEN: ${{ secrets.COVERITY_TOKEN }} run: | cd $HOME - echo "VERSION=$GITHUB_SHA" ls -hal cov-int.tgz echo "NOTE: If size above is > 500 MB, this will fail and need to be restructured to use the more advanced coverity API" curl --form token=$COVERITY_TOKEN \ --form email=byron.marohn@intel.com \ --form file=@cov-int.tgz \ - --form version="$VERSION" \ - --form description="Coverity build for edge-desktop-virtualization@$VERSION" \ + --form version="$EDV_VERSION" \ + --form description="Coverity build for edge-desktop-virtualization@$EDV_VERSION" \ https://scan.coverity.com/builds?project=open-edge-platform%2Fedge-desktop-virtualization diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu-kubevirt.yaml similarity index 50% rename from .github/workflows/qemu.yaml rename to .github/workflows/qemu-kubevirt.yaml index d998c39..cab1bb3 100644 --- a/.github/workflows/qemu.yaml +++ b/.github/workflows/qemu-kubevirt.yaml @@ -2,7 +2,7 @@ # SPDX-FileCopyrightText: (C) 2025 Intel Corporation # SPDX-License-Identifier: Apache-2.0 -name: "QEMU: Build, Trivy & ClamAV Scan" +name: "QEMU & Kubevirt: Build, Trivy & ClamAV Scan" run-name: "Workflow (by @${{ github.actor }} via ${{ github.event_name }})" # Only run at most 1 workflow concurrently per PR, unlimited for branches @@ -17,19 +17,25 @@ on: push: branches: - main + tags: + - "*" jobs: qemu-build-and-scan: permissions: contents: read runs-on: ubuntu-24.04 + outputs: + qemu-artifact-id: ${{ steps.upload-qemu.outputs.artifact-id }} steps: - name: Checkout Code uses: actions/checkout@v4 with: persist-credentials: false + fetch-depth: 0 # All history, not just latest commit + ref: ${{ github.event.pull_request.head.sha }} # Check out the actual commit, not a fake merge commit - - name: Setup Tools + - name: Setup Tools & Common Variables uses: ./.github/actions/setup-tools - name: Cache QEMU source & build directory @@ -40,12 +46,12 @@ jobs: with: path: workspace/qemu-8.2.1 # Use the hash of the document this workflow is based on to decide whether the build should be re-run or not - key: qemu-binary-$(hashFiles('kubevirt-patch/README.md') + key: qemu-binary-${{ hashFiles('kubevirt-patch/README.md') }} - name: Build and patch QEMU continue-on-error: false if: ${{ steps.cache-qemu.outputs.cache-hit != 'true' }} - # Each logical block here is copied exactly from a code block in docs/kubevirt-patch-qemu-sriov.md + # Each logical block here is copied exactly from a code block in kubevirt-patch/README.md run: | mkdir -p workspace cd workspace @@ -90,10 +96,11 @@ jobs: sha256sum build/qemu-system-x86_64 - name: Upload qemu-system-x86_64 artifact - continue-on-error: true + id: upload-qemu + continue-on-error: false uses: actions/upload-artifact@v4 with: - name: qemu-system-x86_64 artifact + name: qemu-artifact path: | workspace/qemu-8.2.1/build/qemu-system-x86_64 @@ -111,7 +118,7 @@ jobs: trivy fs . --format template --template "@trivy-html.tpl" --exit-code 1 --severity MEDIUM,HIGH,CRITICAL -o "trivy_code_scan_qemu.html" - name: Upload trivy reports - continue-on-error: true + continue-on-error: false uses: actions/upload-artifact@v4 with: name: trivy-code-scan-results-core @@ -139,8 +146,111 @@ jobs: fi - name: Upload QEMU Antivirus Report - continue-on-error: true + continue-on-error: false uses: actions/upload-artifact@v4 with: name: antivirus-qemu-report-core path: workspace/qemu-8.2.1/build/clamav-scan-report.log + + kubevirt-build-and-scan: + needs: qemu-build-and-scan + permissions: + contents: read + runs-on: ubuntu-24.04 + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + persist-credentials: false + fetch-depth: 0 # All history, not just latest commit + ref: ${{ github.event.pull_request.head.sha }} # Check out the actual commit, not a fake merge commit + + - name: Setup Tools & Common Variables + uses: ./.github/actions/setup-tools + + - name: Cache Kubevirt output artifacts + id: cache-kubevirt + uses: actions/cache@v4 + env: + cache-name: cache-kubevirt + with: + path: workspace/kubevirt-artifacts + # Use the hash of the document this workflow is based on to decide whether the build should be re-run or not + key: kubevirt-binary-${{ hashFiles('kubevirt-patch/0001-Bump-dependency-versions-for-kubevirt-v1.5.0.patch', 'kubevirt-patch/0001-Patching-Kubevirt-with-GTK-libraries_v1.patch', 'kubevirt-patch/README.md') }} + + - name: Run local docker registry + continue-on-error: false + run: | + # Run a local registry + docker run -d -p 5000:5000 --name registry registry:2.7 + + - name: Download QEMU artifact + uses: actions/download-artifact@v4 + with: + artifact-ids: ${{ needs.qemu-build-and-scan.outputs.qemu-artifact-id }} + path: . # Will unpack into a folder with the name used in upload-artifact, containing the binary + + - name: Build and patch kubevirt + continue-on-error: false + if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' }} + # Each logical block here is copied exactly from a code block in kubevirt-patch/README.md + run: | + mkdir -p workspace + cd workspace + git clone https://github.com/kubevirt/kubevirt.git + cd kubevirt + + git checkout v1.5.0 + + git apply $EDV_HOME/kubevirt-patch/0001-Bump-dependency-versions-for-kubevirt-v1.5.0.patch + + git apply $EDV_HOME/kubevirt-patch/0001-Patching-Kubevirt-with-GTK-libraries_v1.patch + + mkdir build + cp $EDV_HOME/qemu-artifact/qemu-system-x86_64 build/qemu-system-x86_64 + + QEMU_SHA256="$(sha256sum ./build/qemu-system-x86_64 | cut -d ' ' -f 1)" + echo "QEMU_SHA256=$QEMU_SHA256" + perl -p -i -e "s||$QEMU_SHA256|g" WORKSPACE + + export DOCKER_PREFIX=localhost:5000 + export DOCKER_TAG=$EDV_VERSION + + make rpm-deps + make all + make bazel-build-images + + make push + + make manifests + + - name: Export kubevirt build artifacts to output directory + continue-on-error: false + shell: bash + working-directory: workspace/kubevirt-artifacts + run: | + cp -a ../kubevirt/_out/manifests/release/kubevirt-operator.yaml + cp -a ../kubevirt/_out/manifests/release/kubevirt-cr.yaml + docker image pull localhost:5000/sidecar-shim:$EDV_VERSION + docker image pull localhost:5000/virt-api:$EDV_VERSION + docker image pull localhost:5000/virt-handler:$EDV_VERSION + docker image pull localhost:5000/virt-launcher:$EDV_VERSION + docker image pull localhost:5000/virt-operator:$EDV_VERSION + docker image pull localhost:5000/virt-controller:$EDV_VERSION + docker save -o sidecar-shim.tar localhost:5000/sidecar-shim:$EDV_VERSION + docker save -o virt-api.tar localhost:5000/virt-api:$EDV_VERSION + docker save -o virt-controller.tar localhost:5000/virt-controller:$EDV_VERSION + docker save -o virt-handler.tar localhost:5000/virt-handler:$EDV_VERSION + docker save -o virt-launcher.tar localhost:5000/virt-launcher:$EDV_VERSION + docker save -o virt-operator.tar localhost:5000/virt-operator:$EDV_VERSION + tar czf intel-idv-kubevirt-$EDV_VERSION.tar.gz *.tar *.yaml + + ls -hal + + - name: Upload kubevirt artifacts + continue-on-error: false + uses: actions/upload-artifact@v4 + with: + name: kubevirt artifacts + path: | + workspace/kubevirt-artifacts/intel-idv-kubevirt-${{ env.EDV_VERSION }}.tar.gz diff --git a/device-plugins-for-kubernetes/build.sh b/device-plugins-for-kubernetes/build.sh index 18456d1..20079ad 100755 --- a/device-plugins-for-kubernetes/build.sh +++ b/device-plugins-for-kubernetes/build.sh @@ -75,4 +75,7 @@ if [[ $PUSH == "true" ]]; then fi fi +# Update the deployment manifest with the newly built image version +perl -p -i -e "s|image:.*mf-device-plugin:.*$|image: '$DOCKER_REPO/mf-device-plugin:$VER'|g" deploy/manifests/maverikflats-device-plugin.yaml + echo "Build successful." diff --git a/kubevirt-patch/README.md b/kubevirt-patch/README.md index 242bd26..725339c 100644 --- a/kubevirt-patch/README.md +++ b/kubevirt-patch/README.md @@ -177,12 +177,9 @@ The original idea to build within the Centos container comes from this [link](ht 1. Clone the kubevirt repo: ```sh - mkdir ~/workspace - + mkdir -p ~/workspace cd ~/workspace - git clone https://github.com/kubevirt/kubevirt.git - cd kubevirt ``` @@ -191,16 +188,16 @@ The original idea to build within the Centos container comes from this [link](ht git checkout v1.5.0 ``` -1. Apply a patch to kubevirt to update dependencies which resolve potential security issues since the original v1.5.0 kubevirt was released +1. Apply a patch to kubevirt to update dependencies which resolve potential security issues since the original v1.5.0 kubevirt was released. $EDV_HOME should be set to the path to the top level of this repository (e.g. edge-desktop-virtualization). ```sh - git apply your/path/to/kubevirt-patch/0001-Bump-dependency-versions-for-kubevirt-v1.5.0.patch + git apply $EDV_HOME/kubevirt-patch/0001-Bump-dependency-versions-for-kubevirt-v1.5.0.patch ``` 1. [OPTIONAL] Update kubevirt dependency images using the `make bump-images` command. Note that you may also have to update `go_version` in `WORKSPACE` if applicable. 1. Apply the kubevirt patch from this repo to expand kubevirt virt-launcher image with additional dependencies to support GTK ```sh - git apply your/path/to/kubevirt-patch/0001-Patching-Kubevirt-with-GTK-libraries_v1.patch + git apply $EDV_HOME/kubevirt-patch/0001-Patching-Kubevirt-with-GTK-libraries_v1.patch ``` 1. Create a directory to place the custom QEMU binary and copy it from the QEMU build @@ -213,13 +210,13 @@ The original idea to build within the Centos container comes from this [link](ht 1. Obtain the `SHA` hash number of the QEMU binary ```sh - sha256sum ./build/qemu-system-x86_64 - 13c2760bf012a8011ddbe0c595ec3dca24249debe32bc4d1e338ec8538ad7453 ./build/qemu-system-x86_64 + QEMU_SHA256="$(sha256sum ./build/qemu-system-x86_64 | cut -d ' ' -f 1)" + echo "QEMU_SHA256=$QEMU_SHA256" ``` 1. Patch the top level `WORKSPACE` file in top level `kubevirt` directory. Replace `` with your sha256sum from the previous step ```sh - vim WORKSPACE + perl -p -i -e "s||$QEMU_SHA256|g" WORKSPACE ``` 1. Export the location of the docker registry and build tag (local docker registry in this case) From 343056812b35b60affd617c27310e94756806b3f Mon Sep 17 00:00:00 2001 From: Byron Marohn Date: Thu, 19 Jun 2025 15:56:07 -0700 Subject: [PATCH 4/4] Working kubevirt build, release artifacts, trivy scans - Improved shared actions file with some limited settings - Cleaned up disk space on runner to make room for kubevirt build - Caching to make kubevirt not have to build for 30m every time - Misc cleanup to other working actions Signed-off-by: Byron Marohn --- .github/actions/setup-tools/action.yaml | 16 +- .github/workflows/device_plugin.yaml | 7 - .github/workflows/device_plugin_coverity.yaml | 1 - .github/workflows/qemu-kubevirt.yaml | 152 ++++++++++++++++-- 4 files changed, 148 insertions(+), 28 deletions(-) diff --git a/.github/actions/setup-tools/action.yaml b/.github/actions/setup-tools/action.yaml index ed18336..0b0a68c 100644 --- a/.github/actions/setup-tools/action.yaml +++ b/.github/actions/setup-tools/action.yaml @@ -1,21 +1,30 @@ name: 'Setup Tools' description: 'Sets up required tools' +inputs: + go: + description: "Run setup-go action if true" + required: false + default: "true" + trivy: + description: "Install Trivy if true" + required: false + default: "true" + runs: using: "composite" steps: - name: Setup Go - continue-on-error: false + if: "${{ inputs.go == 'true' }}" uses: actions/setup-go@v5 - name: Install Trivy - continue-on-error: false + if: "${{ inputs.trivy == 'true' }}" shell: bash run: | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin - name: Set EDV_VERSION to the current git version for this actions run - continue-on-error: false shell: bash run: | # Print the most recent commit @@ -37,7 +46,6 @@ runs: echo "EDV_VERSION=$EDV_VERSION" >> $GITHUB_ENV - name: Set EDV_HOME to the checked-out edge-desktop-virtualization source code - continue-on-error: false shell: bash run: | echo "EDV_HOME=$(pwd)" >> $GITHUB_ENV diff --git a/.github/workflows/device_plugin.yaml b/.github/workflows/device_plugin.yaml index 0fac3fd..26ce720 100644 --- a/.github/workflows/device_plugin.yaml +++ b/.github/workflows/device_plugin.yaml @@ -38,13 +38,11 @@ jobs: - name: Build the device plugin and docker image working-directory: device-plugins-for-kubernetes - continue-on-error: false run: | ./build.sh --ver "$EDV_VERSION" --repo "localhost:5000" - name: Build device plugin release tarball working-directory: device-plugins-for-kubernetes - continue-on-error: false run: | mkdir device-plugin-artifacts cd device-plugin-artifacts @@ -62,7 +60,6 @@ jobs: ls -hal - name: Upload device plugin release tarball - continue-on-error: false uses: actions/upload-artifact@v4 with: name: device-plugin artifacts @@ -70,7 +67,6 @@ jobs: device-plugins-for-kubernetes/device-plugin-artifacts/intel-idv-device-plugin-${{ env.EDV_VERSION }}.tar.gz - name: trivy repo scan - continue-on-error: false shell: bash working-directory: device-plugins-for-kubernetes run: | @@ -83,7 +79,6 @@ jobs: trivy fs . --format template --template "@trivy-html.tpl" -o "trivy_code_scan_core.html" - name: Upload trivy reports - continue-on-error: false uses: actions/upload-artifact@v4 with: name: trivy-code-scan-results-core @@ -99,7 +94,6 @@ jobs: trivy image --quiet --format spdx-json --output device-plugins-for-kubernetes/trivy_image_scan_core-backend.spdx.json "localhost:5000/mf-device-plugin:$EDV_VERSION" - name: Upload Trivy Image Report - continue-on-error: false uses: actions/upload-artifact@v4 with: name: Trivy image scan report-core @@ -128,7 +122,6 @@ jobs: fi - name: Upload Antivirus Report - continue-on-error: false if: always() uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/device_plugin_coverity.yaml b/.github/workflows/device_plugin_coverity.yaml index 26f207d..ed59456 100644 --- a/.github/workflows/device_plugin_coverity.yaml +++ b/.github/workflows/device_plugin_coverity.yaml @@ -80,7 +80,6 @@ jobs: - name: Run coverity build working-directory: device-plugins-for-kubernetes - continue-on-error: false run: | cov-build --dir $HOME/cov-int ./build.sh --ver "$EDV_VERSION" --repo "localhost" diff --git a/.github/workflows/qemu-kubevirt.yaml b/.github/workflows/qemu-kubevirt.yaml index cab1bb3..e1b5500 100644 --- a/.github/workflows/qemu-kubevirt.yaml +++ b/.github/workflows/qemu-kubevirt.yaml @@ -37,6 +37,8 @@ jobs: - name: Setup Tools & Common Variables uses: ./.github/actions/setup-tools + with: + go: "false" - name: Cache QEMU source & build directory id: cache-qemu @@ -49,7 +51,6 @@ jobs: key: qemu-binary-${{ hashFiles('kubevirt-patch/README.md') }} - name: Build and patch QEMU - continue-on-error: false if: ${{ steps.cache-qemu.outputs.cache-hit != 'true' }} # Each logical block here is copied exactly from a code block in kubevirt-patch/README.md run: | @@ -97,7 +98,6 @@ jobs: - name: Upload qemu-system-x86_64 artifact id: upload-qemu - continue-on-error: false uses: actions/upload-artifact@v4 with: name: qemu-artifact @@ -118,7 +118,6 @@ jobs: trivy fs . --format template --template "@trivy-html.tpl" --exit-code 1 --severity MEDIUM,HIGH,CRITICAL -o "trivy_code_scan_qemu.html" - name: Upload trivy reports - continue-on-error: false uses: actions/upload-artifact@v4 with: name: trivy-code-scan-results-core @@ -146,10 +145,9 @@ jobs: fi - name: Upload QEMU Antivirus Report - continue-on-error: false uses: actions/upload-artifact@v4 with: - name: antivirus-qemu-report-core + name: antivirus-qemu path: workspace/qemu-8.2.1/build/clamav-scan-report.log kubevirt-build-and-scan: @@ -167,6 +165,8 @@ jobs: - name: Setup Tools & Common Variables uses: ./.github/actions/setup-tools + with: + go: "false" - name: Cache Kubevirt output artifacts id: cache-kubevirt @@ -176,27 +176,53 @@ jobs: with: path: workspace/kubevirt-artifacts # Use the hash of the document this workflow is based on to decide whether the build should be re-run or not + # NOTE: This must be a superset of the qemu cache hashFiles above. In other words if qemu needs to be rebuilt, so does kubevirt key: kubevirt-binary-${{ hashFiles('kubevirt-patch/0001-Bump-dependency-versions-for-kubevirt-v1.5.0.patch', 'kubevirt-patch/0001-Patching-Kubevirt-with-GTK-libraries_v1.patch', 'kubevirt-patch/README.md') }} + ######################################################################################################3 + # The kubevirt workflow requires 30+ GB of free space to run successfully + # These steps delete many unnecessary files from the actions runner so that enough space is available + # These pieces are only run if a kubevirt build needs to be done + - name: Disable man-db to make package install and removal faster + if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' }} + run: | + echo 'set man-db/auto-update false' | sudo debconf-communicate >/dev/null + sudo dpkg-reconfigure man-db + + - name: Free Disk Space (Ubuntu) + if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' }} + # This is a fork of the popular jlumbroso/free-disk-space@main with faster performance + # @byron-marohn reviewed all the code in this specific commit on Jun 19 2025 + uses: xc2/free-disk-space@fbe203b3788f2bebe2c835a15925da303eaa5efe + with: + tool-cache: true + android: true + dotnet: true + haskell: true + large-packages: true + swap-storage: false # Retain swap file for improved build performance + + ######################################################################################################3 + - name: Run local docker registry - continue-on-error: false + if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' }} run: | # Run a local registry docker run -d -p 5000:5000 --name registry registry:2.7 - name: Download QEMU artifact + if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' }} uses: actions/download-artifact@v4 with: artifact-ids: ${{ needs.qemu-build-and-scan.outputs.qemu-artifact-id }} path: . # Will unpack into a folder with the name used in upload-artifact, containing the binary - name: Build and patch kubevirt - continue-on-error: false if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' }} # Each logical block here is copied exactly from a code block in kubevirt-patch/README.md run: | - mkdir -p workspace - cd workspace + mkdir -p $EDV_HOME/workspace + cd $EDV_HOME/workspace git clone https://github.com/kubevirt/kubevirt.git cd kubevirt @@ -224,33 +250,127 @@ jobs: make manifests + echo "Partition sizes & free space following build:" + df -h + - name: Export kubevirt build artifacts to output directory - continue-on-error: false + if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' }} shell: bash - working-directory: workspace/kubevirt-artifacts run: | - cp -a ../kubevirt/_out/manifests/release/kubevirt-operator.yaml - cp -a ../kubevirt/_out/manifests/release/kubevirt-cr.yaml + mkdir -p $EDV_HOME/workspace/kubevirt-artifacts + cd $EDV_HOME/workspace/kubevirt-artifacts + + cp $EDV_HOME/workspace/kubevirt/_out/manifests/release/kubevirt-operator.yaml . + cp $EDV_HOME/workspace/kubevirt/_out/manifests/release/kubevirt-cr.yaml . + docker image pull localhost:5000/sidecar-shim:$EDV_VERSION docker image pull localhost:5000/virt-api:$EDV_VERSION docker image pull localhost:5000/virt-handler:$EDV_VERSION docker image pull localhost:5000/virt-launcher:$EDV_VERSION docker image pull localhost:5000/virt-operator:$EDV_VERSION docker image pull localhost:5000/virt-controller:$EDV_VERSION + + docker save -o sidecar-shim.tar localhost:5000/sidecar-shim:$EDV_VERSION + docker save -o virt-api.tar localhost:5000/virt-api:$EDV_VERSION + docker save -o virt-controller.tar localhost:5000/virt-controller:$EDV_VERSION + docker save -o virt-handler.tar localhost:5000/virt-handler:$EDV_VERSION + docker save -o virt-launcher.tar localhost:5000/virt-launcher:$EDV_VERSION + docker save -o virt-operator.tar localhost:5000/virt-operator:$EDV_VERSION + + tar cvzf intel-idv-kubevirt-$EDV_VERSION.tar.gz *.tar *.yaml + + echo "Contents of $(pwd):" + ls -hal + + echo "Partition sizes & free space following export:" + df -h + + # If the cache was loaded, then the artifacts folder contains valid images which are still valid for this version + # (i.e. nothing changed about kubevirt or qemu, so there was no need to rebuild the images) + # However, they will have the old tag - whatever the tag was when they were built last + # Need to re-tag them and import them into docker so they're usable by subsequent steps + - name: Reload and re-tag cached images + if: ${{ steps.cache-kubevirt.outputs.cache-hit == 'true' }} + shell: bash + run: | + cd $EDV_HOME/workspace/kubevirt-artifacts + + # Extract the old version from the kubevirt-operator file + OLD_VERSION="$(cat kubevirt-operator.yaml | grep -A 1 KUBEVIRT_VERSION | grep value: | perl -p -e 's|^.*value: (.*)$|\1|g')" + + # Replace exactly OLD_VERSION with EDV_VERSION, even if they somehow contain regular expression metacharacters + perl -p -i -e "s|\\Q$OLD_VERSION\\E|$EDV_VERSION|g" kubevirt-operator.yaml + + docker image load -i $EDV_HOME/workspace/kubevirt-artifacts/sidecar-shim.tar + docker image load -i $EDV_HOME/workspace/kubevirt-artifacts/virt-api.tar + docker image load -i $EDV_HOME/workspace/kubevirt-artifacts/virt-controller.tar + docker image load -i $EDV_HOME/workspace/kubevirt-artifacts/virt-handler.tar + docker image load -i $EDV_HOME/workspace/kubevirt-artifacts/virt-launcher.tar + docker image load -i $EDV_HOME/workspace/kubevirt-artifacts/virt-operator.tar + + docker tag localhost:5000/sidecar-shim:$OLD_VERSION localhost:5000/sidecar-shim:$EDV_VERSION + docker tag localhost:5000/virt-api:$OLD_VERSION localhost:5000/virt-api:$EDV_VERSION + docker tag localhost:5000/virt-controller:$OLD_VERSION localhost:5000/virt-controller:$EDV_VERSION + docker tag localhost:5000/virt-handler:$OLD_VERSION localhost:5000/virt-handler:$EDV_VERSION + docker tag localhost:5000/virt-launcher:$OLD_VERSION localhost:5000/virt-launcher:$EDV_VERSION + docker tag localhost:5000/virt-operator:$OLD_VERSION localhost:5000/virt-operator:$EDV_VERSION + docker save -o sidecar-shim.tar localhost:5000/sidecar-shim:$EDV_VERSION docker save -o virt-api.tar localhost:5000/virt-api:$EDV_VERSION docker save -o virt-controller.tar localhost:5000/virt-controller:$EDV_VERSION docker save -o virt-handler.tar localhost:5000/virt-handler:$EDV_VERSION docker save -o virt-launcher.tar localhost:5000/virt-launcher:$EDV_VERSION docker save -o virt-operator.tar localhost:5000/virt-operator:$EDV_VERSION - tar czf intel-idv-kubevirt-$EDV_VERSION.tar.gz *.tar *.yaml + rm intel-idv-kubevirt*.tar.gz + tar cvzf intel-idv-kubevirt-$EDV_VERSION.tar.gz *.tar *.yaml + + echo "Contents of $(pwd):" ls -hal - name: Upload kubevirt artifacts - continue-on-error: false uses: actions/upload-artifact@v4 with: - name: kubevirt artifacts + name: kubevirt-artifacts path: | workspace/kubevirt-artifacts/intel-idv-kubevirt-${{ env.EDV_VERSION }}.tar.gz + + - name: Trivy Image Scan + continue-on-error: true + shell: bash + run: | + mkdir -p workspace/kubevirt-trivy + cd workspace/kubevirt-trivy + + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl + trivy image "localhost:5000/sidecar-shim:$EDV_VERSION" --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_sidecar-shim.html + trivy image "localhost:5000/virt-api:$EDV_VERSION" --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_virt-api.html + trivy image "localhost:5000/virt-controller:$EDV_VERSION" --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_virt-controller.html + trivy image "localhost:5000/virt-handler:$EDV_VERSION" --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_virt-handler.html + trivy image "localhost:5000/virt-launcher:$EDV_VERSION" --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_virt-launcher.html + trivy image "localhost:5000/virt-operator:$EDV_VERSION" --ignore-unfixed --format template --template "@trivy-html.tpl" -o trivy_virt-operator.html + + trivy image --quiet --format spdx-json --output trivy_sidecar-shim.spdx.json "localhost:5000/sidecar-shim:$EDV_VERSION" + trivy image --quiet --format spdx-json --output trivy_virt-api.spdx.json "localhost:5000/virt-api:$EDV_VERSION" + trivy image --quiet --format spdx-json --output trivy_virt-controller.spdx.json "localhost:5000/virt-controller:$EDV_VERSION" + trivy image --quiet --format spdx-json --output trivy_virt-handler.spdx.json "localhost:5000/virt-handler:$EDV_VERSION" + trivy image --quiet --format spdx-json --output trivy_virt-launcher.spdx.json "localhost:5000/virt-launcher:$EDV_VERSION" + trivy image --quiet --format spdx-json --output trivy_virt-operator.spdx.json "localhost:5000/virt-operator:$EDV_VERSION" + + - name: Upload Trivy Image Report + uses: actions/upload-artifact@v4 + with: + name: Trivy kubevirt image scan + path: | + workspace/kubevirt-trivy/trivy_sidecar-shim.html + workspace/kubevirt-trivy/trivy_virt-api.html + workspace/kubevirt-trivy/trivy_virt-controller.html + workspace/kubevirt-trivy/trivy_virt-handler.html + workspace/kubevirt-trivy/trivy_virt-launcher.html + workspace/kubevirt-trivy/trivy_virt-operator.html + workspace/kubevirt-trivy/trivy_sidecar-shim.spdx.json + workspace/kubevirt-trivy/trivy_virt-api.spdx.json + workspace/kubevirt-trivy/trivy_virt-controller.spdx.json + workspace/kubevirt-trivy/trivy_virt-handler.spdx.json + workspace/kubevirt-trivy/trivy_virt-launcher.spdx.json + workspace/kubevirt-trivy/trivy_virt-operator.spdx.json