Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
150 changes: 150 additions & 0 deletions .github/workflows/kubevirt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
name: KubeVirt

on:
pull_request:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
kubevirt:
name: KubeVirt
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Enable KVM access
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
| sudo tee /etc/udev/rules.d/99-kvm.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- name: Build KubeVirt image
run: |
set -euxo pipefail

builddir=$(mktemp -d)
echo "BUILDDIR=${builddir}" >> "$GITHUB_ENV"

cosa() {
env | sort > /tmp/cosa-env
podman run --rm \
--security-opt=label=disable --privileged \
--uidmap=1000:0:1 --uidmap=0:1:1000 --uidmap=1001:1001:64536 \
-v="${builddir}:/srv/" --device=/dev/kvm --device=/dev/fuse \
--tmpfs=/tmp -v=/var/tmp:/var/tmp \
--env-file=/tmp/cosa-env \
${COREOS_ASSEMBLER_CONTAINER} "$@"
rc=$?; return $rc
}

export COREOS_ASSEMBLER_CONTAINER="${COREOS_ASSEMBLER_CONTAINER:-quay.io/coreos-assembler/coreos-assembler:latest}"

cosa init https://github.com/coreos/fedora-coreos-config
cosa fetch
cosa build
cosa buildextend-kubevirt

- name: Create Kind cluster
run: |
cat <<EOF | kind create cluster --wait 120s --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraMounts:
- hostPath: /dev/kvm
containerPath: /dev/kvm
EOF

- name: Install KubeVirt
run: |
set -euxo pipefail

KUBEVIRT_VERSION=v1.8.0
KUBEVIRT_RELEASE_URL="https://github.com/kubevirt/kubevirt/releases/download/${KUBEVIRT_VERSION}"

# Bump inotify limits on Kind nodes
for node in $(kubectl get node --no-headers -o custom-columns=":metadata.name"); do
docker exec -t "${node}" bash -c "echo 'fs.inotify.max_user_watches=1048576' >> /etc/sysctl.conf"
docker exec -t "${node}" bash -c "echo 'fs.inotify.max_user_instances=512' >> /etc/sysctl.conf"
docker exec -i "${node}" bash -c "sysctl -p /etc/sysctl.conf"
done

# Deploy KubeVirt operator and CR
kubectl apply -f "${KUBEVIRT_RELEASE_URL}/kubevirt-operator.yaml"
kubectl apply -f "${KUBEVIRT_RELEASE_URL}/kubevirt-cr.yaml"

# Wait for KubeVirt to be ready
if ! kubectl wait -n kubevirt kv kubevirt --for=condition=Available --timeout=15m; then
kubectl get pod -n kubevirt || true
kubectl describe pod -n kubevirt || true
for p in $(kubectl get pod -n kubevirt -o name | sed "s#pod/##"); do
kubectl logs -p --all-containers=true -n kubevirt "$p" || true
kubectl logs --all-containers=true -n kubevirt "$p" || true
done
exit 1
fi

- name: Load image into Kind
run: |
set -euxo pipefail
ociarchive=$(find "${BUILDDIR}/builds/" -name '*-kubevirt.*.ociarchive' | head -1)
skopeo copy "oci-archive:${ociarchive}" "docker-archive:/tmp/fcos-kubevirt.tar:localhost/fcos-kubevirt:latest"
kind load image-archive /tmp/fcos-kubevirt.tar

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Build kola
run: go build -o bin/kola ./mantle/cmd/kola

- name: Verify KubeVirt readiness
run: |
set -euxo pipefail
# Check KVM device is available in Kind node
docker exec kind-control-plane ls -la /dev/kvm
# Check KubeVirt device plugin allocated kvm
kubectl get node -o jsonpath='{.items[0].status.allocatable}' | jq .
# Check virt components are running
kubectl get pods -n kubevirt

- name: Run kola tests
run: |
set -euxo pipefail
./bin/kola run -p kubevirt \
--kubevirt-image localhost/fcos-kubevirt:latest \
--output-dir "${BUILDDIR}/tmp/kola" \
-v \
'fcos.metadata.kubevirt.configdrive'

- name: Debug on failure
if: failure()
run: |
set +e
echo "=== VMs ==="
kubectl get vm,vmi -A
echo "=== VM details ==="
kubectl describe vmi -A
echo "=== Pods ==="
kubectl get pods -A
echo "=== virt-launcher logs ==="
for p in $(kubectl get pod -l kubevirt.io=virt-launcher -o name 2>/dev/null); do
echo "--- $p ---"
kubectl logs "$p" --all-containers=true 2>/dev/null | tail -50
done

- name: Upload KubeVirt artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: fcos-kubevirt-image
path: builds/latest/**/fedora-coreos-*-kubevirt.*.ociarchive
if-no-files-found: warn
31 changes: 30 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ require (
github.com/google/uuid v1.6.0
github.com/gophercloud/gophercloud v1.14.1
github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/kylelemons/godebug v1.1.0
github.com/pborman/uuid v1.2.1
Expand All @@ -56,6 +57,11 @@ require (
google.golang.org/api v0.274.0
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.35.3
k8s.io/apimachinery v0.35.3
k8s.io/client-go v0.35.3
kubevirt.io/api v1.8.0
sigs.k8s.io/controller-runtime v0.23.3
)

require (
Expand Down Expand Up @@ -85,18 +91,25 @@ require (
github.com/coreos/go-json v0.0.0-20231102161613-e49c8866685a // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/digitalocean/go-libvirt v0.0.0-20250317183548-13bf9b43b50b // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.11 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/errors v0.22.4 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/strfmt v0.25.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.28.0 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect
Expand All @@ -106,18 +119,23 @@ require (
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/openshift/custom-resource-status v1.1.2 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
go.mongodb.org/mongo-driver v1.17.6 // indirect
Expand All @@ -127,14 +145,25 @@ require (
go.opentelemetry.io/otel/metric v1.42.0 // indirect
go.opentelemetry.io/otel/trace v1.42.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/net v0.52.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/text v0.35.0 // indirect
golang.org/x/time v0.15.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect
google.golang.org/grpc v1.79.3 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
k8s.io/apiextensions-apiserver v0.35.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
kubevirt.io/containerized-data-importer-api v1.64.0 // indirect
kubevirt.io/controller-lifecycle-operator-sdk/api v0.2.4 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)

Expand Down
Loading
Loading