feat(sbx): VM dev-toolchain bootstrap + save/load parity across backends
Reorganize the help menu into one VIRTUAL MACHINES cluster covering all backends, and bring docker/multipass/vbox to save+load parity: - Launch-time dev toolchain: sandbox-bootstrap.sh + editable sandbox-tools.json (vim/curl guaranteed), installed in docker AND multipass sandboxes at provision time. - Vbox load: vm_restore + `/sbx vmload <vm> [label]` (restore snapshot then boot the GUI). - Multipass load: `/sbx load` is now backend-aware (locate_snapshot + SnapKind), mp_restore re-attaches the shared shell; teardown stops (not purges) an instance that still has snapshots so they survive `/sbx stop`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
# sandbox-bootstrap.sh — install a baseline dev toolchain inside a hack-house
|
||||
# Docker sandbox.
|
||||
#
|
||||
# It is piped to `bash -s` (as root) inside the container at provision time, so
|
||||
# fresh sandboxes come up usable instead of bare. Idempotent + sentinel-guarded:
|
||||
# a re-provision (new member joins) or a snapshot load is a fast no-op.
|
||||
#
|
||||
# When launched by hh, the package list comes from scripts/sandbox-tools.json
|
||||
# (the canonical, editable schema) via $HH_SBX_PKGS. DEFAULT_PKGS below is only
|
||||
# the fallback for running this script standalone. Per-launch override:
|
||||
# HH_SBX_PKGS="vim tmux ripgrep" ./host-house.sh ...
|
||||
set -uo pipefail
|
||||
|
||||
SENTINEL=/var/lib/hh-bootstrap.done
|
||||
[[ -f "$SENTINEL" ]] && exit 0 # this container is already provisioned
|
||||
|
||||
# Baseline dev tools: editors, fetchers, vcs, net + inspect utilities, json,
|
||||
# archives. Keep names valid for the base image (ubuntu:24.04) — an unknown
|
||||
# package would otherwise abort the whole batch install.
|
||||
DEFAULT_PKGS="vim nano less curl wget ca-certificates git \
|
||||
build-essential pkg-config \
|
||||
procps iproute2 iputils-ping net-tools \
|
||||
jq unzip zip tree htop file ripgrep \
|
||||
python3 python3-pip python3-venv"
|
||||
|
||||
PKGS="${HH_SBX_PKGS:-$DEFAULT_PKGS}"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Refresh the index first (base images ship without /var/lib/apt/lists). If the
|
||||
# update fails (e.g. no network) we bail WITHOUT writing the sentinel, so the
|
||||
# next launch retries instead of leaving a half-provisioned shell.
|
||||
apt-get update -qq || exit 0
|
||||
|
||||
# --no-install-recommends keeps the image lean. apt is atomic on resolution, so
|
||||
# if one name is unavailable the batch aborts — fall back to one-by-one so a
|
||||
# single bad/missing package can't deprive the shell of everything else.
|
||||
# shellcheck disable=SC2086
|
||||
if ! apt-get install -y --no-install-recommends $PKGS; then
|
||||
for p in $PKGS; do
|
||||
apt-get install -y --no-install-recommends "$p" || true
|
||||
done
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$SENTINEL")"
|
||||
date -u +%FT%TZ > "$SENTINEL" # mark done; skip on the next provision pass
|
||||
Reference in New Issue
Block a user