Phase 1 toolchain: pinned dev container (prereqs not all Python)

Per operator rule: OpenTofu/age/sops/flux are Go binaries, so bake the toolchain
into a pinned Fedora-44 dev container (matches host libvirt 12) instead of a venv.
infra/devcontainer/: Containerfile + versions.env (tofu 1.9.0, age 1.2.1, sops
3.9.4, flux 2.4.0, kubectl 1.32.0, helm 3.16.0) + dev.sh (runs with host libvirt
socket + repo + ssh mounted) + README. Built & validated: all tools resolve;
virsh reaches host libvirt from inside the container.

Also record resolved Phase 1 decisions in PHASE1-SCOPE.md (6GiB/4vCPU x3;
k3s-dev NAT 10.73.0.0/24; container toolchain). Gate green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-16 00:59:47 -05:00
1 parent 814029f2da
commit 5d2b248b68
5 files changed
+162 -10

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
# Dev toolbox (containerized baseline)
The Phase 1 prerequisites are **not all Python** (OpenTofu, `age`, `sops`, `flux` are Go binaries;
only Ansible is Python). Per the operator's rule, the toolchain is therefore a **pinned dev
container** baked with everything needed to drive the local KVM cluster — no host pollution, one
reproducible baseline.
## What's inside (pinned in `versions.env`)
OpenTofu, `age` + `age-keygen`, `sops`, `flux`, `kubectl`, `helm`, `ansible-core`, `libvirt-client`
(so the tofu `dmacvicar/libvirt` provider can talk to the host libvirt), `qemu-img`, cloud-init seed
tooling (`cloud-utils`/`genisoimage`), `openssh-clients`, and common utilities.
## Use
```bash
cd infra/devcontainer
./dev.sh build # build the image (needs network: base image + pinned binaries)
./dev.sh # build if needed + open a shell in /work (the repo)
./dev.sh run tofu -version
```
`ENGINE=docker ./dev.sh` to use docker instead of rootless podman.
## How it reaches the host KVM
`dev.sh` runs the container with:
- `--network host` — so Ansible can SSH to the cluster VMs on the `k3s-dev` NAT subnet
(10.73.0.0/24) and `kubectl`/`flux` can reach the API server.
- `-v /run/libvirt:/run/libvirt` + `LIBVIRT_DEFAULT_URI=qemu:///system` — so OpenTofu/virsh drive
the host libvirt daemon (the socket is world-writable; no group change needed).
- `--security-opt label=disable` — lets the container use the host libvirt socket without
relabeling it (SELinux hosts).
- `-v $REPO:/work` and `-v ~/.ssh:/root/.ssh:ro` — the repo and your SSH keys.
## Notes
- Versions are **best-effort pins**; if a download 404s at build, bump the value in `versions.env`
(one line) to the current stable and rebuild. The image records the resolved set at
`/etc/dev-toolchain-versions`.
- Secrets never enter the image. The SOPS **age private key** is generated at bootstrap and kept
out of git (`.gitignore` guards `age.key`).
- This container is the toolchain, not the cluster. It provisions the 3 KVM nodes (T-1.1–T-1.4);
the cluster itself runs on libvirt on the host.