feat: server-class staging template — box mints, rig converges, cast registers #69
2 changed files with 53 additions and 0 deletions
21
CHANGELOG.md
21
CHANGELOG.md
|
|
@ -5,6 +5,27 @@ which records not just what changed but what each drill run proved.
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- **Server-class boxes: the `staging` template** (#68) — Debian 13 VM with
|
||||
docker + rig (+ tmux, the #65 contract) preinstalled and *nothing* that
|
||||
joins or admits: tailscale, sshd and every credential are rig's to install
|
||||
at bootstrap time (`box shell` → `sudo rig bootstrap workload`), inside
|
||||
the guest — box stays creds-free. Two new optional `box.env` keys carry
|
||||
the posture: `BOX_REQUIRE_VM=1` (no container fallback, and `--container`
|
||||
is refused — the VM is the trust boundary and the guest runs docker) and
|
||||
`BOX_AUTOSTART=1` (`boot.autostart=true`, so the box returns from a host
|
||||
reboot without an operator; clones inherit it via `incus copy`). Still no
|
||||
key for a network or a `security.*` flag. The design doc gains the
|
||||
overlay-join clarification and the snapshot-before-join rule.
|
||||
- **Template test suite** — `test/cli.sh`'s template coverage is dynamic
|
||||
over `templates/*/`, so a new template cannot ship unseen: `box.env` is
|
||||
driven through the real, extracted `load_template` (unknown keys and
|
||||
missing `BOX_IMAGE`/`BOX_USER` fail), `user-data.yaml` must exist, declare
|
||||
`#cloud-config`, parse as YAML and install tmux; staging additionally
|
||||
proves its boot demands, docker + rig, and the creds-free refusal (no
|
||||
tailscale/authkey/ssh in effective cloud-init lines).
|
||||
|
||||
## 0.6.0 — 2026-07-18
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -132,3 +132,35 @@ pass before merge:
|
|||
- [ ] Grep assertions: `BOX_REQUIRE_VM`/`BOX_AUTOSTART` appear in the
|
||||
allowlist; `boot.autostart` is stamped only under the `BOX_AUTOSTART`
|
||||
guard; no template other than `staging` sets either key.
|
||||
|
||||
---
|
||||
|
||||
## Addendum (2026-07-18): rebased onto main; the template test suite
|
||||
|
||||
The branch was rebased onto main, which had since gained the restricted tier
|
||||
(#74), a CI workflow, and `test/cli.sh`. What that changed here:
|
||||
|
||||
- **`load_template` conflicts** — main replaced the `[ -n … ] && [ -n … ] ||
|
||||
die` required-keys idiom with the spelled-out `if [ -z … ]` form (SC2015)
|
||||
and grew the SC2034 directive block; the two new key arms were re-applied
|
||||
onto that version, both intact.
|
||||
- **`cmd_new`** — main added a tier-aware box-net pre-flight at the top of
|
||||
the function; the `BOX_REQUIRE_VM` refusal stays in the fresh-mint branch,
|
||||
after `pick_mode` (it must read the *effective* mode). Its message holds
|
||||
for both tiers: `/dev/kvm` is a host fact, and admin and restricted mints
|
||||
go through the same daemon, so the fix is the same — a KVM host, not a
|
||||
grant.
|
||||
- **tmux** — `box tmux` is a contract every template honors (#65, asserted
|
||||
by `test/cli.sh`), so the staging package list carries tmux; the operator
|
||||
babysits `rig bootstrap workload` through it.
|
||||
- **The template test suite** (maintainer request): `test/cli.sh`'s template
|
||||
coverage is now *dynamic* over `templates/*/` — a new template cannot ship
|
||||
unseen. Per template: `box.env` driven through the real, extracted
|
||||
`load_template` (unknown keys and missing `BOX_IMAGE`/`BOX_USER` fail);
|
||||
`user-data.yaml` exists, declares `#cloud-config`, parses as YAML
|
||||
(python3+pyyaml, loudly skipped where absent), installs tmux.
|
||||
Staging-specific: both boot demands proven through the parser, docker +
|
||||
rig present, and a creds-free grep-refusal (no tailscale/authkey/ssh in
|
||||
effective cloud-init lines). Grep guards pin the `cmd_new` half: the
|
||||
refusal orders after `pick_mode`; `boot.autostart` is stamped only under
|
||||
the `T_AUTOSTART` guard.
|
||||
|
|
|
|||
Loading…
Reference in a new issue