Workflow (by @Dhanya122 via pull_request) #47
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
# SPDX-FileCopyrightText: (C) 2025 Intel Corporation | |
# SPDX-License-Identifier: Apache-2.0 | |
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 | |
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 | |
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 & Common Variables | |
uses: ./.github/actions/setup-tools | |
with: | |
go: "false" | |
- 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 | |
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: | | |
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 <<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 | |
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 | |
uses: actions/upload-artifact@v4 | |
with: | |
name: qemu-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 | |
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 | |
uses: actions/upload-artifact@v4 | |
with: | |
name: antivirus-qemu | |
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 | |
with: | |
go: "false" | |
- 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 | |
# 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 | |
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 | |
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 $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' }} | |
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/workspace/kubevirt/_out/manifests/release/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 | |
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 | |
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 | |
uses: actions/upload-artifact@v4 | |
with: | |
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 |