Skip to content

Initial github actions for automated build & security scans #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/actions/setup-tools/action.yaml
Original file line number Diff line number Diff line change
@@ -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
104 changes: 104 additions & 0 deletions .github/workflows/device_plugin.yaml
Original file line number Diff line number Diff line change
@@ -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
103 changes: 103 additions & 0 deletions .github/workflows/device_plugin_coverity.yaml
Original file line number Diff line number Diff line change
@@ -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
146 changes: 146 additions & 0 deletions .github/workflows/qemu.yaml
Original file line number Diff line number Diff line change
@@ -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 <<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
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
8 changes: 4 additions & 4 deletions device-plugins-for-kubernetes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading
Loading