@@ -17,10 +17,16 @@ jobs:
1717 go-version-file : go.mod
1818 cache : true
1919 - name : Run controller-runtime envtest
20- run : make test
20+ run : make test-report
21+ - name : Upload test reports
22+ if : always()
23+ uses : actions/upload-artifact@v4
24+ with :
25+ name : envtest-reports
26+ path : reports/
2127
2228 kind-e2e :
23- name : kind e2e
29+ name : kind topology e2e
2430 runs-on : ubuntu-latest
2531 steps :
2632 - uses : actions/checkout@v4
@@ -31,55 +37,76 @@ jobs:
3137 - uses : helm/kind-action@v1
3238 with :
3339 cluster_name : kind
34- - name : Run one deployment e2e test
40+ - name : Run deployed-topology e2e test
3541 env :
3642 RUN_E2E : " true"
3743 KIND_CLUSTER : kind
38- run : make test-e2e
44+ run : make test-e2e-report
45+ - name : Upload e2e reports
46+ if : always()
47+ uses : actions/upload-artifact@v4
48+ with :
49+ name : e2e-reports
50+ path : reports/
3951
40- smolvm-runtime-smoke :
41- name : smolvm runtime smoke
52+ smolvm-runtime-e2e :
53+ name : smolvm runtime lifecycle e2e
4254 runs-on : ubuntu-latest
43- timeout-minutes : 20
55+ timeout-minutes : 45
4456 steps :
4557 - uses : actions/checkout@v4
4658 - uses : actions/setup-go@v5
4759 with :
4860 go-version-file : go.mod
4961 cache : true
62+ - name : Prepare KVM-backed kind mounts
63+ run : |
64+ set -euxo pipefail
65+ test -e /dev/kvm
66+ sudo chmod 666 /dev/kvm
67+ sudo mkdir -p /tmp/smolvm-kind-var-lib /tmp/smolvm-kind-var-run
68+ sudo chmod 777 /tmp/smolvm-kind-var-lib /tmp/smolvm-kind-var-run
5069 - uses : helm/kind-action@v1
5170 with :
5271 cluster_name : runtime
53- - name : Install smolvm
72+ config : .github/kind-runtime-config.yaml
73+ - name : Build and load operator images
5474 run : |
55- sudo apt-get update
56- sudo apt-get install -y libvirglrenderer1 libepoxy0 libgbm1
57- curl -fsSL -o /tmp/smolvm.tar.gz https://github.com/smol-machines/smolvm/releases/download/v0.8.1/smolvm-0.8.1-linux-x86_64.tar.gz
58- mkdir -p /tmp/smolvm
59- tar -xzf /tmp/smolvm.tar.gz -C /tmp/smolvm --strip-components=1
60- echo /tmp/smolvm >> "$GITHUB_PATH"
61- /tmp/smolvm/smolvm --version
62- - name : Run operator against real smolvm runtime
75+ set -euxo pipefail
76+ make docker-build IMG=example.com/smolvm-operator:e2e
77+ make docker-build-runtime RUNTIME_IMG=example.com/smolvm-runtime:e2e
78+ kind load docker-image example.com/smolvm-operator:e2e --name runtime
79+ kind load docker-image example.com/smolvm-runtime:e2e --name runtime
80+ - name : Deploy full stack and run VM lifecycle
6381 run : |
6482 set -euxo pipefail
65- sudo chmod 666 /dev/kvm
66- export LD_LIBRARY_PATH="/tmp/smolvm/lib:${LD_LIBRARY_PATH:-}"
67- export LD_PRELOAD="$(find /usr/lib -name 'libvirglrenderer.so.1' | head -1)"
68- smolvm serve start --listen 127.0.0.1:8080 > smolvm-serve.log 2>&1 &
69- serve_pid=$!
70- trap 'kubectl delete smolvm runtime-smoke --ignore-not-found=true --wait=false || true; kill $serve_pid || true; cat smolvm-serve.log || true' EXIT
83+ make install
84+ make deploy IMG=example.com/smolvm-operator:e2e RUNTIME_IMG=example.com/smolvm-runtime:e2e
7185
72- for i in {1..60}; do
73- curl -fsS http://127.0.0.1:8080/api/v1/machines && break
74- sleep 1
75- done
86+ cleanup() {
87+ kubectl delete smolvm runtime-smoke --ignore-not-found=true --wait=false || true
88+ kubectl -n operator-system get pods -o wide || true
89+ kubectl -n operator-system logs deployment/operator-controller-manager --all-containers=true || true
90+ kubectl -n operator-system logs daemonset/operator-smolvm-runtime --all-containers=true || true
91+ }
92+ trap cleanup EXIT
7693
77- make install
78- SMOLVM_API_URL=http://127.0.0.1:8080 go run ./cmd/main.go \
79- --metrics-bind-address=0 \
80- --health-probe-bind-address=:8081 > manager.log 2>&1 &
81- manager_pid=$!
82- trap 'kubectl delete smolvm runtime-smoke --ignore-not-found=true --wait=false || true; kill $manager_pid || true; kill $serve_pid || true; cat manager.log || true; cat smolvm-serve.log || true' EXIT
94+ kubectl rollout status deployment/operator-controller-manager -n operator-system --timeout=3m
95+ kubectl rollout status daemonset/operator-smolvm-runtime -n operator-system --timeout=5m
96+
97+ node=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
98+ for i in {1..90}; do
99+ kubectl get smolvmnode "$node" -o yaml || true
100+ ready=$(kubectl get smolvmnode "$node" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || true)
101+ runtime_ready=$(kubectl get smolvmnode "$node" -o jsonpath='{.status.conditions[?(@.type=="RuntimeReady")].status}' 2>/dev/null || true)
102+ if [ "$ready" = "True" ] && [ "$runtime_ready" = "True" ]; then
103+ break
104+ fi
105+ sleep 2
106+ done
107+ test "$(kubectl get smolvmnode "$node" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}')" = "True"
108+ test "$(kubectl get smolvmnode "$node" -o jsonpath='{.status.conditions[?(@.type=="RuntimeReady")].status}')" = "True"
109+ test "$(kubectl get smolvmnode "$node" -o jsonpath='{.status.endpoint.podNamespace}')" = "operator-system"
83110
84111 cat <<'EOF' | kubectl apply -f -
85112 apiVersion: vm.smolvm.dev/v1alpha1
@@ -94,40 +121,36 @@ jobs:
94121 memoryMiB: 128
95122 EOF
96123
97- ready=false
98- for i in {1..48}; do
99- echo "--- poll $i ---"
124+ for i in {1..60}; do
100125 kubectl get smolvm runtime-smoke -o yaml || true
101- curl -fsS http://127.0.0.1:8080/api/v1/machines || true
102126 status=$(kubectl get smolvm runtime-smoke -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || true)
103127 if [ "$status" = "True" ]; then
104- ready=true
105128 break
106129 fi
107130 sleep 10
108131 done
109- if [ "$ready" != "true" ]; then
110- echo "runtime-smoke did not become Ready"
111- kubectl get smolvm runtime-smoke -o yaml || true
112- curl -fsS http://127.0.0.1:8080/api/v1/machines || true
113- exit 1
114- fi
132+ test "$(kubectl get smolvm runtime-smoke -o jsonpath='{.status.conditions[?(@.type=="Scheduled")].reason}')" = "Bound"
115133 test "$(kubectl get smolvm runtime-smoke -o jsonpath='{.status.conditions[?(@.type=="RuntimeReady")].status}')" = "True"
116- test "$(kubectl get smolvm runtime-smoke -o jsonpath='{.status.conditions[?(@.type=="GuestReady")].status }')" = "Unknown "
134+ test "$(kubectl get smolvm runtime-smoke -o jsonpath='{.status.phase }')" = "Running "
117135
118136 kubectl patch smolvm runtime-smoke --type=merge -p '{"spec":{"running":false}}'
119- kubectl wait smolvm runtime-smoke \
120- --for=jsonpath='{.status.phase}'=Stopped \
121- --timeout=5m
137+ kubectl wait smolvm runtime-smoke --for=jsonpath='{.status.phase}'=Stopped --timeout=5m
122138
123139 machine=$(kubectl get smolvm runtime-smoke -o jsonpath='{.status.machineName}')
140+ runtime_pod=$(kubectl -n operator-system get pod -l app.kubernetes.io/name=smolvm-runtime -o jsonpath='{.items[0].metadata.name}')
124141 kubectl delete smolvm runtime-smoke --wait=true --timeout=5m
125142 for i in {1..30}; do
126- if ! curl -fsS http://127.0.0.1:8080/api/v1/machines | grep -q "$machine"; then
143+ if ! kubectl -n operator-system exec "$runtime_pod" -- smolvm machine ls | grep -q "$machine"; then
127144 exit 0
128145 fi
129146 sleep 2
130147 done
131148 echo "runtime machine $machine still exists after CR deletion"
132- curl -fsS http://127.0.0.1:8080/api/v1/machines || true
149+ kubectl -n operator-system exec "$runtime_pod" -- smolvm machine ls || true
133150 exit 1
151+ - name : Upload runtime logs
152+ if : always()
153+ uses : actions/upload-artifact@v4
154+ with :
155+ name : runtime-e2e-logs
156+ path : reports/
0 commit comments