Bug: syncVMSSHClientConfig did os.RemoveAll on $ConfigDir/ssh every daemon Open. The intent was to migrate off the pre-opt-in layout, where banger used to write $ConfigDir/ssh/ssh_config. But a user who sets ssh_key_path = "~/.config/banger/ssh/id_ed25519" in config.toml has their key live exactly in that dir — and the scrub deletes it along with every other file in the tree. This is the same class of bug that cost the default key untilebe6517moved it to StateDir, but that fix was scoped to the default path. A configured ssh_key_path pointed under the legacy dir still dies. Fix: replace os.RemoveAll with a narrow two-step cleanup: 1. Skip the cleanup entirely when the configured ssh_key_path resolves under the legacy dir. A user who pointed banger at a key there must keep the enclosing directory. 2. Otherwise, os.Remove the specific legacy file ($ConfigDir/ssh/ ssh_config) and then os.Remove the directory. The second os.Remove fails with ENOTEMPTY if the dir still holds anything (e.g. a user-managed sibling file we don't own). Both errors are swallowed — this is best-effort migration, not a hard failure. Tests pin all three paths: user key under legacy dir survives, legacy dir empties and is removed when the user moved on, and a user-managed sibling file in the legacy dir is preserved. Also fix stale doc claims in README.md and AGENTS.md — both still pointed at the old ~/.config/banger/ssh/id_ed25519 default, which moved to ~/.local/state/banger/ssh/id_ed25519 inebe6517. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 KiB
4 KiB
Repository Guidelines
Always run make build before commit.
Project Structure
cmd/banger,cmd/bangerd, andcmd/banger-vsock-agentare the three binaries. The first two are user-facing; the third is a companion that ships inside each guest VM.internal/contains the daemon, CLI, RPC, storage, Firecracker integration, and guest helpers.internal/daemon/is the composition root; pure helpers live in its subpackages (opstate,dmsnap,fcproc,imagemgr,workspace). Seeinternal/daemon/ARCHITECTURE.md.internal/imagecat/andinternal/kernelcat/embed the image + kernel catalogs.images/golden/is the Dockerfile for thedebian-bookwormcatalog entry.scripts/contains manual helper workflows for rootfs, kernel, and bundle preparation.build/bin/is the canonical source-checkout build output.build/manual/is the canonical source-checkout location for manual rootfs/kernel artifacts.
Build and Test
make buildbuilds./build/bin/banger,./build/bin/bangerd, and./build/bin/banger-vsock-agent.make testrunsgo test ./....make lintrunsgofmt -l,go vet ./..., andshellcheck --severity=erroronscripts/*.sh. Run before commits../build/bin/banger doctorchecks host readiness../build/bin/banger vm runis the primary user-facing entry point — auto-pulls the default image + kernel from the catalogs if missing../build/bin/banger image pull <name>uses the bundle catalog (fast) when<name>is a catalog entry, or falls through to the OCI path for arbitrary registry refs. Seedocs/image-catalog.mdanddocs/oci-import.md../build/bin/banger image register ...registers an unmanaged host-side image stack../build/bin/banger image promote <image>copies an unmanaged image into daemon-owned managed artifacts.scripts/make-generic-kernel.shbuilds a Firecracker-optimized vmlinux from upstream sources.scripts/publish-kernel.sh <name>publishes it to the kernel catalog.scripts/publish-golden-image.shrebuilds + publishes the golden image bundle and patches the image catalog.
Image Model
- Managed images own the full boot set: rootfs, optional work-seed, kernel, optional initrd, and optional modules.
- The image catalog ships pre-built bundles.
vm runauto-pulls the default catalog entry;image pull <name>can be invoked explicitly. default_image_namedefaults todebian-bookworm. On miss, the daemon auto-pulls fromimagecatbefore surfacing "not found".- Kernel references follow the same auto-pull pattern against
kernelcat.
Config
- Config lives at
~/.config/banger/config.toml. - Firecracker comes from
PATHby default, orfirecracker_bin. - SSH uses
ssh_key_pathor an auto-managed default key at~/.local/state/banger/ssh/id_ed25519.
Coding Style
- Prefer small, direct Go code and standard library solutions.
- Keep shell scripts strict with
set -euo pipefail. - Use
gofmtfor Go formatting. - When a CLI accepts either an inline string or a file input, always prefer the file-based form.
- For shell commands and AI/LLM tooling, prefer passing files as input whenever the CLI allows it.
- Create temporary files as needed to follow the file-first rule.
- Examples: use
git commit -F <file>instead ofgit commit -m <message>, and use prompt files instead of inline prompt strings when invoking LLM CLIs.
Testing Guidance
- Primary automated coverage is
go test ./...(wired throughmake test). make coverageruns the suite with-coverpkg=./...and prints per-package averages plus a total;make coverage-htmlwrites a browsable report tocoverage.html;make coverage-totalprints just the total (for scripts/CI).- For lifecycle changes, smoke-test with
vm runend-to-end (covers create + start + boot + ssh). - If guest provisioning changes, document whether existing images must be rebuilt or recreated.
Security
- Do not commit secrets.
- VM workflows require
sudoand/dev/kvm. - The default SSH key is local configuration, not a checked-in runtime artifact.