rig major updates

This commit is contained in:
2026-09-22 05:15:49 -03:00
parent 9c963514f1
commit 2a0a793f19
64 changed files with 1762 additions and 645 deletions

View File

@@ -100,24 +100,15 @@ ones you never type, or add whatever your own projects already say: each alias
is two lines at the bottom of the file, calling the same script the canonical
target does.
**`make tilt` works on a fresh copy, unedited.** rig ships `ctrl/Tiltfile`, and
`k8s/base` already boots, so the dev loop comes up with the two examples running
and nothing to configure first.
**`make tilt` works on a fresh copy, unedited.** rig's `ctrl/Tiltfile` does
rig's part — identity, context guard, registry, the manifests — and then includes
the overlay's own Tiltfile. With no overlay named that is `examples/starter`, so
the dev loop comes up with its two examples running and nothing to configure.
It hardcodes nothing. It asks `ctrl/ports.sh active` for this environment's
cluster name, kube context, ports and manifest directory — the same values every
other rig script resolves through `ctrl/lib/config.sh` — so a copied and renamed
rig deploys into its own cluster with no edits. Every other project here writes
its slug into the Tiltfile five or six times by hand, which is exactly the
collision `kind-config.yaml.tpl` exists to avoid.
What it deploys is `MANIFESTS_DIR`, defaulting to rig's own `ctrl/k8s/overlays/dev`.
Point that at an overlay versioned elsewhere and rig stops owning the manifests.
Replace the examples, then add your images and resources in the two marked
sections. The catalogue below them holds the blocks that recur across every
project here — `docker_build`, resource ordering, gateway reload, port-forwards —
with the parts that are easy to get wrong already commented.
cluster name, kube context, ports and paths — the same values every other rig
script resolves through `ctrl/lib/config.sh` — so a copied and renamed rig, or a
moved overlay, deploys into its own cluster with no edits.
`make help` lists every target.
@@ -126,81 +117,82 @@ nothing to download with — see [BOOTSTRAP.md](BOOTSTRAP.md), which runs the
toolchain through the installer container and carries on to scaffolding and running
a new project.
## One directory is one environment
## What runs is an overlay
rig is the machine: toolchain, cluster, registry, port block, the dev loop's
plumbing. What runs on it is an **overlay** — one folder, outside rig's version
control, holding a use case: its settings (`rig.env`), its manifests
(`k8s/overlays/dev`), its images and Tiltfile, its addons, its kind config if it
needs its own. rig reads it and never writes into it. See
[`docs/notes/overlay.md`](docs/notes/overlay.md).
```bash
cp -r examples/starter local/myenv # local/ is gitignored
OVERLAY=local/myenv make cluster up # or OVERLAY=local/myenv in ctrl/.env
OVERLAY=local/myenv make tilt
```
An overlay can also be a repo of its own, anywhere, or a project folder that
carries rig at `<project>/rig/` with a three-line forwarding Makefile.
Copy this directory, rename it, run it. Cluster name, kubectl context, image
tags and the host port block all derive from the directory name, so copies never
collide and neither one's teardown can touch the other.
## One environment per folder
A copy of this directory is a **sibling** of it, named after the environment it
models (`acme-rig`). That is why the ignore rules for copies sit in the *parent*
repo's `.gitignore` rather than here: a rule in this directory cannot see a
directory beside it.
Cluster name, kubectl context, image tags and the host port block all derive
from a folder name — the overlay's when one is named, else rig's own — so copies
never collide and neither one's teardown can touch the other. Two overlays run
side by side from one rig; two copies of rig do too.
## Profiles
**rig needs no profile.** With none named it runs on built-in defaults: one node,
no addons, a local registry, the newest Kubernetes version it pins. A profile is
an optional overlay — a file in `ctrl/env.d/`, named by `PROFILE` — for when you
want different addons or registry.
rig ships **examples**, not active profiles, because each one is a use case rather
than something every rig needs. Copy one to use it:
an optional file in `ctrl/env.d/`, named by `PROFILE`, that says how this machine
reaches the world. rig ships two as **examples**; copy one to use it (the copy is
gitignored):
| example | what it changes |
| --- | --- |
| `client.env.example` | images through a mirror of a corporate registry |
| `mirror.env.example` | images through a pull-through cache of an internal registry |
| `offline.env.example` | air-gapped: everything from a preloaded local registry |
| `data.env.example` | databases and a scheduler: postgres, redis, airflow |
```bash
cp ctrl/env.d/data.env.example ctrl/env.d/data.env
PROFILE=data make cluster up # installs the profile's addons too
PROFILE=data make check # what the profile wants, and what exists
cp ctrl/env.d/mirror.env.example ctrl/env.d/mirror.env
PROFILE=mirror make cluster up
```
The **cluster itself** is one file, `ctrl/k8s/kind-config.yaml.tpl` (one node).
To change it — more nodes, other port mappings — edit it and `make cluster
reset`. The node count is read back out of it, so there is nothing to drift. The layout under `ctrl/k8s/` is the
same as every other project here — a kind config, a kustomize `base/`, an
`overlays/dev/` — see [`ctrl/k8s/README.md`](ctrl/k8s/README.md).
The layers, weakest first: built-in defaults < `ctrl/versions.env` < the profile
< the overlay's `rig.env` < `ctrl/.env` < your command line.
The **cluster itself** is one file: the overlay's `kind-config.yaml.tpl` if it has
one, else rig's `ctrl/k8s/kind-config.yaml.tpl` (one node). To change it — more
nodes, other port mappings, mounts — edit it and `make cluster reset`. The node
count is read back out of it, so there is nothing to drift.
## Addons
Each addon is its own idempotent script in `ctrl/addons/`, and a profile names
the ones it wants in `ADDONS`. Adding one is adding a file — there is no
dispatcher to edit.
Each addon is its own idempotent script, and `ADDONS` names the ones to install,
in order. Adding one is adding a file — there is no dispatcher to edit. An
overlay's `addons/<name>.sh` is found before rig's own.
**There is no ingress controller, deliberately.** They pin a narrow window of
Kubernetes versions, so depending on one would constrain which k8s a rig can be
built with — and running a trailing-edge control plane to model a legacy estate
is the whole point. Services are reached through MetalLB and
`type: LoadBalancer`, which carries no such constraint and is also what a real
cluster does.
built with — and running a trailing-edge control plane is often the point.
Services are reached through MetalLB and `type: LoadBalancer`, which carries no
such constraint and is also what a real cluster does.
rig's own addons make the cluster work:
| Addon | Does |
| --- | --- |
| `metallb` | gives `type: LoadBalancer` an address it can actually reach |
| `cert-manager` | a local CA, so TLS works offline |
| `metrics-server` | makes `kubectl top` work on kind |
| `postgres` | database, in the `data` namespace |
| `redis` | cache and broker |
| `airflow` | scheduled pipelines; needs postgres and redis |
The last three are **cabinets**: a public service dropped in as-is, the upstream
image unmodified, reachable at a known address. A cabinet is declared once and
installs on either target — a `service.yml` composes it for a laptop, and these
install the same one here. The names match on purpose: each cabinet carries a
`rig_addon` field pointing at `ctrl/addons/<name>.sh`.
Plain manifests rather than helm charts, like every other addon: a chart repo is
a network dependency, and the `offline` profile exists precisely so there is a
path with none. Images are pinned in `ctrl/versions.env` and can be preloaded.
Passwords are generated on first install and kept across re-runs, so re-running
an addon never rotates a credential out from under something already connected:
What a workload needs — a database, a cache, a scheduler — belongs to its
overlay. [`examples/data`](examples/data/) carries postgres, redis and airflow as
plain manifests (no helm: a chart repo is a network dependency), with passwords
generated on first install and kept across re-runs:
```bash
kubectl -n data get secret postgres -o jsonpath='{.data.POSTGRES_PASSWORD}' | base64 -d
kubectl -n data port-forward svc/airflow 8080:8080
OVERLAY=examples/data make cluster up
```