Skip to content

Workflow (by @dependabot[bot] via pull_request) #373

Workflow (by @dependabot[bot] via pull_request)

Workflow (by @dependabot[bot] via pull_request) #373

---
# SPDX-FileCopyrightText: (C) 2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
name: "QEMU & Kubevirt"
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' }}
permissions:
contents: read
on:
pull_request:
branches:
- main
push:
branches:
- main
tags:
- "*"
workflow_dispatch:
inputs:
disable_cache:
description: "Run workflow without cache"
required: false
default: "false"
jobs:
qemu-build:
permissions:
contents: read
runs-on: ubuntu-24.04
outputs:
qemu-artifact-id: ${{ steps.upload-qemu.outputs.artifact-id }}
qemu-scan-source-artifact-id: ${{ steps.upload-qemu-scan-source.outputs.artifact-id }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- name: Checkout Code
# [email protected] released 2024 October 23. SHA pinned for enhanced security
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
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
with:
go: "false"
trivy: "false"
- name: Cache QEMU source & build directory
id: cache-qemu
# The cache is disabled for release builds which zizmor can't accurately detect
# [email protected] released 2025 March 19. SHA pinned for enhanced security
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # zizmor: ignore[cache-poisoning]
# Always disable cache for tagged runs, runs on the main branch, or when disable_cache is explicitly set to true
if: ${{ ! (github.ref_type == 'tag' || github.ref == 'refs/heads/main' || inputs.disable_cache == 'true') }}
env:
cache-name: cache-qemu
with:
path: workspace/qemu-9.1.0
# Use the hash of the document this workflow is based on to decide whether the build should be re-run or not
# If the workflow was triggered as a result of pushing a tag, always do a clean cache-free build
key: "qemu-${{ github.event_name == 'push' && github.ref_type == 'tag' && github.ref || hashFiles('kubevirt-patch/README.md') }}"
- name: Build and patch QEMU
if: ${{ steps.cache-qemu.outputs.cache-hit != 'true' || inputs.disable_cache == '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/intel/Intel-distribution-of-QEMU.git
cd Intel-distribution-of-QEMU
git checkout 29ed545c07364a99a931b31712ae68fdf74f6992
git format-patch -54
ls -hal
if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/9.1.0-gfx-sriov)" ]; then
echo "::warning file=kubevirt-patch/README.md::The 9.1.0-gfx-sriov branch has new commits which are not included here. Consider updating the README and this workflow."
fi
cd ..
wget -N https://download.qemu.org/qemu-9.1.0.tar.xz
tar -xf qemu-9.1.0.tar.xz
cd qemu-9.1.0
git init
ls -hal
mkdir sriov
cp -r ../Intel-distribution-of-QEMU/00*.patch sriov/
ls -hal 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 <<EOF > 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 --disable-smartcard --disable-libnfs -Ddocs=disabled --disable-docs
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
id: upload-qemu
# [email protected] released 2025 March 19. SHA pinned for enhanced security
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: qemu-artifact
path: |
workspace/qemu-9.1.0/build/qemu-system-x86_64
- name: Upload entire QEMU build directory as a temporary artifact for scanning
id: upload-qemu-scan-source
# [email protected] released 2025 March 19. SHA pinned for enhanced security
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
retention-days: 2 # This only needs to be retained long enough for the scanner to run on it
name: qemu-scan-source
path: |
workspace/qemu-9.1.0
qemu-scan:
needs: qemu-build
permissions:
contents: read
security-events: write
runs-on: ubuntu-24.04
steps:
- name: Checkout Code
# [email protected] released 2024 October 23. SHA pinned for enhanced security
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
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
with:
go: "false"
trivy: "true"
- name: Download QEMU scan source artifact
# [email protected] released 2025 April 24. SHA pinned for enhanced security
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
artifact-ids: ${{ needs.qemu-build.outputs.qemu-scan-source-artifact-id }}
path: . # Will unpack into a folder with the name used in upload-artifact
- name: Restore unpacked artifact to correct directory
shell: bash
run: |
mkdir -p workspace
mv qemu-scan-source workspace/qemu-9.1.0
- name: trivy qemu source scan
shell: bash
run: |
cd workspace/qemu-9.1.0
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
# Disable unneccessary warning for OSS project maintainers
export TRIVY_DISABLE_VEX_NOTICE=true
# Scan QEMU code, ignoring some python packages in components that are not copied to the release package
# Only scan QEMU for vulnerabilities (disable secrets)
trivy fs . \
--format json \
--scanners vuln \
-o trivy_raw_results.json \
--skip-files 'docs/requirements.txt' \
--skip-files 'roms/u-boot/test/py/requirements.txt'
# Implementation note: Using || to set the exit code in this way prevents this action component from exiting early when an expected error happens
TRIVY_STATUS=0
trivy convert \
--format template --template "@trivy-html.tpl" \
-o "trivy_code_scan_qemu.html" \
--exit-code 1 \
trivy_raw_results.json || TRIVY_STATUS=$?
# Generate SARIF output for GitHub Security tab
trivy convert \
--format sarif \
-o "trivy_code_scan_qemu.sarif" \
trivy_raw_results.json
# Summarize results on github for quick access
echo "# Trivy QEMU Scan Results" >> $GITHUB_STEP_SUMMARY
# Only fail this specific build step if the scan itself fails - need it to succeed so that artifacts are uploaded
if [[ $TRIVY_STATUS -eq 0 ]]; then
echo "Trivy scan completed with no vulnerabilities detected"
echo "TRIVY_QEMU_STATUS=No vulnerabilities detected" >> $GITHUB_ENV
echo "Trivy scan completed with no vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
elif [[ $TRIVY_STATUS -eq 1 ]]; then
echo "Trivy scan detected vulnerabilities"
echo "TRIVY_QEMU_STATUS=Trivy detected vulnerable dependencies. See report artifact for details." >> $GITHUB_ENV
echo "$(trivy convert --format table trivy_raw_results.json)" >> $GITHUB_STEP_SUMMARY
else
echo "Trivy scan failed."
echo "Trivy scan failed" >> $GITHUB_STEP_SUMMARY
exit $TRIVY_STATUS
fi
- name: Upload trivy reports
# [email protected] released 2025 March 19. SHA pinned for enhanced security
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: trivy-qemu-results
path: |
workspace/qemu-9.1.0/trivy_code_scan_qemu.html
- name: Upload Trivy scan results to GitHub Security tab
# [email protected] released 2025 June 30. SHA pinned for enhanced security
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b
with:
sarif_file: 'workspace/qemu-9.1.0/trivy_code_scan_qemu.sarif'
- name: ClamAV QEMU Antivirus Scan
shell: bash
run: |
echo "Starting ClamAV scan on workspace/qemu-9.1.0/build/..."
CLAMAV_STATUS=0
docker run --rm \
--mount type=bind,source=./workspace/qemu-9.1.0/build/,target=/scandir \
clamav/clamav:stable \
clamscan --recursive --log=/scandir/clamav-scan-report.log \
/scandir || CLAMAV_STATUS=$?
sudo chown $USER:$USER workspace/qemu-9.1.0/build/clamav-scan-report.log 2>/dev/null || true
if [ $CLAMAV_STATUS -ne 0 ]; then
echo "QEMU ClamAV scan failed or found issues"
echo "CLAMAV_QEMU_STATUS=Issues detected during antivirus scan" >> $GITHUB_ENV
echo "CLAMAV_QEMU_STATE=failure" >> $GITHUB_ENV
else
echo "QEMU ClamAV scan completed successfully with no issues detected"
echo "CLAMAV_QEMU_STATUS=No issues detected during antivirus scan" >> $GITHUB_ENV
echo "CLAMAV_QEMU_STATE=success" >> $GITHUB_ENV
fi
echo "# ClamAV QEMU Scan Results" >> $GITHUB_STEP_SUMMARY
echo "$(cat workspace/qemu-9.1.0/build/clamav-scan-report.log | grep -v 'Empty file$')" >> $GITHUB_STEP_SUMMARY
- name: Upload QEMU Antivirus Report
# [email protected] released 2025 March 19. SHA pinned for enhanced security
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: clamav-qemu-results
path: workspace/qemu-9.1.0/build/clamav-scan-report.log
- name: Evaluate Scan Results
shell: bash
run: |
echo "$TRIVY_QEMU_STATUS"
echo "$CLAMAV_QEMU_STATUS"
if [[ "$CLAMAV_QEMU_STATE" != "success" ]]; then
exit 1
fi
kubevirt-build:
needs: qemu-build
permissions:
contents: read
runs-on: ubuntu-24.04
outputs:
kubevirt-artifact-id: ${{ steps.upload-kubevirt.outputs.artifact-id }}
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
with:
egress-policy: audit
- name: Checkout Code
# [email protected] released 2024 October 23. SHA pinned for enhanced security
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
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
with:
go: "false"
- name: Cache Kubevirt output artifacts
id: cache-kubevirt
# The cache is disabled for release builds which zizmor can't accurately detect
# [email protected] released 2025 March 19. SHA pinned for enhanced security
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # zizmor: ignore[cache-poisoning]
# Always disable cache for tagged runs, runs on the main branch, or when disable_cache is explicitly set to true
if: ${{ ! (github.ref_type == 'tag' || github.ref == 'refs/heads/main' || inputs.disable_cache == 'true') }}
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
# If the workflow was triggered as a result of pushing a tag, always do a clean cache-free build
# 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-${{ github.event_name == 'push' && github.ref_type == 'tag' && github.ref || 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' || inputs.disable_cache == '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
if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' || inputs.disable_cache == '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' || inputs.disable_cache == 'true' }}
# [email protected] released 2025 April 24. SHA pinned for enhanced security
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
artifact-ids: ${{ needs.qemu-build.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
if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' || inputs.disable_cache == 'true' }}
# Each logical block here is copied exactly from a code block in kubevirt-patch/README.md
run: |
mkdir -p $EDV_HOME/workspace
cd $EDV_HOME/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|<SHA256SUM_OF_PATCHED_QEMU>|$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
echo "Partition sizes & free space following build:"
df -h
- name: Export kubevirt build artifacts to output directory
if: ${{ steps.cache-kubevirt.outputs.cache-hit != 'true' || inputs.disable_cache == 'true' }}
shell: bash
run: |
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/kubevirt-patch/kubevirt-cr.yaml .
# Modify the generated operator yaml to specify images by tag, rather than sha256
cat kubevirt-operator.yaml | sed '/name: VIRT_API_SHASUM/,/name: KUBEVIRT_VERSION/ { /name: KUBEVIRT_VERSION/!d }' > kubevirt-operator.new.yaml
perl -p -i -e "s|virt-operator\@sha256.*\$|virt-operator:$EDV_VERSION|g" kubevirt-operator.new.yaml
mv -f kubevirt-operator.new.yaml kubevirt-operator.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
for file in *.tar; do
zstd --no-progress -T0 -16 -f --long=25 "$file" -o "${file}.zst"
done
mkdir intel-idv-kubevirt-$EDV_VERSION
mv *.zst intel-idv-kubevirt-$EDV_VERSION/
cp *.yaml intel-idv-kubevirt-$EDV_VERSION/
ls -hal
tar cvzf intel-idv-kubevirt-$EDV_VERSION.tar.gz intel-idv-kubevirt-$EDV_VERSION
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' && inputs.disable_cache != 'true' }}
shell: bash
run: |
cd $EDV_HOME/workspace/kubevirt-artifacts
# Delete the old previously-cached release folder which will be regenerated by this cache restoration workflow
rm -rf intel-idv-kubevirt-*
# 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
for file in *.tar; do
zstd --no-progress -T0 -16 -f --long=25 "$file" -o "${file}.zst"
done
mkdir intel-idv-kubevirt-$EDV_VERSION
mv *.zst intel-idv-kubevirt-$EDV_VERSION/
cp *.yaml intel-idv-kubevirt-$EDV_VERSION/
tar cvzf intel-idv-kubevirt-$EDV_VERSION.tar.gz intel-idv-kubevirt-$EDV_VERSION
echo "Contents of $(pwd):"
ls -hal
- name: Upload kubevirt artifacts
id: upload-kubevirt
# [email protected] released 2025 March 19. SHA pinned for enhanced security
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: kubevirt-artifacts
path: |
workspace/kubevirt-artifacts/intel-idv-kubevirt-${{ env.EDV_VERSION }}.tar.gz
kubevirt-scan:
needs: kubevirt-build
permissions:
contents: read
security-events: write
runs-on: ubuntu-24.04
steps:
- name: Checkout Code
# [email protected] released 2024 October 23. SHA pinned for enhanced security
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
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
with:
go: "false"
trivy: "true"
- name: Download Kubevirt artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
artifact-ids: ${{ needs.kubevirt-build.outputs.kubevirt-artifact-id }}
path: workspace
- name: Unpack and Load Kubevirt Images
shell: bash
run: |
# Unpack the kubevirt artifacts
cd workspace/kubevirt-artifacts
tar -xvzf "intel-idv-kubevirt-${EDV_VERSION}.tar.gz"
cd "intel-idv-kubevirt-${EDV_VERSION}"
# Uncompress the zst files and load them into Docker
for file in *.zst; do
uncompressed_file="${file%.zst}"
zstd -d "$file" -o "$uncompressed_file"
docker load -i "$uncompressed_file"
done
- name: Trivy Image Scan
shell: bash
run: |
mkdir -p workspace/kubevirt-trivy
cd workspace/kubevirt-trivy
# Disable unneccessary warning for OSS project maintainers
export TRIVY_DISABLE_VEX_NOTICE=true
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -o trivy-html.tpl
# Define a function to handle scanning, converting, and setting environment variables
scan_and_process_image() {
IMAGE_NAME="$1"
DOCKER_IMAGE="$2"
echo "Scanning $DOCKER_IMAGE..."
trivy image "$DOCKER_IMAGE" --format json -o "${IMAGE_NAME}_raw_results.json"
# Convert raw results to full HTML report
TRIVY_STATUS=0
trivy convert --format template --template "@trivy-html.tpl" \
-o "${IMAGE_NAME}.html" \
--exit-code 1 \
"${IMAGE_NAME}_raw_results.json" || TRIVY_STATUS=$?
# Generate SARIF output for GitHub Security tab
trivy convert \
--format sarif \
-o "${IMAGE_NAME}.sarif" \
"${IMAGE_NAME}_raw_results.json"
# Generate SPDX JSON file
trivy image --quiet --format spdx-json --output "${IMAGE_NAME}.spdx.json" "$DOCKER_IMAGE"
# Summarize results on GitHub for quick access
echo "# Trivy $IMAGE_NAME Scan Results" >> $GITHUB_STEP_SUMMARY
# Set environment variables based on scan results
if [[ $TRIVY_STATUS -eq 0 ]]; then
echo "Trivy scan for $DOCKER_IMAGE completed with no vulnerabilities detected"
echo "Trivy scan for $DOCKER_IMAGE completed with no vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
elif [[ $TRIVY_STATUS -eq 1 ]]; then
echo "Trivy scan for $DOCKER_IMAGE detected vulnerabilities"
echo "$(trivy convert --format table "${IMAGE_NAME}_raw_results.json")" >> $GITHUB_STEP_SUMMARY
else
echo "Trivy scan for $DOCKER_IMAGE failed."
echo "Trivy scan failed" >> $GITHUB_STEP_SUMMARY
exit $TRIVY_STATUS
fi
}
# Call the function for each image
scan_and_process_image "sidecar-shim" "localhost:5000/sidecar-shim:$EDV_VERSION"
scan_and_process_image "virt-api" "localhost:5000/virt-api:$EDV_VERSION"
scan_and_process_image "virt-controller" "localhost:5000/virt-controller:$EDV_VERSION"
scan_and_process_image "virt-handler" "localhost:5000/virt-handler:$EDV_VERSION"
scan_and_process_image "virt-launcher" "localhost:5000/virt-launcher:$EDV_VERSION"
scan_and_process_image "virt-operator" "localhost:5000/virt-operator:$EDV_VERSION"
- name: Upload Trivy Image Report
# [email protected] released 2025 March 19. SHA pinned for enhanced security
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: Trivy kubevirt image scan
path: |
workspace/kubevirt-trivy/sidecar-shim.html
workspace/kubevirt-trivy/virt-api.html
workspace/kubevirt-trivy/virt-controller.html
workspace/kubevirt-trivy/virt-handler.html
workspace/kubevirt-trivy/virt-launcher.html
workspace/kubevirt-trivy/virt-operator.html
workspace/kubevirt-trivy/sidecar-shim.spdx.json
workspace/kubevirt-trivy/virt-api.spdx.json
workspace/kubevirt-trivy/virt-controller.spdx.json
workspace/kubevirt-trivy/virt-handler.spdx.json
workspace/kubevirt-trivy/virt-launcher.spdx.json
workspace/kubevirt-trivy/virt-operator.spdx.json
# Unfortunately, upload-sarif deprecated a feature that lets you upload all of these files together.
# Now they need to be done one-by-one with an explicitly different category
- name: Upload Trivy SARIF Results to GitHub Security Tab - sidecar-shim
# [email protected] released 2025 June 30. SHA pinned for enhanced security
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b
with:
sarif_file: workspace/kubevirt-trivy/sidecar-shim.sarif
category: kubevirt-sidecar-shim
- name: Upload Trivy SARIF Results to GitHub Security Tab - virt-api
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b
with:
sarif_file: workspace/kubevirt-trivy/virt-api.sarif
category: kubevirt-virt-api
- name: Upload Trivy SARIF Results to GitHub Security Tab - virt-controller
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b
with:
sarif_file: workspace/kubevirt-trivy/virt-controller.sarif
category: kubevirt-virt-controller
- name: Upload Trivy SARIF Results to GitHub Security Tab - virt-handler
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b
with:
sarif_file: workspace/kubevirt-trivy/virt-handler.sarif
category: kubevirt-virt-handler
- name: Upload Trivy SARIF Results to GitHub Security Tab - virt-launcher
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b
with:
sarif_file: workspace/kubevirt-trivy/virt-launcher.sarif
category: kubevirt-virt-launcher
- name: Upload Trivy SARIF Results to GitHub Security Tab - virt-operator
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b
with:
sarif_file: workspace/kubevirt-trivy/virt-operator.sarif
category: kubevirt-virt-operator