From c0611e5f0b6882c90243399a19525da85172c6b8 Mon Sep 17 00:00:00 2001 From: claude-hdb Date: Tue, 14 Jul 2026 13:14:26 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20create=20the=20storage=20pool=20delibera?= =?UTF-8?q?tely=20=E2=80=94=20btrfs,=20because=20cloning=20is=20the=20whol?= =?UTF-8?q?e=20point?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'incus admin init --minimal' picks the 'dir' backend, which has no copy-on-write: every snapshot and clone is a full copy of the box's root — several GB and minutes apiece once Docker, Node and Claude Code are installed. Measured live: one clone took minutes, and a single drill run pays that three times (snapshot + two clones). The workflow the tool exists for — log in once, snapshot, clone forever — stops being attractive at exactly that price. setup-host.sh now bootstraps via a preseed that mirrors what --minimal creates (default pool, incusbr0, default profile with root + eth0) with only the driver deliberate: btrfs on a loop device (CoW — clones share blocks and diverge on write), installing btrfs-progs if absent, falling back to dir with a warning if btrfs cannot be had. Existing hosts are untouched: the block is skipped whenever a 'default' pool exists. Closes #29 --- host/setup-host.sh | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/host/setup-host.sh b/host/setup-host.sh index 6cb8434..25e35f8 100755 --- a/host/setup-host.sh +++ b/host/setup-host.sh @@ -16,8 +16,44 @@ if ! id -nG "$USER" | grep -qw incus-admin; then exit 0 fi -# Storage pool + base config (safe to re-run; init is a no-op if configured) -incus storage show default >/dev/null 2>&1 || incus admin init --minimal +# Storage pool + base config (safe to re-run: skipped once the pool exists). +# NOT 'incus admin init --minimal': minimal picks the 'dir' backend, which has +# no copy-on-write — every snapshot and clone is a FULL copy of the box's root, +# several GB and minutes apiece once a box is provisioned, against a workflow +# whose whole point is "log in once, snapshot, clone forever" (#29). btrfs on +# a loop device gives CoW (near-instant, near-free clones) with no +# partitioning. The preseed mirrors exactly what --minimal creates (pool, +# incusbr0, default profile) with only the driver deliberate; dir remains the +# fallback so a host that cannot do btrfs still works — just slowly, and it +# says so. +if ! incus storage show default >/dev/null 2>&1; then + driver=btrfs + command -v mkfs.btrfs >/dev/null 2>&1 || sudo apt-get install -y btrfs-progs || driver=dir + if ! incus admin init --preseed <&2 + incus admin init --minimal + fi + echo "storage: pool 'default' driver = $(incus storage show default | awk '/^driver:/ {print $2}')" +fi # Isolated NAT network. IPv6 off: one less egress path to reason about. incus network show claudenet >/dev/null 2>&1 || incus network create claudenet \