banger/CHANGELOG.md
Thales Maciel ae3466b944
release: prep v0.1.10 changelog
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:08:48 -03:00

15 KiB
Raw Blame History

Changelog

All notable changes to banger are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

The version line printed by banger version is the canonical reference for what's installed; this file is the canonical reference for what changed between versions.

Unreleased

v0.1.10 - 2026-05-03

Added

  • README now includes an animated demo GIF showing the typical sandbox lifecycle (vm run, host-side ssh demo.vm, stop/start with file persistence, vm exec, curl http://demo.vm). The recording script lives at assets/demo.tape and is rendered with VHS.

v0.1.9 - 2026-05-01

Fixed

  • vm exec no longer falls back to cd /root/repo on VMs that have no recorded workspace. Previously, running vm exec against a plain VM (one that never had vm workspace prepare / vm run ./repo) blew up with cd: /root/repo: No such file or directory — surfaced via the login shell's mise activate hook because bash -lc sources profile.d before the explicit cd. Now the auto-cd only fires when the user passes --guest-path or the VM actually has a workspace recorded; otherwise the command runs from root's home. Mise wrapping is unchanged — without a .mise.toml it's a no-op.

Changed

  • vm exec --guest-path default in --help now reads "from last workspace prepare; otherwise root's home" (was "or /root/repo"). Anyone who relied on the implicit /root/repo default for a VM that has a repo there but no workspace record must now pass --guest-path /root/repo explicitly.

Notes

  • Internal: smoke-test harness ported from scripts/smoke.sh to a Go test suite under internal/smoketest. make smoke is unchanged for maintainers; no user-visible effect.

v0.1.8 - 2026-05-01

Fixed

  • <vm>.vm resolution from the host (NSS path: curl, ssh hostname, etc.) now works on systemd-resolved hosts. The root helper's validateResolverAddr was rejecting the host:port form (127.0.0.1:42069) that banger constructs to point resolved at the in-process DNS server, so the auto-wire silently failed at every daemon startup. dig @127.0.0.1 worked because that bypasses NSS; any tool going through glibc's resolver chain didn't.
  • Validator now accepts both bare IPs and IP:port (matching what resolvectl dns itself accepts) with new test coverage for the port'd form.

Notes

  • Existing v0.1.x installs that already booted with the broken validator have stale per-link resolved state. After updating to v0.1.8, run sudo banger system restart once to re-trigger the auto-wire, or restart the host. systemd-resolved restarts also wipe per-link state — banger restores it on its own daemon startup but won't re-run for an already-running daemon.

v0.1.7 - 2026-05-01

Added

  • vm run -d / --detach creates the VM, runs workspace prep + tooling bootstrap, then exits without attaching to ssh. Reconnect later with banger vm ssh <name>. The combos -d --rm and -d -- <cmd> are rejected before VM creation.
  • vm run --no-bootstrap skips the mise tooling install entirely; useful when a workspace has a .mise.toml you don't want banger to act on.
  • banger doctor --verbose / -v prints every check with details. Without it, doctor's default output now collapses (see Changed).

Changed

  • vm run refuses early when bootstrap can't succeed. Previously, a workspace containing .mise.toml or .tool-versions without --nat set silently failed the bootstrap into a log file and dropped you into ssh with tools missing. It now refuses before VM creation with tooling bootstrap requires --nat (or pass --no-bootstrap to skip). Existing scripts that relied on the silent-failure path will need to add --nat or --no-bootstrap.
  • banger doctor default output is now compact. A healthy host collapses to a single line (all N checks passed); failing or warning checks print only the affected entries plus a summary footer (N passed, M warnings, K failures). Pass --verbose for the full per-check output. Anything parsing the previous always-verbose output needs to switch to doctor --verbose.

Fixed

  • The detached bootstrap path runs synchronously (foreground, tee'd to the existing log file) so the CLI only returns once installs finish. Interactive mode keeps today's nohup'd background behaviour so the ssh session starts promptly.

v0.1.6 - 2026-04-29

Fixed

  • v0.1.4's "running VMs survive daemon restart" fix was incomplete: the binary-level reconcile path was correct, but /run/banger (the daemon's runtime dir) was being wiped on every daemon stop because systemd defaults to RuntimeDirectoryPreserve=no. The api-sock symlinks the helper had created for live VMs vanished with it, and findByJailerPidfile couldn't resolve them to find the chroot
    • pidfile. v0.1.6 sets RuntimeDirectoryPreserve=yes on both unit templates so the symlinks (and helper RPC sock) survive the restart window. Live-verified: FC PID and guest boot_id both unchanged across a full helper+daemon restart cycle with a VM running.
  • v0.1.4's CHANGELOG correction stands: existing v0.1.x installs (where x < 6) need a one-time sudo banger system install after updating to v0.1.6 to pick up both the new KillMode=process and the new RuntimeDirectoryPreserve=yes directives. banger update swaps binaries, not unit files.

v0.1.5 - 2026-04-29

No functional changes. Verification release for v0.1.4: the previous release shipped the running-VMs-survive-update fix, but updating to v0.1.4 from v0.1.3 used v0.1.3's buggy driver, so the fix couldn't be verified live in that direction. v0.1.5 exists so a host on v0.1.4 can update to it and observe a running VM survive end-to-end with v0.1.4 in the driver seat.

v0.1.4 - 2026-04-29

Fixed

  • Daemon restarts no longer kill running VMs. Two changes together:
    • The bangerd-root.service and bangerd.service unit templates now set KillMode=process. The default (control-group) sent SIGKILL to every process in the unit's cgroup on stop/restart, including the jailer-spawned firecracker children — fork/exec doesn't escape a systemd cgroup. With KillMode=process only the unit's main PID is signalled; firecracker children survive.
    • fcproc.FindPID now also looks up jailer'd firecracker processes via the pidfile jailer writes at <chroot>/firecracker.pid (sibling of the api-sock target). Previously the only lookup path was pgrep -n -f <api-sock>, which can't see jailer'd processes because their cmdline only carries the chroot-relative --api-sock /firecracker.socket. Reconcile after a daemon restart now correctly re-attaches to surviving guests instead of mistaking them for stale and tearing down their dm-snapshot.

Notes

  • v0.1.0's CHANGELOG line "daemon restarts do not interrupt running guests" was wrong: it was true at the systemd cgroup layer in theory but the default KillMode defeated it, and even with KillMode=process the daemon's reconcile would mistake surviving FCs for stale and tear them down. v0.1.4 is the version where this actually works end-to-end.
  • Updating from v0.1.0v0.1.3 to v0.1.4 still kills running VMs because the driver of the update is the buggy older binary. Updates from v0.1.4 onward preserve running VMs across the helper+daemon restart that banger update performs.
  • Existing v0.1.0v0.1.3 installs that update to v0.1.4 do NOT automatically pick up the new unit files — banger update swaps binaries, not systemd units. Run sudo banger system install once on those hosts after updating to refresh the units. New v0.1.4+ installs get the correct units from the start.

v0.1.3 - 2026-04-29

No functional changes. Verification release: v0.1.2 fixed banger update's install.toml handling, but the fix only takes effect when v0.1.2 (or later) is the driver of an update. v0.1.3 exists so a host running v0.1.2 can update to it and confirm the fix works end-to-end with the new code in the driver seat.

v0.1.2 - 2026-04-29

Fixed

  • banger update now writes the freshly-installed binary's commit and built_at fields to /etc/banger/install.toml, not the running CLI's. Previously install.toml's version was correct after an update but commit + built_at still pointed at the pre-update binary's identity, which made banger doctor raise a false-positive "CLI/install drift" warning on every update. Caught by the v0.1.0 → v0.1.1 live update smoke-test.

v0.1.1 - 2026-04-29

Added

  • install.sh — one-command installer published at https://releases.thaloco.com/banger/install.sh. Runs as the invoking user, downloads + verifies the latest signed release with the embedded cosign public key, and re-execs sudo only for the actual system-install step. Pre-sudo summary explains in plain language why elevation is needed.
  • BANGER_INSTALL_NONINTERACTIVE=1 env var on install.sh for non-interactive use through curl | bash (CI, automated provisioning).

v0.1.0 - 2026-04-29

First public release. banger runs disposable development sandboxes as Firecracker microVMs: each sandbox boots in a few seconds, gets its own root filesystem and network, and exits on demand.

Added

Sandbox VMs

  • banger vm run boots a microVM, drops you into ssh, and tears it down on exit. Optional positional path ships a host repo into the guest; -- cmd args runs a command non-interactively and exits with its status.
  • Long-lived VMs via vm create / vm start / vm stop / vm restart / vm ssh / vm exec / vm logs / vm stats / vm ports / vm kill. vm list and ps enumerate state; vm prune deletes every non-running VM.
  • vm workspace ships a host repo into a guest and pulls diffs back.
  • Per-VM cgroup-isolated firecracker process under jailer chroot; daemon restarts do not interrupt running guests.

Images

  • banger image pull <name> pulls a curated rootfs+kernel bundle from the banger image catalog. image pull <oci-ref> pulls any OCI image.
  • image list / image show / image delete / image promote / image register round out the lifecycle.
  • image cache manages the OCI layer-blob cache.
  • Concurrent pulls of the same image are coalesced; the first pull wins, the rest wait.

Kernels

  • banger kernel pull <name> pulls a Firecracker-compatible kernel from the banger kernel catalog. kernel list / kernel show / kernel rm manage the local store.

Host networking

  • Per-host bridge with NAT; per-VM tap device; deterministic IPv4 assignment; iptables rules installed/removed with VM lifecycle.
  • DNS routing: local resolver on 127.0.0.1:42069 answers queries for <vm>.vm so plain ssh <vm>.vm reaches the guest.
  • banger ssh-config writes a one-time ~/.ssh/config include so ssh, scp, and rsync resolve <vm>.vm from any terminal.

System install

  • sudo banger system install installs an owner-mode daemon (bangerd.service) and a root-helper (bangerd-root.service) as systemd units. The owner daemon runs as the invoking user; only the root helper holds privilege, and only for a vetted set of operations.
  • system status / system restart / system uninstall round out the lifecycle. daemon is a thin alias.
  • banger doctor audits host readiness: architecture, CLI/install version drift, state store, host runtime, vm lifecycle prerequisites, vsock guest agent, vm defaults, ssh shortcut, /root work disk, DNS, NAT, firecracker binary version, systemd units, socket permissions, helper unit hardening directives.

Self-update

  • banger update downloads, verifies, and installs newer releases from the public manifest. Flow: fetch manifest, refuse if any VM operation is in flight, download tarball + SHA256SUMS + SHA256SUMS.sig, verify the cosign signature against the embedded public key, verify the tarball hash, stage to a scratch dir, run bangerd --check-migrations against the staged binary, atomically swap the three banger binaries, restart the systemd units, run banger doctor, finalise the install record.
  • Pre-restart abort and post-restart auto-rollback both restore the previous install on failure.
  • banger update --check reports whether a newer release is available without applying it; --to vX.Y.Z pins a specific version; --dry-run prints the plan; --force skips the in-flight-op refusal.

Trust model

  • Every release is cosign-signed. The public key is embedded in the banger binary at build time; the signed payload is SHA256SUMS, which in turn covers the release tarball. Verification uses the Go standard library (crypto/ecdsa.VerifyASN1); cosign is needed only for signing, not for verification.
  • The release manifest URL is hardcoded into the binary so a compromised daemon config cannot redirect the updater to a different bucket.

CLI surface

  • Top-level: vm, ps, image, kernel, ssh-config, system, daemon, doctor, update, version, completion.
  • banger version reports the version, commit SHA, and build timestamp baked in via ldflags at release-build time.

Compatibility

  • The host-side and guest-side vsock agent protocol is informally stable across patch versions (v0.1.x). Minor-version bumps (v0.2.x) may change it; existing VMs created against an older minor will need to be re-pulled. banger doctor warns when a running VM's agent is older than the daemon expects but does not block lifecycle operations.
  • The on-disk store schema is forward-only. Downgrading the binary against a database written by a newer binary is unsupported; the updater detects this via bangerd --check-migrations and refuses the swap rather than starting up against an incompatible store.
  • Linux only. amd64 only. KVM required.