feat: box export / import — state that survives the box and the host (#70) #78

Merged
dan-claude-bot merged 3 commits from feat/box-export into main 2026-07-18 19:01:57 +00:00
2 changed files with 10 additions and 2 deletions
Showing only changes of commit 2bbc53d1dd - Show all commits

View file

@ -161,7 +161,7 @@ OPTIONS
dev/test only. Default where /dev/kvm is absent.
--json Emit Incus JSON instead of a table (list, info)
--instance-only Export the live state only, no snapshots (export)
--force, -f Delete without the confirmation prompt (rm)
--force, -f Delete without asking (rm); overwrite the file (export)
--remote <r> Act on Incus remote <r> (any)
--help, -h Help; after a command, help for that command
--version, -V Print the box version
@ -347,6 +347,7 @@ the reuse workflow (log in once, snapshot, clone forever) lives in them.
box export <box> [<file>] # default file: <box>-<UTC timestamp>.tar.gz
--instance-only # live state only, leave the snapshots behind
--force # overwrite an existing <file> (refused otherwise)
The box must be stopped first ('box down <box>'). Incus can back up a running
instance, but a live root disk is a moving target — and this artifact's whole
@ -804,7 +805,7 @@ wait_agent() {
# the reset costs one reboot. Do it before handing the box over, never after.
reset_identity() {
local i="$1"
echo "box: giving the clone its own identity (machine-id, DHCP lease)..."
echo "box: giving the instance its own identity (machine-id, DHCP lease)..."
# Do NOT truncate machine-id and reboot: systemd needs a valid one to shut
# down cleanly, so the graceful stop hangs and the reboot never happens —
# leaving the clone on its source's identity, which is the bug we are here to

View file

@ -151,6 +151,13 @@ snaps="$(incus project get "$p1" restricted.snapshots 2>/dev/null)"
[ "$snaps" = allow ] && ok "snapshots allowed in $p1 (the clone workflow exists)" \
|| no "restricted.snapshots = '$snaps' — box snapshot will refuse"
# The same shape for backups (#70): export rides the backup API, which
# restricted projects block by default exactly like snapshots. A grant that
# missed this key strands every post-upgrade 'box export' at the tier.
bkups="$(incus project get "$p1" restricted.backups 2>/dev/null)"
[ "$bkups" = allow ] && ok "backups allowed in $p1 (box export works at this tier)" \
|| no "restricted.backups = '$bkups' — box export will refuse"
incus --project "$p1" profile device get default eth0 type >/dev/null 2>&1 \
&& no "(h) $p1's default profile still carries the private-bridge eth0" \
|| ok "(h) $p1's default profile places no network — box-net is the only door"