release: box 0.5.0 — codex+grok templates, migrate-host, box expose #56
8 changed files with 90 additions and 36 deletions
19
README.md
19
README.md
|
|
@ -18,7 +18,7 @@ live in a shared profile no template can touch, so `blank` is a box with
|
||||||
nobody home — not a box with the safety off.
|
nobody home — not a box with the safety off.
|
||||||
|
|
||||||
**The tool knows nothing about your projects.** You just `git clone` inside a
|
**The tool knows nothing about your projects.** You just `git clone` inside a
|
||||||
box. A repo can ship an optional [`.claudebox/`](docs/box-recipe.md)
|
box. A repo can ship an optional [`.box/`](docs/box-recipe.md)
|
||||||
runbook that Claude Code reads and acts on — there is no `install` step and no
|
runbook that Claude Code reads and acts on — there is no `install` step and no
|
||||||
host-run setup. See [docs/box-design.md](docs/box-design.md) for the
|
host-run setup. See [docs/box-design.md](docs/box-design.md) for the
|
||||||
design rationale.
|
design rationale.
|
||||||
|
|
@ -44,7 +44,7 @@ retires the old `claudebox` symlink. (No `git clone` needed.)
|
||||||
## One-time host setup (Ubuntu 24.04 / Debian 13)
|
## One-time host setup (Ubuntu 24.04 / Debian 13)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
~/.local/share/box/host/setup-host.sh # run twice if it adds you to incus-admin (re-login between)
|
box setup-host # run twice if it adds you to incus-admin (re-login between)
|
||||||
```
|
```
|
||||||
|
|
||||||
Idempotent. Installs Incus and creates the isolation stack: the `boxnet` NAT
|
Idempotent. Installs Incus and creates the isolation stack: the `boxnet` NAT
|
||||||
|
|
@ -70,7 +70,7 @@ claude # then run /login — copy the URL (press c), o
|
||||||
# in YOUR browser, paste the code back. No host CLI needed.
|
# in YOUR browser, paste the code back. No host CLI needed.
|
||||||
gh auth login # or drop a PAT in — your git credentials, your call
|
gh auth login # or drop a PAT in — your git credentials, your call
|
||||||
git clone https://github.com/you/project && cd project
|
git clone https://github.com/you/project && cd project
|
||||||
claude # if the repo has .claudebox/, Claude reads it and sets up
|
claude # if the repo has .box/, Claude reads it and sets up
|
||||||
```
|
```
|
||||||
|
|
||||||
## Templates
|
## Templates
|
||||||
|
|
@ -158,7 +158,8 @@ dev/test only.
|
||||||
## Boxes are just Incus instances
|
## Boxes are just Incus instances
|
||||||
|
|
||||||
A box is an ordinary Incus instance tagged `user.box=1` (pre-0.4.0 boxes
|
A box is an ordinary Incus instance tagged `user.box=1` (pre-0.4.0 boxes
|
||||||
carry `user.claudebox=1`, honored forever). box wraps the box lifecycle and the isolation model — not all of Incus. It owns a command
|
carry `user.claudebox=1`, honored forever). box wraps the box lifecycle and
|
||||||
|
the isolation model — not all of Incus. It owns a command
|
||||||
when it must enforce something Incus can't see: that tag (it will not stop,
|
when it must enforce something Incus can't see: that tag (it will not stop,
|
||||||
rename or delete an instance it didn't mint), the isolation stack, or the
|
rename or delete an instance it didn't mint), the isolation stack, or the
|
||||||
creds-free snapshot workflow. For everything else, there's the door:
|
creds-free snapshot workflow. For everything else, there's the door:
|
||||||
|
|
@ -227,9 +228,9 @@ diagnoses the host faults that have actually happened: a wedged Incus daemon,
|
||||||
a dnsmasq that silently isn't serving, a VPN resolver that boxes would
|
a dnsmasq that silently isn't serving, a VPN resolver that boxes would
|
||||||
inherit.
|
inherit.
|
||||||
|
|
||||||
## Recipes: the `.claudebox/` convention
|
## Recipes: the `.box/` convention
|
||||||
|
|
||||||
A repo that wants to be easy to stand up in a box ships an optional `.claudebox/`
|
A repo that wants to be easy to stand up in a box ships an optional `.box/`
|
||||||
folder — a runbook Claude reads and follows (install deps, start services,
|
folder — a runbook Claude reads and follows (install deps, start services,
|
||||||
template env, seed data, smoke-test). It is agent-facing documentation, not a
|
template env, seed data, smoke-test). It is agent-facing documentation, not a
|
||||||
host-executed script. See [docs/box-recipe.md](docs/box-recipe.md).
|
host-executed script. See [docs/box-recipe.md](docs/box-recipe.md).
|
||||||
|
|
@ -237,9 +238,9 @@ host-executed script. See [docs/box-recipe.md](docs/box-recipe.md).
|
||||||
## Uninstall
|
## Uninstall
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
~/.local/share/box/host/teardown-host.sh # boxes, network, ACL, profile, firewall
|
box teardown-host # boxes, network, ACL, profile, firewall
|
||||||
~/.local/share/box/host/teardown-host.sh --purge-incus # ...and Incus itself
|
box teardown-host --purge-incus # ...and Incus itself
|
||||||
rm -rf ~/.local/share/box ~/.local/bin/box # the CLI
|
rm -rf ~/.local/share/box ~/.local/bin/box # the CLI itself
|
||||||
```
|
```
|
||||||
|
|
||||||
## Non-goals
|
## Non-goals
|
||||||
|
|
|
||||||
51
bin/box
51
bin/box
|
|
@ -53,6 +53,9 @@ CMDS=(
|
||||||
"expose^<box> <port> [<host-port>] | --list | --remove <port>^box^Forward a box port to the host's loopback — see a dev server^fn:cmd_expose^"
|
"expose^<box> <port> [<host-port>] | --list | --remove <port>^box^Forward a box port to the host's loopback — see a dev server^fn:cmd_expose^"
|
||||||
"incus^<box> -- <args...>^box^Escape hatch: run any incus command against a box^fn:cmd_incus^"
|
"incus^<box> -- <args...>^box^Escape hatch: run any incus command against a box^fn:cmd_incus^"
|
||||||
"doctor^[--fix | --pin-dns]^^Is this host fit to mint boxes? Diagnose the daemon, network, DNS, isolation^fn:cmd_doctor^"
|
"doctor^[--fix | --pin-dns]^^Is this host fit to mint boxes? Diagnose the daemon, network, DNS, isolation^fn:cmd_doctor^"
|
||||||
|
"setup-host^^^One-time host setup: Incus, the boxnet stack, the profile, the firewall^fn:cmd_setup_host^"
|
||||||
|
"teardown-host^[--purge-incus]^^Remove the box host stack (both name generations)^fn:cmd_teardown_host^"
|
||||||
|
"migrate-host^--box <n> | --all-boxes | --retire-legacy^^Move a host from the pre-0.4.0 stack onto box^fn:cmd_migrate_host^"
|
||||||
"status^^^Deprecated alias for 'list'^fn:cmd_status^"
|
"status^^^Deprecated alias for 'list'^fn:cmd_status^"
|
||||||
"help^[<command>]^^This help, or 'box help <command>' for one command^fn:cmd_help^"
|
"help^[<command>]^^This help, or 'box help <command>' for one command^fn:cmd_help^"
|
||||||
)
|
)
|
||||||
|
|
@ -119,7 +122,7 @@ EOF
|
||||||
local r v sum
|
local r v sum
|
||||||
for r in "${CMDS[@]}"; do
|
for r in "${CMDS[@]}"; do
|
||||||
IFS='^' read -r v _ _ sum _ _ <<<"$r"
|
IFS='^' read -r v _ _ sum _ _ <<<"$r"
|
||||||
printf ' %-9s %s\n' "$v" "$sum"
|
printf ' %-13s %s\n' "$v" "$sum"
|
||||||
done
|
done
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
|
|
||||||
|
|
@ -371,6 +374,37 @@ cloud-init error that names none of them.
|
||||||
Exit 0 = clean; 1 = problems found (each printed with its fix). Read-only
|
Exit 0 = clean; 1 = problems found (each printed with its fix). Read-only
|
||||||
unless --fix or --pin-dns is given.
|
unless --fix or --pin-dns is given.
|
||||||
EOF
|
EOF
|
||||||
|
;;
|
||||||
|
setup-host) cat <<'EOF'
|
||||||
|
Prepare this host to mint boxes — one time. Installs Incus and builds the
|
||||||
|
isolation stack: the boxnet NAT bridge (resolver pinned), the box-isolate
|
||||||
|
ACL, the box-net profile, and the firewall rules, all re-applied at boot.
|
||||||
|
Idempotent — safe to re-run after a box upgrade to pick up stack changes.
|
||||||
|
|
||||||
|
If it has to add you to the incus-admin group it will say so and exit; log
|
||||||
|
back in (or 'sg incus-admin') and run it again.
|
||||||
|
|
||||||
|
box setup-host
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
teardown-host) cat <<'EOF'
|
||||||
|
Remove the box host stack — all boxes, the boxnet/claudenet networks, the
|
||||||
|
ACLs, the profiles, and the firewall rules of BOTH name generations (current
|
||||||
|
and pre-0.4.0). Asks first.
|
||||||
|
|
||||||
|
box teardown-host # the stack; leaves Incus installed
|
||||||
|
box teardown-host --purge-incus # ...and uninstall Incus too
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
migrate-host) cat <<'EOF'
|
||||||
|
Move a host from the pre-0.4.0 'claudebox' stack onto 'box'. Re-homing
|
||||||
|
preserves a box's authed state (no re-login) — it only re-tags and reassigns
|
||||||
|
the profile, then verifies the box works on its new network leg.
|
||||||
|
|
||||||
|
box migrate-host --box <name> # re-home one legacy box
|
||||||
|
box migrate-host --all-boxes # re-home every legacy box
|
||||||
|
box migrate-host --retire-legacy # remove the old stack (once no legacy box remains)
|
||||||
|
EOF
|
||||||
;;
|
;;
|
||||||
status) cat <<'EOF'
|
status) cat <<'EOF'
|
||||||
Deprecated alias for 'box list'. It ignored the <box> argument it
|
Deprecated alias for 'box list'. It ignored the <box> argument it
|
||||||
|
|
@ -424,6 +458,8 @@ while [ $# -gt 0 ]; do
|
||||||
if [ "$cmd" = doctor ]; then args+=("$1"); shift; continue; fi
|
if [ "$cmd" = doctor ]; then args+=("$1"); shift; continue; fi
|
||||||
# expose's own flags (--list, --remove) are positional to it, not box's
|
# expose's own flags (--list, --remove) are positional to it, not box's
|
||||||
if [ "$cmd" = expose ]; then args+=("$1"); shift; continue; fi
|
if [ "$cmd" = expose ]; then args+=("$1"); shift; continue; fi
|
||||||
|
# the host verbs delegate their flags to the scripts they wrap
|
||||||
|
case "$cmd" in setup-host|teardown-host|migrate-host) args+=("$1"); shift; continue ;; esac
|
||||||
if [ "$cmd" = exec ] || [ "$cmd" = incus ]; then
|
if [ "$cmd" = exec ] || [ "$cmd" = incus ]; then
|
||||||
usage_error "unknown option: $1 — a command's own flags go after --, as in '$(synopsis_of "$cmd")'"
|
usage_error "unknown option: $1 — a command's own flags go after --, as in '$(synopsis_of "$cmd")'"
|
||||||
fi
|
fi
|
||||||
|
|
@ -843,6 +879,19 @@ cmd_doctor() {
|
||||||
exec bash "$script" "${args[@]}"
|
exec bash "$script" "${args[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# The host lifecycle scripts, as first-class verbs — nobody should have to know
|
||||||
|
# where the install tree keeps its scripts. Each execs the installed script
|
||||||
|
# with its flags passed through; the script owns its own behavior (setup-host's
|
||||||
|
# incus-admin re-login dance, teardown's confirmation, migrate's per-box work).
|
||||||
|
host_script() { # $1 = script basename under host/
|
||||||
|
local script="$root/host/$1"
|
||||||
|
[ -f "$script" ] || die "$1 not found at $script — re-run install.sh"
|
||||||
|
exec bash "$script" "${args[@]}"
|
||||||
|
}
|
||||||
|
cmd_setup_host() { host_script setup-host.sh; }
|
||||||
|
cmd_teardown_host() { host_script teardown-host.sh; }
|
||||||
|
cmd_migrate_host() { host_script migrate-host.sh; }
|
||||||
|
|
||||||
cmd_help() { show_help "${args[0]:-}"; }
|
cmd_help() { show_help "${args[0]:-}"; }
|
||||||
|
|
||||||
# The escape hatch. The box is resolved and tag-checked; everything else is
|
# The escape hatch. The box is resolved and tag-checked; everything else is
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ design decisions.
|
||||||
|
|
||||||
- **The tool** mints isolated boxes with Claude installed but **unauthenticated**.
|
- **The tool** mints isolated boxes with Claude installed but **unauthenticated**.
|
||||||
It knows nothing about projects, secrets, recipes, or memory.
|
It knows nothing about projects, secrets, recipes, or memory.
|
||||||
- **The agent** (Claude Code, inside the box) reads an optional `.claudebox/`
|
- **The agent** (Claude Code, inside the box) reads an optional `.box/`
|
||||||
runbook in a cloned repo and acts on it. The recipe's consumer is the
|
runbook in a cloned repo and acts on it. The recipe's consumer is the
|
||||||
reasoning agent, not host machinery.
|
reasoning agent, not host machinery.
|
||||||
|
|
||||||
|
|
@ -45,10 +45,10 @@ Log in once → snapshot → spin up authed boxes from it.
|
||||||
|
|
||||||
cloud-init installs a global `~/.claude/CLAUDE.md` in every box telling Claude it
|
cloud-init installs a global `~/.claude/CLAUDE.md` in every box telling Claude it
|
||||||
is running in a box (trust-less, ephemeral, creds-free) and to treat a
|
is running in a box (trust-less, ephemeral, creds-free) and to treat a
|
||||||
repo's `.claudebox/` folder as its bootstrap runbook. No "tell it" step, no host
|
repo's `.box/` folder as its bootstrap runbook. No "tell it" step, no host
|
||||||
execution.
|
execution.
|
||||||
|
|
||||||
## `.claudebox/` is optional, agent-facing documentation
|
## `.box/` is optional, agent-facing documentation
|
||||||
|
|
||||||
Not host-executed shell. A repo that wants to be easy to stand up in a sandbox
|
Not host-executed shell. A repo that wants to be easy to stand up in a sandbox
|
||||||
ships a runbook (prose + optional scripts the agent may run). A repo that does
|
ships a runbook (prose + optional scripts the agent may run). A repo that does
|
||||||
|
|
@ -56,12 +56,12 @@ not, you set up by hand. The tool enforces no contract; there is no `install`.
|
||||||
|
|
||||||
## What box owns, and what it doesn't
|
## What box owns, and what it doesn't
|
||||||
|
|
||||||
Boxes are ordinary Incus instances, tagged `user.claudebox=1`. That makes every
|
Boxes are ordinary Incus instances, tagged `user.box=1`. That makes every
|
||||||
Incus verb a candidate feature request — `rename`, `info`, `file push`, on
|
Incus verb a candidate feature request — `rename`, `info`, `file push`, on
|
||||||
forever — and wrapping them one at a time grows a worse `incus`. The rule:
|
forever — and wrapping them one at a time grows a worse `incus`. The rule:
|
||||||
|
|
||||||
> **box owns a command when it must enforce an invariant Incus cannot see:**
|
> **box owns a command when it must enforce an invariant Incus cannot see:**
|
||||||
> the `user.claudebox=1` boundary (never touch an instance we didn't mint), the
|
> the `user.box=1` boundary (never touch an instance we didn't mint), the
|
||||||
> isolation stack (`claude-dev` profile + `claudenet` + ACL), or the creds-free
|
> isolation stack (`claude-dev` profile + `claudenet` + ACL), or the creds-free
|
||||||
> snapshot→clone workflow. Everything else is Incus's job.
|
> snapshot→clone workflow. Everything else is Incus's job.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# The `.claudebox/` convention
|
# The `.box/` convention
|
||||||
|
|
||||||
`box` mints trust-less, creds-free, isolated VMs with Claude Code already
|
`box` mints trust-less, creds-free, isolated VMs with Claude Code already
|
||||||
installed (`box new/shell/snapshot/restore/exec/down/start/rm/status`). The
|
installed (`box new/shell/snapshot/restore/exec/down/start/rm/status`). The
|
||||||
|
|
@ -6,13 +6,17 @@ tool knows **nothing** about your project. There is no `install` step and no
|
||||||
host-run setup script.
|
host-run setup script.
|
||||||
|
|
||||||
A project makes itself easy to stand up inside a box by shipping an optional
|
A project makes itself easy to stand up inside a box by shipping an optional
|
||||||
`.claudebox/` folder. This folder is **agent-facing documentation** — read and
|
`.box/` folder. This folder is **agent-facing documentation** — read and
|
||||||
acted on by Claude Code (the reasoning agent) running inside the box. It is not
|
acted on by Claude Code (the reasoning agent) running inside the box. It is not
|
||||||
shell that the host executes.
|
shell that the host executes.
|
||||||
|
|
||||||
|
> The folder was named `.claudebox/` before the 0.5.0 rename. Repos that still
|
||||||
|
> ship `.claudebox/` keep working — the agent is told to read either — but new
|
||||||
|
> projects should use `.box/`.
|
||||||
|
|
||||||
## What it is / what it is not
|
## What it is / what it is not
|
||||||
|
|
||||||
- **Optional.** No `.claudebox/` is a perfectly valid state.
|
- **Optional.** No `.box/` is a perfectly valid state.
|
||||||
- **Agent-facing.** You are writing instructions to a reasoning agent, not a
|
- **Agent-facing.** You are writing instructions to a reasoning agent, not a
|
||||||
machine. Prose is fine; the agent adapts.
|
machine. Prose is fine; the agent adapts.
|
||||||
- **Not a host contract.** The host never parses, sources, or runs anything in
|
- **Not a host contract.** The host never parses, sources, or runs anything in
|
||||||
|
|
@ -23,34 +27,34 @@ shell that the host executes.
|
||||||
## How it's consumed
|
## How it's consumed
|
||||||
|
|
||||||
Every box ships a global `~/.claude/CLAUDE.md` telling Claude it is inside a
|
Every box ships a global `~/.claude/CLAUDE.md` telling Claude it is inside a
|
||||||
box and to treat a repo's `.claudebox/` folder as its bootstrap runbook.
|
box and to treat a repo's `.box/` folder as its bootstrap runbook.
|
||||||
So the whole flow is:
|
So the whole flow is:
|
||||||
|
|
||||||
```
|
```
|
||||||
box new # get a box
|
box new # get a box
|
||||||
box shell # get in
|
box shell # get in
|
||||||
git clone <repo> && cd <repo>
|
git clone <repo> && cd <repo>
|
||||||
claude # Claude reads .claudebox/ and brings the project up
|
claude # Claude reads .box/ and brings the project up
|
||||||
```
|
```
|
||||||
|
|
||||||
The operator can also just say: *"set this project up per .claudebox"*.
|
The operator can also just say: *"set this project up per .box"*.
|
||||||
|
|
||||||
## Suggested contents (all optional)
|
## Suggested contents (all optional)
|
||||||
|
|
||||||
Author everything here for a reasoning agent.
|
Author everything here for a reasoning agent.
|
||||||
|
|
||||||
- **`.claudebox/SETUP.md`** — the prose runbook. Prerequisites, how to install
|
- **`.box/SETUP.md`** — the prose runbook. Prerequisites, how to install
|
||||||
deps, how to start services, how to template the env, how to seed data, and
|
deps, how to start services, how to template the env, how to seed data, and
|
||||||
how to smoke-test. Written as instructions to Claude.
|
how to smoke-test. Written as instructions to Claude.
|
||||||
- **Helper scripts** (e.g. `.claudebox/dev-up.sh`) that the runbook tells Claude
|
- **Helper scripts** (e.g. `.box/dev-up.sh`) that the runbook tells Claude
|
||||||
to run. Claude decides to run them; the host never does.
|
to run. Claude decides to run them; the host never does.
|
||||||
- **`.claudebox/env.template`** — example env the runbook explains how to fill.
|
- **`.box/env.template`** — example env the runbook explains how to fill.
|
||||||
Staging values the operator pastes in. **Never commit real secrets.**
|
Staging values the operator pastes in. **Never commit real secrets.**
|
||||||
- **`.claudebox/compose.yml`** — optional services the runbook starts.
|
- **`.box/compose.yml`** — optional services the runbook starts.
|
||||||
|
|
||||||
## Worked example
|
## Worked example
|
||||||
|
|
||||||
A minimal `.claudebox/SETUP.md` for a Node + Postgres app:
|
A minimal `.box/SETUP.md` for a Node + Postgres app:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# Setup
|
# Setup
|
||||||
|
|
@ -58,8 +62,8 @@ A minimal `.claudebox/SETUP.md` for a Node + Postgres app:
|
||||||
This is a Node service backed by Postgres.
|
This is a Node service backed by Postgres.
|
||||||
|
|
||||||
1. Install deps: `npm ci`
|
1. Install deps: `npm ci`
|
||||||
2. Start Postgres: `docker compose -f .claudebox/compose.yml up -d`
|
2. Start Postgres: `docker compose -f .box/compose.yml up -d`
|
||||||
3. Create the env file: copy `.claudebox/env.template` to `.env` and ask the
|
3. Create the env file: copy `.box/env.template` to `.env` and ask the
|
||||||
operator to fill in `DATABASE_URL` and `API_KEY` (staging values).
|
operator to fill in `DATABASE_URL` and `API_KEY` (staging values).
|
||||||
4. Run migrations: `npm run migrate`
|
4. Run migrations: `npm run migrate`
|
||||||
5. Start the app: `npm run dev`
|
5. Start the app: `npm run dev`
|
||||||
|
|
@ -72,7 +76,7 @@ That's it — Claude reads it top to bottom and adapts if reality differs.
|
||||||
|
|
||||||
- **Keep it declarative and resilient.** State intent and steps; let the agent
|
- **Keep it declarative and resilient.** State intent and steps; let the agent
|
||||||
adapt when the repo has drifted. Don't hard-code brittle assumptions.
|
adapt when the repo has drifted. Don't hard-code brittle assumptions.
|
||||||
- **Never put real credentials in `.claudebox/`.** Templates and staging
|
- **Never put real credentials in `.box/`.** Templates and staging
|
||||||
placeholders only. The operator pastes real values at runtime.
|
placeholders only. The operator pastes real values at runtime.
|
||||||
- **No `.claudebox/` is fine.** The operator can stand the project up by hand,
|
- **No `.box/` is fine.** The operator can stand the project up by hand,
|
||||||
or let Claude infer the steps from the repo's `README` / `CLAUDE.md`.
|
or let Claude infer the steps from the repo's `README` / `CLAUDE.md`.
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ if incus network show boxnet >/dev/null 2>&1; then
|
||||||
ok "dns.mode = none — a box cannot enumerate its siblings by name"
|
ok "dns.mode = none — a box cannot enumerate its siblings by name"
|
||||||
else
|
else
|
||||||
no "dns.mode = ${dns:-<unset>} — a box can RESOLVE its siblings' names and addresses"
|
no "dns.mode = ${dns:-<unset>} — a box can RESOLVE its siblings' names and addresses"
|
||||||
inf "fix: re-run ~/.local/share/box/host/setup-host.sh"
|
inf "fix: re-run: box setup-host"
|
||||||
[ "$FIX" = 1 ] && { incus network set boxnet dns.mode=none && inf "set: dns.mode=none"; }
|
[ "$FIX" = 1 ] && { incus network set boxnet dns.mode=none && inf "set: dns.mode=none"; }
|
||||||
fi
|
fi
|
||||||
inf "ipv4.address = $(incus network get boxnet ipv4.address 2>/dev/null)"
|
inf "ipv4.address = $(incus network get boxnet ipv4.address 2>/dev/null)"
|
||||||
|
|
@ -110,7 +110,7 @@ if [ -n "$PROFILES" ]; then
|
||||||
no "$p: security.port_isolation is NOT set — BOXES CAN REACH EACH OTHER"
|
no "$p: security.port_isolation is NOT set — BOXES CAN REACH EACH OTHER"
|
||||||
inf "an L3 ACL cannot do this: two boxes on one bridge are on the same L2"
|
inf "an L3 ACL cannot do this: two boxes on one bridge are on the same L2"
|
||||||
inf "segment, so their frames are switched, never routed past the ACL."
|
inf "segment, so their frames are switched, never routed past the ACL."
|
||||||
inf "fix: re-run ~/.local/share/box/host/setup-host.sh"
|
inf "fix: re-run: box setup-host"
|
||||||
fi
|
fi
|
||||||
for k in security.mac_filtering security.ipv4_filtering; do
|
for k in security.mac_filtering security.ipv4_filtering; do
|
||||||
v="$(incus profile device get "$p" eth0 "$k" 2>/dev/null)"
|
v="$(incus profile device get "$p" eth0 "$k" 2>/dev/null)"
|
||||||
|
|
@ -192,7 +192,7 @@ else
|
||||||
no "the host resolves via a CGNAT/Tailscale resolver ($hostns), and boxes INHERIT it — see issue #33"
|
no "the host resolves via a CGNAT/Tailscale resolver ($hostns), and boxes INHERIT it — see issue #33"
|
||||||
inf "· box DNS breaks whenever the tailnet's resolver does (this is what kills cold mints)"
|
inf "· box DNS breaks whenever the tailnet's resolver does (this is what kills cold mints)"
|
||||||
inf "· and tailnet names RESOLVE from inside a box, though its ACL blocks connecting to them"
|
inf "· and tailnet names RESOLVE from inside a box, though its ACL blocks connecting to them"
|
||||||
inf "fix: re-run ~/.local/share/box/host/setup-host.sh (it pins the resolver)"
|
inf "fix: re-run: box setup-host (it pins the resolver)"
|
||||||
inf " or quick-test the pin alone: bash drill/doctor.sh --pin-dns"
|
inf " or quick-test the pin alone: bash drill/doctor.sh --pin-dns"
|
||||||
else
|
else
|
||||||
inf "boxes inherit the host's resolver (unpinned — setup-host.sh pins this now; re-run it)"
|
inf "boxes inherit the host's resolver (unpinned — setup-host.sh pins this now; re-run it)"
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ write_files:
|
||||||
- **Disposable.** Nothing here is backed up. State is discarded when the box is
|
- **Disposable.** Nothing here is backed up. State is discarded when the box is
|
||||||
removed; the operator persists work via git push and via `box snapshot`.
|
removed; the operator persists work via git push and via `box snapshot`.
|
||||||
- **Bootstrap runbook.** If the repository you are working in contains a
|
- **Bootstrap runbook.** If the repository you are working in contains a
|
||||||
`.claudebox/` folder, read it as your setup runbook — how to install
|
`.box/` folder (older repos may use `.claudebox/`), read it as your setup runbook — how to install
|
||||||
dependencies, start services, template environment files, seed data, and
|
dependencies, start services, template environment files, seed data, and
|
||||||
smoke-test — and follow it. It is documentation for you, not a script the
|
smoke-test — and follow it. It is documentation for you, not a script the
|
||||||
host runs.
|
host runs.
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ write_files:
|
||||||
- **Disposable.** Nothing here is backed up. State is discarded when the box
|
- **Disposable.** Nothing here is backed up. State is discarded when the box
|
||||||
is removed; the operator persists work via git push and via `box snapshot`.
|
is removed; the operator persists work via git push and via `box snapshot`.
|
||||||
- **Bootstrap runbook.** If the repository you are working in contains a
|
- **Bootstrap runbook.** If the repository you are working in contains a
|
||||||
`.claudebox/` folder, read it as your setup runbook — how to install
|
`.box/` folder (older repos may use `.claudebox/`), read it as your setup runbook — how to install
|
||||||
dependencies, start services, template environment files, seed data, and
|
dependencies, start services, template environment files, seed data, and
|
||||||
smoke-test — and follow it. It is documentation for you, not a script the
|
smoke-test — and follow it. It is documentation for you, not a script the
|
||||||
host runs.
|
host runs.
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ write_files:
|
||||||
- **Disposable.** Nothing here is backed up. State is discarded when the box
|
- **Disposable.** Nothing here is backed up. State is discarded when the box
|
||||||
is removed; the operator persists work via git push and via `box snapshot`.
|
is removed; the operator persists work via git push and via `box snapshot`.
|
||||||
- **Bootstrap runbook.** If the repository you are working in contains a
|
- **Bootstrap runbook.** If the repository you are working in contains a
|
||||||
`.claudebox/` folder, read it as your setup runbook — how to install
|
`.box/` folder (older repos may use `.claudebox/`), read it as your setup runbook — how to install
|
||||||
dependencies, start services, template environment files, seed data, and
|
dependencies, start services, template environment files, seed data, and
|
||||||
smoke-test — and follow it. It is documentation for you, not a script the
|
smoke-test — and follow it. It is documentation for you, not a script the
|
||||||
host runs.
|
host runs.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue