feat!: claudebox becomes box — the Claude box is one template among several
The tool underneath was already generic: a thin, honest wrapper over
Incus. What was Claude-specific was welded on — one image, one profile,
one cloud-init file, one hardcoded 'sudo -u claude'. The weld is now a
template.
The mechanic: 'box new' stamps the template's identity onto the
instance (user.box=1, user.box.template, user.box.user); shell/exec/
tmux read the user back off the instance, and 'incus copy' carries
user.* keys (audit B2), so a clone knows what it is without consulting
the template. Templates are box.env (parsed against a strict allowlist,
never sourced — no key for a network exists, on purpose) plus a
verbatim cloud-init. Every template launches with the shared box-net
profile: the isolated NIC and root disk, nothing template-controlled —
resources land per-instance from box.env, overridable via BOX_CPU/
BOX_MEMORY/BOX_DISK (which is also how the drill shrinks boxes on a
small host now that profile edits can't).
The three open calls, taken as recommended: clean cut at 0.4.0 (no
claudebox shim; the installer retires the old symlink); default
template = claude (muscle memory survives); repo stays heavy-duty/
claudebox, binary is box.
Compat is the tag, not the name: resolve_box and list honor the legacy
user.claudebox=1 forever, and the legacy tag maps to the claude user —
a pre-rename box lists, shells, clones, unchanged.
Deliberate divergence from #17's table: the host-stack resource names
(claudenet, claude-isolate, nft tables, claudebox-firewall.*) are NOT
renamed — they are host-internal, invisible to users, and renaming
them breaks every provisioned host for zero user-visible gain.
claude-dev is no longer created; setup-host creates box-net, teardown
removes both.
Closes #17
2026-07-14 14:22:50 +00:00
|
|
|
#cloud-config
|
|
|
|
|
# The whole template: create the user and stop. BOX_USER in box.env must
|
|
|
|
|
# match the name here — the file is passed to Incus verbatim.
|
|
|
|
|
users:
|
|
|
|
|
- name: dev
|
|
|
|
|
shell: /bin/bash
|
|
|
|
|
sudo: "ALL=(ALL) NOPASSWD:ALL"
|
|
|
|
|
lock_passwd: true
|
|
|
|
|
package_update: false
|
2026-07-18 00:01:15 +00:00
|
|
|
# The one package a blank box still needs: 'box tmux' runs 'tmux new-session'
|
|
|
|
|
# INSIDE the box, and a bare Debian image ships no tmux — without this it fails
|
|
|
|
|
# with "tmux: command not found" (#65). cloud-init refreshes the apt lists on its
|
|
|
|
|
# own whenever 'packages' is non-empty, so package_update stays false here.
|
|
|
|
|
packages:
|
|
|
|
|
- tmux
|