fix: box restore asks before it destroys, in its own words (#105) #109
4 changed files with 23 additions and 4 deletions
|
|
@ -59,7 +59,11 @@ which records not just what changed but what each drill run proved.
|
|||
one verb that already worked would be a regression shipped as a
|
||||
refactor. A row marked `confirm` with no words is now a hard internal
|
||||
error rather than a blank question. `--force` and the no-TTY refusal come
|
||||
free — `confirm()` already had both. Coverage went from two
|
||||
free — `confirm()` already had both. The one automated caller had to
|
||||
consent explicitly: `drill/multiuser.sh` drives restore unattended on real
|
||||
Incus and now passes `--force`, which is the rehearsal proving the gate
|
||||
rather than working around it — the CI run of this very PR failed there
|
||||
first, which is the shape a gate is supposed to have. Coverage went from two
|
||||
argument-validation checks that never reached dispatch to the destructive
|
||||
path itself, driven against a fake incus: refusing leaves the call log
|
||||
empty, `--force` produces exactly one `incus snapshot restore`. Not
|
||||
|
|
|
|||
|
|
@ -320,7 +320,10 @@ box new --name feature --from work/authed # clone the authed state into a new
|
|||
|
||||
`--from` copies the whole box (agent login, git creds, clones and all) while
|
||||
preserving isolation. You can also `box new --name x --from work` to clone
|
||||
a box's live state, or roll a box back with `box restore work authed`.
|
||||
a box's live state, or roll a box back with `box restore work authed` — which
|
||||
asks first, since a rollback discards everything since the snapshot (`--force`
|
||||
skips the prompt, and scripts must pass it: with no terminal to ask on, box
|
||||
refuses rather than assuming yes).
|
||||
|
||||
Forgotten what you called a checkpoint? `box info work` prints the box's
|
||||
snapshot labels and the `--from` line to clone one.
|
||||
|
|
@ -388,7 +391,8 @@ box shell <box> # enter as the template's user
|
|||
box exec <box> -- <cmd...> # run a command in the box
|
||||
box tmux <box> [session] # attach/create a tmux session — survives disconnects
|
||||
box snapshot <box> [label] # checkpoint (label defaults to manual-<epoch>)
|
||||
box restore <box> <snap> # roll back to a snapshot
|
||||
box restore <box> <snap> [--force]
|
||||
# roll back to a snapshot — destructive, asks first
|
||||
box export <box> [<file>] [--instance-only]
|
||||
# one portable file (snapshots incl.) — survives rm & host
|
||||
box import <file> [--name <box>]
|
||||
|
|
|
|||
|
|
@ -206,7 +206,13 @@ as_u "$U1" box info mine 2>/dev/null | grep -qF "$(boxnet_pfx)" \
|
|||
&& ok "(g) box info shows a boxnet ($(boxnet_pfx)x) address — placed on the hardened network" \
|
||||
|| no "(g) mine has no boxnet address in box info"
|
||||
as_u "$U1" box snapshot mine s1 >/dev/null 2>&1 && ok "(b) box snapshot mine s1" || no "(b) snapshot refused"
|
||||
as_u "$U1" box restore mine s1 >/dev/null 2>&1 && ok "(b) box restore mine s1 (the incus 6 'snapshot restore' spelling)" || no "(b) restore failed"
|
||||
# --force, and it is the assertion as much as the fix: restore is destructive
|
||||
# and now asks (#105), so an unattended drill MUST consent explicitly. Without
|
||||
# the flag this line fails — correctly — because confirm() refuses rather than
|
||||
# assuming yes when there is no terminal to ask on. Adding --force here is not
|
||||
# working around the gate; it is the drill proving the gate is real, and that
|
||||
# the documented non-interactive path through it works on real Incus.
|
||||
as_u "$U1" box restore mine s1 --force >/dev/null 2>&1 && ok "(b) box restore mine s1 --force (the incus 6 'snapshot restore' spelling, through the #105 gate)" || no "(b) restore failed"
|
||||
as_u "$U1" box new --name c1 --from mine/s1 >/dev/null 2>&1 && ok "(b) box new --from mine/s1 — the clone workflow" || no "(b) clone failed"
|
||||
# c1 stays alive through phase g: it is the distinctly-NAMED sibling the
|
||||
# enumeration probe needs (both users' primaries are 'mine' by design of d).
|
||||
|
|
|
|||
|
|
@ -877,6 +877,11 @@ check "table: every 'confirm' row supplies a prompt (#105)" 0 "" \
|
|||
# shellcheck disable=SC2016 # the $-strings are literals in the target file
|
||||
check "dispatch: the confirm prompt comes from the row, not a constant (#105)" 0 "" \
|
||||
grep -qF 'confirm "$(fill "$cnf" "$inst")"' "$ROOT/bin/box"
|
||||
# The rehearsal drives restore unattended on real Incus, so it must consent
|
||||
# EXPLICITLY — the gate is only real if the one automated caller had to change.
|
||||
# Pinned here because the rehearsal itself needs a daemon and this suite has none.
|
||||
check "rehearsal: the unattended restore passes --force (#105)" 0 "" \
|
||||
grep -qF 'box restore mine s1 --force' "$ROOT/drill/multiuser.sh"
|
||||
rm -rf "$CSHIM" "$CWORK"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue