You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: exporter-as-main QEMU pods with ExitAndReplace recycle e2e (#929)
## Summary
Make QEMU ExporterSet pods follow an exporter-as-main /
runtime-as-sidecar model so Pod lifecycle, logs, and ExitAndReplace
recycling behave correctly, and cover that path in the main e2e suite.
### Pod layout (`qemu.jumpstarter.dev`)
- **exporter** is the main container (`jmp run`, UID 65532) — default
`kubectl logs`, and exporter exit completes the Pod (`restartPolicy:
Never`).
- **target-runtime** is a native sidecar (`restartPolicy: Always`, runs
as root) — starts first so `launcher.sock` is ready; runs QEMU via
`jumpstarter-exec`.
- **copy-jumpstarter-exec** init container stages the binary from the
**exporter** image onto `/shared` (not baked into each runtime image).
- Shared `emptyDir` holds Unix sockets (QMP, serial, launcher), disk,
and cloud-init cidata (world-traversable so the runtime can mount vvfat
across the UID boundary).
- Runtime creates sockets with permissive mode so the non-root exporter
can connect.
- Normalize Kubernetes quantity suffixes (`10Gi` → `10G`) for QEMU
driver config.
### Lifecycle / recycle
- Add `jumpstarter-exec shutdown` and best-effort runtime teardown from
the exporter on `exitOnLeaseEnd`.
- ExitAndReplace: delete unleased exporters whose Pods are
`Succeeded`/`Failed`, then refill `minAvailableReplicas` (avoids
Completed/Offline zombies and `maxReplicas` stalls).
### E2E / CI
- Fold ExporterSet QEMU coverage into the main `e2e-tests` job; add
`make e2e-exporterset-qemu` for focused local runs.
- Build/load exporter + qemu-runtime images in CI; prefetch Alpine guest
image during `e2e-setup` (CI and local).
- Specs: Online/Ready Pod; power cycle + ExitAndReplace recycle stays
responsive.
- Flash/boot remains skipped while shared emptyDir SizeLimit is `100Mi`
(needs #924).
- Share OIDC/legacy client–exporter helpers in `e2e/test/utils.go`;
cover `shutdown_runtime_sidecar` paths for diff-cover.
- Update JEP-0014 to match the exporter-main / runtime-sidecar model.
## Test plan
- [x] `go test ./internal/exporterset/...` (ExitAndReplace cleanup +
RenderPod layout)
- [x] `make e2e-exporterset-qemu` — Online/Ready + power cycle/recycle;
flash/boot skipped on 100Mi SizeLimit
- [x] `make -C python pkg-test-jumpstarter` — includes
`shutdown_runtime_sidecar` coverage
- [x] CI `e2e-tests` on this PR
- [x] Manual: apply `controller/hack/sample-x86_64-kind.yaml`,
lease/release, confirm Completed Pod is deleted and a new Ready instance
appears
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
0 commit comments