How redhat-openshift-partner-labs/virtwork works
1. What this repo is
- virtwork is a Go CLI and containerized operator-like tool that creates OpenShift Virtualization VMs, injects workload configuration, and exits.
- It is not a long-running controller; VM workload lifecycle is expected to continue inside each guest via systemd-managed services.
2. Top-level execution paths
- The main user flows are run and cleanup.
- run provisions namespaces/resources/VMs for selected workloads, optionally waits for readiness, and records an audit trail.
- cleanup finds managed resources by label and removes them, optionally scoped to a specific run ID.
3. CLI and orchestration boundary
- cmd/virtwork/main.go is the orchestration entry point, likely wiring Cobra commands, config loading, and high-level action sequencing.
- This layer depends on lower-level packages for cluster access, VM/resource creation, workload definitions, waiting, cleanup, and audit logging.
4. Configuration and runtime inputs
- internal/config merges the precedence chain described in the README: CLI flags, VIRTWORK_* environment variables, YAML config file, then defaults.
- Runtime behavior is also influenced by pod-level env vars in deploy/deployment.yaml and entrypoint.sh via VIRTWORK_COMMAND and VIRTWORK_ARGS.
- The tool supports both local kubeconfig execution and in-cluster execution.
5. Cluster access and Kubernetes abstraction layer
- internal/cluster initializes the Kubernetes/OpenShift client, likely using controller-runtime.
- internal/resources, internal/vm, and internal/wait form the main Kubernetes abstraction layer:
- resources: namespace, service, secret creation
- vm: VM/VMI spec construction and CRUD
- wait: readiness polling and synchronization
6. Workload modeling layer
- internal/workloads contains the workload registry plus five implementations: CPU, memory, database, network, and disk.
- Each workload encapsulates its own VM count, sizing, and guest-side bootstrap data, allowing the orchestration layer to treat workloads uniformly.
- The network workload is structurally different from the others because it creates paired server/client VMs rather than simple N-instance fleets.
7. Guest bootstrap and VM payload
- internal/cloudinit builds cloud-init/user-data used to configure VMs at boot.
- This is where SSH access, startup configuration, and workload installation/launch details are injected into the guest.
- The guest-side workload execution itself is outside the Go process; the repo only provisions the bootstrapping inputs.
8. Workload-to-infrastructure data flow
- The orchestration layer selects enabled workloads, expands them into VM/resource requests, and labels every created object with managed-by and run-id metadata.
- Those requests flow into resources and vm, which create the Kubernetes/OpenShift Virtualization objects.
- wait then watches for VMI readiness before the command returns, unless --no-wait is set.
9. Cleanup and lifecycle management
- internal/cleanup is intentionally label-driven and error-tolerant.
- It discovers resources created by virtwork using labels rather than storing a separate inventory, which makes cleanup resilient even if a deployment was interrupted or the process crashed mid-run.
- The optional --delete-namespace flag extends teardown beyond the managed objects themselves.
10. Audit subsystem
- internal/audit provides local SQLite-backed execution tracking.
- It records run metadata, workload/VM/resource details, and event timelines, keyed by a generated UUID run-id.
- Audit is a local operational concern, not a remote service; the README notes no SSH credentials are persisted, only whether SSH was configured.
11. Infrastructure and deployment packaging
- deploy/ contains the OpenShift deployment packaging: namespace, RBAC, service account, ConfigMap, Secret, PVC, and Deployment.
- The container image is built with a multi-stage Dockerfile: a Debian/Golang build stage for CGO/SQLite and a UBI-minimal runtime stage.
- This packaging implies the binary can run either as a local CLI or as an in-cluster job-like pod.
12. Testing and validation boundaries
- The repo separates unit tests, integration tests, and E2E tests.
- tests/e2e exercises the full cluster lifecycle, while internal/*_integration_test.go validates Kubernetes-facing behavior against a real cluster.
- internal/testutil and the per-package suite files suggest Ginkgo-style structured testing across layers.
13. Architectural shape to draw
- A useful diagram should show a strict downward dependency chain: CLI/orchestration at the top, workload definitions in the middle, Kubernetes abstractions below that, then configuration/cluster/cloud-init support, with constants as shared definitions.
- The external boundary is an OpenShift cluster with OpenShift Virtualization/KubeVirt, plus the local SQLite audit database and the optional container runtime environment around the CLI.
Main entry points: main.go virtwork · registry.go Registry · cloudinit.go Cloud-init · cluster.go Cluster
Components 22
Control flow
CLI entrypoint, configuration, orchestration, cleanup, and audit tracking.
- virtwork · Main command wiring and top-level run/cleanup sequencing.
cmd/virtwork/main.go - Config · Merges flags, env, config file, and defaults.
internal/config/config.go - Audit · SQLite-backed run metadata and event timeline storage.
internal/audit/audit.go - Cleanup · Discovers and deletes managed resources by labels and run ID.
internal/cleanup/cleanup.go
Workloads
Workload registry and per-workload sizing/bootstrap definitions.
- Registry · Selects enabled workload implementations and expands them into actions.
internal/workloads/registry.go - CPU · CPU stress workload sizing and payload definition.
internal/workloads/cpu.go - Memory · Memory pressure workload sizing and payload definition.
internal/workloads/memory.go - Database · Database workload sizing and guest bootstrap definition.
internal/workloads/database.go - Network · Server/client workload that provisions paired VMs.
internal/workloads/network.go - Disk · Disk I/O workload sizing and guest bootstrap definition.
internal/workloads/disk.go - Cloud-init · Builds user-data and startup configuration injected into VMs.
internal/cloudinit/cloudinit.go - Constants · Common labels, names, and fixed values shared across packages.
internal/constants/constants.go
Cluster ops
Kubernetes/OpenShift access, resource creation, VM management, and readiness waits.
- Cluster · Initializes Kubernetes/OpenShift client access.
internal/cluster/cluster.go - Resources · Creates namespaces, services, secrets, and related managed objects.
internal/resources/resources.go - VM · Constructs and manages VM/VMI specs and lifecycle operations.
internal/vm/vm.go - Wait · Polls and synchronizes on VM/VMI readiness.
internal/wait/wait.go
Packaging
Container and deployment assets that shape runtime behavior.
- Deploy · Deployment manifests that define in-cluster execution and env wiring.
deploy/deployment.yaml - Entrypoint · Container startup script that passes command and args into the binary.
entrypoint.sh - Image build · Multi-stage image build for the CLI and runtime container.
Dockerfile
External boundaries
Cluster, guest VMs, and local audit storage outside the Go codebase.
- OpenShift cluster · Target cluster providing Kubernetes and OpenShift Virtualization APIs.
- Guest VM · Provisioned virtual machine where workload services run after boot.
- SQLite DB · Local on-disk audit database used for execution tracking.
Connections 35
- virtwork → Config: loads · CLI startup resolves configuration precedence and runtime mode.
- virtwork → Registry: selects · Top-level commands choose which workloads to run.
- virtwork → Cluster: connects · Commands initialize cluster access before resource operations.
- virtwork → Resources: creates · Run flow provisions namespaces and supporting objects.
- virtwork → VM: provisions · Run flow creates and manages VMs for selected workloads.
- virtwork → Wait: waits · Optional readiness synchronization before exit.
- virtwork → Cleanup: tears down · Cleanup command removes managed resources by label.
- virtwork → Audit: records · Execution metadata and event timeline are persisted locally.
- Registry → CPU: registers · Registry includes CPU workload implementation.
- Registry → Memory: registers · Registry includes memory workload implementation.
- Registry → Database: registers · Registry includes database workload implementation.
- Registry → Network: registers · Registry includes network workload implementation.
- Registry → Disk: registers · Registry includes disk workload implementation.
- CPU → Cloud-init: boots · Workload definitions feed guest bootstrap payloads.
- Memory → Cloud-init: boots · Workload definitions feed guest bootstrap payloads.
- Database → Cloud-init: boots · Workload definitions feed guest bootstrap payloads.
- Network → Cloud-init: boots · Paired network workload injects server/client bootstrap data.
- Disk → Cloud-init: boots · Workload definitions feed guest bootstrap payloads.
- CPU → Constants: uses · Workload sizing and labels reuse shared constants.
- Memory → Constants: uses · Workload sizing and labels reuse shared constants.
- Database → Constants: uses · Workload sizing and labels reuse shared constants.
- Network → Constants: uses · Workload sizing and labels reuse shared constants.
- Disk → Constants: uses · Workload sizing and labels reuse shared constants.
- Cloud-init → Guest VM: injects · Cloud-init content is consumed by guest VMs at boot.
- Resources → Cluster: applies · Resource creation uses cluster client access.
- VM → Cluster: applies · VM CRUD operations target the cluster APIs.
- Wait → Cluster: observes · Readiness polling watches cluster resources.
- Cleanup → Cluster: deletes · Cleanup removes managed resources from the cluster.
- Cleanup → Constants: filters · Cleanup uses shared labels and run metadata conventions.
- Audit → SQLite DB: writes · Audit records are stored in local SQLite.
- Deploy → Entrypoint: starts · Pod spec launches the container through the entrypoint script.
- Entrypoint → virtwork: invokes · Container environment forwards command and arguments to the binary.
- Deploy → Config: sets env · Deployment manifest provides runtime environment variables.
- Image build → Deploy: packages · Image build and deployment manifest define in-cluster execution.
- Cluster → OpenShift cluster: targets · Client initialization connects to the external cluster boundary.