Files
home-network-k3s-impl/infra/cluster.sh
jakman85andClaude Opus 5 12c40d8c9c docs: reconcile the documentation with the deployed reality
The docs had drifted badly behind ~85 commits of delivery. The root README still
said "Phase 0 — Foundations. No cluster exists yet"; the infra docs still
described a libvirt/KVM cluster that has been retired for two days; and
DECISIONS-LOG.md — the PM's authoritative record — stopped at 2026-08-25 AM.
Anyone following these docs would have been working from a false map.

Verified against the live cluster (3/3 nodes, 7/7 Flux Kustomizations Ready,
10/10 HelmReleases Ready) rather than inferred from commit messages.

README.md
  - Phase 0 -> a per-phase status table: 0-6 delivered and deployed, 7 not open.
  - Layout now shows the wave split, platform-config, apps/vms, infra, bootstrap.
  - Real conformance number (36/51, 70.6%) and how to regenerate it.
  - Devcontainer workflow; note that the gate was red and why.

infra/PHASE1-STATUS.md — rewritten. Was a `virsh`/libvirt resume guide for a
  cluster that no longer exists. Now: the Proxmox substrate, the pfSense NAT
  paths, both kubectl access paths (Keycloak OIDC normal / cert break-glass),
  the toolchain, off-repo state that must not be lost, and the fact that Flux's
  git source is an app inside the cluster (`git push origin main` IS the deploy).

infra/PHASE1-SCOPE.md — historical banner. The exit criteria and sizing
  rationale are still worth keeping; the libvirt execution steps are not.

infra/README.md — Proxmox, plus a map of the subtree and where the cluster
  actually lives (it is not on this workstation).

infra/devcontainer/README.md — the "run tofu and ansible on the HOST" limitation
  is OBSOLETE: it was a dmacvicar/libvirt polkit/PID problem, and bpg/proxmox
  talks to an HTTP API. Everything runs in the container now. Documents the full
  CI-gate toolchain and what each bind mount is load-bearing for (the age keyring
  and the read-only spec repo especially — without the latter, spec-immutability
  silently skips instead of verifying).

infra/tofu/README.md — was "Authoring only — nothing here has been applied". It
  is applied and live. Disk sizes corrected 40/100 -> 64/128 GiB (confirmed
  against the running nodes), pfSense NAT marked done, and a warning that
  terraform.tfstate is absent on a fresh workstation — an apply with empty state
  would try to recreate the three live nodes.

infra/tofu/variables.tf — section comment disagreed with its own defaults.

infra/cluster.sh — retired-with-instructions header. It silently drives libvirt
  domains that do not exist; behaviour unchanged, but it no longer lies.

apps/vms/unifi/README.md — was "NOT WIRED IN", 60Gi, and listed a file that has
  since been dropped. Now: live status, 40Gi, resolved open questions marked
  resolved, and the two constraints the next person will otherwise rediscover —
  KubeVirt's 2048B inline userData cap, and that apps-vms must never carry
  postBuild.substituteFrom (envsubst corrupts the cloud-init).

DECISIONS-LOG.md — backfilled the gap as one structured entry: the Proxmox
  migration, NAT + kube-vip, the twice-proven oauth2-proxy cold-start deadlock,
  the Flux source cutover, CI going live in-cluster, ten app onboardings and the
  renderer bugs they exposed, the wave split (verified: DBs adopted, not
  recreated — original ages intact, prune restored), KubeVirt storage, the UniFi
  VM, and kubectl SSO. Plus verified live state and the carried-forward open list.

Two corrections to the record while verifying:
  - kubectl OIDC is LIVE (`kubectl auth whoami` -> oidc:<user>,
    [oidc:platform-admins]), so the rolling restart 3472f1d deferred has
    happened.
  - UniFi OS Server is NOT installed in the guest. The VM is healthy (Ubuntu
    24.04.4, guest agent connected, live-migratable) but :11443 answers nothing,
    and the CNP explicitly permits cluster -> :11443, so it is genuinely not
    listening rather than a policy artifact.

Docs and comments only; no manifest semantics change.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-27 00:00:05 -05:00

31 lines
1.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# infra/cluster.sh — RETIRED (libvirt era). DO NOT USE.
#
# This managed the ORIGINAL dev cluster: 3 libvirt/KVM VMs on the workstation, on the
# 10.73.0.0/24 NAT network. That cluster no longer exists — the dev cluster was migrated to
# Proxmox VE (nodes 192.168.1.50/.51/.52) and there are no local `k3s-dev-*` domains for
# virsh to start or stop. It is kept only as a record of the retired lifecycle.
#
# What to use instead (see infra/PHASE1-STATUS.md):
# VM power — the Proxmox UI / API on the Proxmox host, or `tofu` in infra/tofu
# kubeconfig — ~/.kube/config context `k3s-oidc` (Keycloak SSO), or the break-glass
# cert kubeconfig from the primary node
# node access — ssh -p 225{0,1,2} [email protected] (pfSense NAT)
# cluster health — kubectl get nodes && flux get kustomizations
set -euo pipefail
export LIBVIRT_DEFAULT_URI=qemu:///system
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
KCFG="${HERE}/ansible/.cache/dev.kubeconfig"
NODES=(k3s-dev-1 k3s-dev-2 k3s-dev-3)
case "${1:-status}" in
status)
virsh list --all | grep -E 'k3s-dev|Name|--' || true
if [ -f "$KCFG" ]; then KUBECONFIG="$KCFG" kubectl get nodes 2>/dev/null || echo "(cluster not reachable — VMs stopped? run: $0 start)"; fi
;;
start) for n in "${NODES[@]}"; do virsh start "$n" 2>/dev/null || echo "$n already running"; done ;;
stop) for n in "${NODES[@]}"; do virsh shutdown "$n" 2>/dev/null || true; done; echo "graceful shutdown sent (state persists on disk; '$0 start' to resume)" ;;
kubeconfig) echo "export KUBECONFIG=${KCFG}" ;;
*) echo "usage: $0 {status|start|stop|kubeconfig}"; exit 2 ;;
esac