Commit graph

44 commits

Author SHA1 Message Date
88e633c6c4
Document vm run tooling bootstrap and attach fallback
Bring the vm run documentation back in line with the current behavior.

Explain that vm run now starts a best effort guest tooling harness,
prefers a host side opencode attach session when the local client
supports it, and falls back to guest opencode over SSH otherwise.
Also note that the harness runs asynchronously and logs inside the guest.
2026-03-29 17:52:42 -03:00
2ebc6f99c6
Add repo-backed vm run command
Create a CLI-only banger vm run [path] flow that resolves the enclosing git repository, creates a VM, imports a guest checkout, and launches opencode attach automatically from the host.

Build the guest checkout by bundling git history plus the resolved base and head commits, cloning that bundle in the guest, and overlaying tracked plus untracked non-ignored files over SSH so local working-tree changes carry over. Support guest-only branch creation with --branch and --from, reject bare repos and submodules, and add selective tar helpers plus CLI seams to keep the workflow testable.

Validate with go test ./..., make build, banger vm run --help, and the expected --from requires --branch error path.
2026-03-21 23:34:20 -03:00
8bcc767824
Sync host opencode auth into guest work disks
Refresh guest opencode auth from the host at VM start so guest opencode can reuse the local login without baking secrets into managed images.

Reuse the existing work-disk preparation path to copy ~/.local/share/opencode/auth.json into /root/.local/share/opencode/auth.json with mode 0600, and warn and skip when the host file is missing or unreadable so any existing guest auth stays in place.

Add daemon coverage for copy, replacement, and warn-and-skip cases, document the restart behavior in the README, and validate with go test ./... plus make build. Existing VMs pick the new auth up on their next restart.
2026-03-21 22:36:13 -03:00
a166068fab
Add an experimental Alpine image flow
Stage a complete Alpine x86_64 image stack so \	--image alpineworks like the existing manual Void path instead of relying on Debian-oriented image builds.\n\nAdd make targets plus kernel/rootfs/register helpers that download pinned Alpine artifacts, extract a Firecracker-compatible vmlinux, build a matching mkinitfs initramfs, seed OpenRC services, and register/promote a managed image named alpine.\n\nFold in the bring-up fixes discovered during boot validation: use rootfstype=ext4 in shared boot args, install libgcc/libstdc++ for the opencode binary, and give opencode more time to become ready on cold boots.\n\nValidate with go test ./..., the Alpine helper builds, image promotion, and banger vm create --image alpine --name alp --nat plus guest service and port checks.
2026-03-21 20:25:55 -03:00
572bf32424
Remove runtime-bundle image dependencies
Hard-cut banger away from source-checkout runtime bundles as an implicit source of\nimage and host defaults. Managed images now own their full boot set,\nimage build starts from an existing registered image, and daemon startup\nno longer synthesizes a default image from host paths.\n\nResolve Firecracker from PATH or firecracker_bin, make SSH keys config-owned\nwith an auto-managed XDG default, replace the external name generator and\npackage manifests with Go code, and keep the vsock helper as a companion\nbinary instead of a user-managed runtime asset.\n\nUpdate the manual scripts, web/CLI forms, config surface, and docs around\nthe new build/manual flow and explicit image registration semantics.\n\nValidation: GOCACHE=/tmp/banger-gocache go test ./..., bash -n scripts/*.sh,\nand make build.
2026-03-21 18:34:53 -03:00
01c7cb5e65
Reorganize the source checkout layout
Separate tracked source from generated artifacts so the repo root stops accumulating helper scripts, manifests, and local runtime outputs.

Move manual shell entrypoints under scripts/, manifests under config/, and the Firecracker API reference under docs/reference/. Make build and runtimebundle now target build/bin, build/runtime, and build/dist as the canonical source-checkout paths.

Update runtime discovery, helper scripts, tests, and docs to follow the new layout while keeping legacy source-checkout runtime fallbacks for existing local bundles during migration.

Validated with bash -n on the moved scripts, make build, and GOCACHE=/tmp/banger-gocache go test ./....
2026-03-21 17:22:57 -03:00
2362d0ae39
Serve a local web UI from bangerd
Add a localhost-only web console so VM and image management no longer depends on the CLI for every inspection and lifecycle action.

Wire bangerd up to a configurable web listener, expose dashboard and async image-build state through the daemon, and serve CSRF-protected HTML pages with host-path picking, VM/image detail views, logs, ports, and progress polling for long-running operations.

Keep the browser path aligned with the existing sudo and host-owned artifact model: surface sudo readiness, print the web URL in daemon status, and document the new workflow. Polish the UI with resource usage cards, clearer clickable affordances, cancel paths, confirmation prompts, image-name links, and HTTP port links.

Validation: GOCACHE=/tmp/banger-gocache go test ./...
2026-03-21 16:47:47 -03:00
30f0c0b54a
Manage image artifacts and show VM create progress
Stop relying on ad hoc rootfs handling by adding image promotion, managed work-seed fingerprint metadata, and lazy self-healing for older managed images after the first create.

Rebuild guest images with baked SSH access, a guest NIC bootstrap, and default opencode services, and add the staged Void kernel/initramfs/modules workflow so void-exp uses a matching Void boot stack.

Replace the opaque blocking vm.create RPC with a begin/status flow that prints live stages in the CLI while still waiting for vsock health and opencode on guest port 4096.

Validate with GOCACHE=/tmp/banger-gocache go test ./... and live void-exp create/delete smoke runs.
2026-03-21 14:48:01 -03:00
0c80d03081
Remove the banger TUI
Hard cut the terminal UI so the supported management surface is the daemon-backed CLI only.

Drop the tui subcommand, delete the Bubble Tea implementation and its tests, and keep a regression check that the legacy command is rejected.
Prune the Charmbracelet dependencies with go mod tidy and remove the stale README and AGENTS references.

Validated with go test ./... and GOCACHE=/tmp/banger-gocache go test ./internal/cli.
2026-03-19 22:56:16 -03:00
7667249b47
Install opencode in Void rootfs
Bring the experimental Void image closer to the default dev image path by installing pinned mise inside the rootfs build, using it to install opencode, and activating mise automatically for root bash sessions.

Keep the change scoped to the Void builder rather than packages.void so the image still stays language-agnostic at the package-manifest level, then clean mise download/cache artifacts before sealing the rootfs and work-seed.

Extend verify-void so the smoke path now proves mise and opencode are actually present in a fresh void-exp VM. Verified with bash -n make-rootfs-void.sh verify.sh, GOCACHE=/tmp/banger-gocache go test ./..., and make build.
2026-03-19 19:04:57 -03:00
3096de0a7f
Refine vm ports output
Make banger vm ports single-target and collapse the old VM/WEB table shape into a simpler PROTO ENDPOINT PROCESS COMMAND view. Web listeners now surface directly as http or https, with clickable endpoints in the main endpoint column instead of a separate URL field.

Classify TCP listeners with HTTPS-first probing so TLS services are not mislabeled as plain HTTP just because they answer bad cleartext requests with an HTTP error, then dedupe rows by rendered PROTO+ENDPOINT so dual-stack binds like 0.0.0.0 and :: only show once.

Update the CLI/daemon regressions and README to match the new contract. Verified with GOCACHE=/tmp/banger-gocache go test ./..., make build, git diff --check, and ./banger vm ports --help.
2026-03-19 18:21:04 -03:00
5ad3b505dd
Install Docker in experimental Void images
Make the local-only void-exp rootfs useful as a dev VM baseline by baking Docker and Compose into the XBPS package set instead of leaving container setup to manual follow-up.

Enable the docker runit service during image assembly, add a small boot preflight that loads the needed netfilter/overlay modules and applies the Docker sysctl file before dockerd starts, and keep the Void cleanup path removing caches, docs, and stale get-docker artifacts.

Refresh the README and repo guidance to describe Docker as part of the current Void image contract and to remind users that they need to rebuild and recreate Void VMs to pick it up.

Verified with bash -n make-rootfs-void.sh and git diff --check for the touched files. I did not run a live make rootfs-void or boot a fresh Void VM in this pass.
2026-03-19 15:52:30 -03:00
c298ed2fc1
Add vsock-backed VM port inspection
Let the host ask the guest vsock agent to run ss so open ports can be surfaced without SSHing in manually.

Add a narrow /ports agent endpoint, a daemon vm.ports RPC that enriches listeners with <hostname>.vm endpoints and best-effort HTTP links, and a concurrent 'banger vm ports' CLI table for one or more VMs.

Update the guest package contract to include ss for rebuilt Debian images, allow the guest agent package in the shell-out policy, and cover the new parsing/RPC/CLI flow in tests.

Verified with GOCACHE=/tmp/banger-gocache go test ./... outside the sandbox, make build, bash -n customize.sh make-rootfs-void.sh verify.sh, and ./banger vm ports --help.
2026-03-19 15:52:11 -03:00
3ed78fdcfc
Add experimental Void guest workflow and vsock agent
Make iterating on a Firecracker-friendly Void guest practical without replacing the Debian default image path.

Add local Void rootfs build/register/verify plumbing, a language-agnostic dev package baseline, and guest SSH/work-disk hardening so new images use the runtime bundle key, keep a normal root bash environment, and repair stale nested /root layouts on restart.

Replace the guest PING/PONG responder with an HTTP /healthz agent over vsock, rename the runtime bundle and config surface from ping helper to agent while still accepting the legacy keys, and route the post-SSH reminder through the new vm.health path.

Validated with GOCACHE=/tmp/banger-gocache go test ./..., make build, bash -n customize.sh make-rootfs-void.sh, and git diff --check.
2026-03-19 14:51:25 -03:00
c8d9a122f9
Speed up VM create with work seeds
Beat VM create wall time without changing VM semantics.

Generate a work-seed ext4 sidecar during image builds and rootfs rebuilds, then clone and resize that seed for each new VM instead of rebuilding /root from scratch. Plumb the new seed artifact through config, runtime metadata, store state, runtime-bundle defaults, doctor checks, and default-image reconciliation so older images still fall back cleanly.

Add a daemon TAP pool to keep idle bridge-attached devices warm, expose stage timing in lifecycle logs, add a create/SSH benchmark script plus Make target, and teach verify.sh that tap-pool-* devices are reusable capacity rather than cleanup leaks.

Validated with go test ./..., make build, ./verify.sh, and make bench-create ARGS="--runs 2".
2026-03-18 21:22:12 -03:00
08ef706e3f
Add vsock-backed SSH session reminders
Remind users when a VM is still running after 	hanger vm ssh exits instead of silently dropping them back to the host shell.\n\nAttach a Firecracker vsock device to each VM, persist the host vsock path/CID,\nadd a new guest-side banger-vsock-pingd responder to the runtime bundle and both\nimage-build paths, and expose a vm.ping RPC that the CLI and TUI call after SSH\nreturns. Doctor and start/build preflight now validate the helper plus\n/dev/vhost-vsock so the feature fails early and clearly.\n\nValidated with go mod tidy, bash -n customize.sh, git diff --check, make build,\nand GOCACHE=/tmp/banger-gocache go test ./... outside the sandbox because the\ndaemon tests need real Unix/UDP sockets. Rebuild the image/rootfs used for new\nVMs so the guest ping service is present.
2026-03-18 20:14:51 -03:00
4930d82cb9
Refactor VM lifecycle around capabilities
Make host-integrated VM features fit a standard Go extension path instead of adding more one-off branches through vm.go. This is the enabling refactor for future work like shared mounts, not the /work feature itself.

Add a daemon capability pipeline plus a structured guest-config builder, then move the existing /root work-disk mount, built-in DNS, and NAT wiring onto those hooks. Generalize Firecracker drive config at the same time so later storage features can extend machine setup without another hardcoded path.

Add banger doctor on top of the shared readiness checks, update the docs to describe the new architecture, and cover the new seams with guest-config, capability, report, CLI, and full go test verification. Also verify make build and a real ./banger doctor run on the host.
2026-03-18 19:28:26 -03:00
38d7eac430
Add tmux resurrect defaults to rebuilt images
New VMs should come up with tmux session persistence ready instead of requiring per-VM plugin setup, and rebuilt images should stop carrying stale Docker installer scraps.

Configure both image build paths to install TPM, tmux-resurrect, and tmux-continuum for root, manage a marked /root/.tmux.conf block with autosave enabled and restore left manual, and remove legacy get-docker helper files during provisioning.

Update the README and repo guidance to document the rebuilt-image behavior. Verified with bash -n customize.sh, GOCACHE=/tmp/banger-gocache go test ./internal/daemon -run TestBuildProvisionScriptInstallsDefaultTools, and GOCACHE=/tmp/banger-gocache make build.
2026-03-18 17:44:12 -03:00
8ba920eda6
Refresh docs for current VM workflows
Keep the user-facing docs aligned with the current Go control plane instead of the older one-VM-at-a-time and ambiguous rootfs rebuild flows.

Document concurrent multi-VM lifecycle and set commands, clarify that rebuilt images now include mise plus opencode, and spell out when make rootfs needs an explicit base image. Also update the repo guidelines so future changes keep those behaviors documented.
2026-03-18 14:23:22 -03:00
942d242c03
Move avoidable daemon shell-outs into Go
Reduce the control plane's dependency on helper scripts while keeping the hard Linux integration points in the approved shell-out layer.

Replace the bash-driven image build path with a native Go builder that clones and optionally resizes the rootfs, boots a temporary Firecracker VM, provisions the guest over SSH, installs packages and modules, and preserves the package-manifest sidecar.

Also replace a few small convenience shell-outs with Go helpers: read process stats from /proc, use os.Truncate for ext4 image growth, add file-clone and normalized-line helpers, drop the sh -c work-disk flattening path, and launch Firecracker via a direct sudo command.

Add tests for the new SSH/archive and system helpers, plus a policy test that keeps os/exec imports confined to cli/firecracker/system. Update the docs to describe customize.sh as a manual helper rather than the daemon's image-build backend.

Validated with go mod tidy, go test ./..., and make build.
2026-03-17 17:13:07 -03:00
0a0b0b617b
Replace mapdns with daemon DNS
Serve daemon-managed .vm names directly from bangerd on 127.0.0.1:42069 instead of shelling out to mapdns. This keeps DNS state tied to VM lifecycle and lets the daemon rebuild records from running VMs after startup or reconcile.

Add a small in-process authoritative DNS server, register and remove records from the VM start/stop/delete paths, and show the listener in daemon status. Remove the mapdns config and preflight surface, stop helper-flow DNS publishing in customize.sh and interactive.sh, drop dns.sh from the runtime bundle, and update docs/tests for the new local-resolver integration model.

Validated with GOCACHE=/tmp/banger-gocache go test ./..., GOCACHE=/tmp/banger-gocache make build, and bash -n customize.sh interactive.sh.
2026-03-17 15:49:35 -03:00
430f66d5dd Move helper NAT management into Go
Remove the last shell-owned NAT surface by extracting the iptables logic into a shared Go package and using it from both bangerd and a hidden helper bridge in the CLI.

Route customize.sh and interactive.sh through banger internal nat up/down so the remaining shell helpers reuse the same rule logic, resolve the local banger binary explicitly, and tear NAT back down during cleanup.

Drop nat.sh from the runtime bundle and docs now that NAT is Go-managed everywhere, and keep coverage aligned with the new shared package and helper command.

Validation: go test ./..., bash -n customize.sh interactive.sh verify.sh, make build, and a live ./verify.sh --nat run that installed host rules, reached outbound network access, and cleaned them up successfully.
2026-03-17 15:07:49 -03:00
617f677c9b
Clarify local runtime bundle bootstrap
Stop presenting make runtime-bundle as a turnkey fresh-checkout bootstrap\nwhen the checked-in manifest is intentionally empty. The manifest comments,\nruntimebundle error messages, Make help, README, and AGENTS docs now all\ndescribe the same local-first flow: stage an archive, use a separate local\nmanifest copy with url/sha256, then bootstrap ./runtime from that manifest.\n\nKeep the existing package/fetch commands intact, and add a small runtimebundle\nregression test so the local-manifest guidance does not drift again.\n\nValidated with make help and GOCACHE=/tmp/banger-gocache go test\n./internal/runtimebundle.
2026-03-16 18:28:40 -03:00
644e60d739
Add structured daemon lifecycle logs
VM start, image build, and network/setup failures were hard to diagnose because bangerd emitted almost no lifecycle logs and the Firecracker SDK logger was discarded. This adds a daemon-wide JSON logger with configurable log level so failures leave breadcrumbs instead of only side effects.

Log the main daemon and VM lifecycle stages, preserve raw Firecracker and image-build helper output in dedicated files, and include those log paths in daemon status and returned errors. Bridge SDK logrus output into the daemon logger at debug level so low-level Firecracker diagnostics are available without making normal info logs unreadable.

Validation: go test ./... and make build. Left unrelated worktree changes out of this commit, including internal/api/types.go, the deleted shell scripts, and my-rootfs.ext4.
2026-03-16 16:16:28 -03:00
fcedacba5c
Make runtime defaults portable
Stop assuming one workstation layout for runtime artifacts, mapdns, and host tooling. The daemon and shell helpers now use portable mapdns configuration, and runtime bundles can carry bundle.json metadata for their default kernel, initrd, modules, rootfs, and helper paths.

Load bundle metadata through config with a legacy layout fallback, thread mapdns_bin/mapdns_data_file through the Go and shell paths, and add command-scoped preflight checks for VM start, NAT, image build, work-disk resize, and SSH so missing tools or artifacts fail with actionable errors.

Update the runtime-bundle manifest, docs, and tests to match the new model. Verified with go test ./..., make build, and bash -n customize.sh interactive.sh dns.sh make-rootfs.sh verify.sh.
2026-03-16 15:30:08 -03:00
238bb8a020
Switch to fetched runtime bundles
Stop treating Firecracker, kernels, modules, and guest images as tracked source files. Source checkouts now resolve runtime assets from ./runtime, while installed binaries keep using ../lib/banger.

Add a small runtimebundle helper plus runtime-bundle.toml so make can bootstrap, package, and install a runtime bundle with checksum validation. Update the shell helpers and daemon path hints to fail clearly when the bundle is missing instead of assuming repo-root artifacts.

This removes the tracked runtime blobs from HEAD in favor of an ignored local runtime/ tree. Verified with go test ./..., make build, bash -n on the shell helpers, make -n install, and a temporary package/fetch smoke test. The manifest URL/SHA still need a published bundle before fresh clones can bootstrap, and history rewrite remains a separate rollout step.
2026-03-16 15:05:10 -03:00
ea72ea26fe
Add Go daemon-driven VM control plane
Replace the shell-only user workflow with `banger` and `bangerd`: Cobra commands, XDG/SQLite-backed state, managed VM and image lifecycle, and a Bubble Tea TUI for browsing and operating VMs.\n\nKeep Firecracker orchestration behind the daemon so VM specs become persistent objects, and add repo entrypoints for building, installing, and documenting the new flow while still delegating rootfs customization to the existing shell tooling.\n\nHarden the control plane around real usage by reclaiming Firecracker API sockets for the user, restarting stale daemons after rebuilds, and returning the correct `vm.create` payload so the CLI and TUI creation flow work reliably.\n\nValidation: `go test ./...`, `make build`, and a host-side smoke test with `./banger vm create --name codex-smoke`.
2026-03-16 12:52:54 -03:00
3cf33d1e0a
Streamline VM overlays and rootfs packages
Move the default guest package list into a repo manifest and record a hash beside built rootfs images so run/make-rootfs can warn when the docker-ready image is stale.

Switch the Firecracker launch path to a single sparse root overlay per VM instead of separate /home and /var disks, so many VMs can share the same base image while still installing packages under /var and working from /root.

Keep older images bootable by masking stale home.mount and var.mount units at boot, and scrub those obsolete fstab entries when customize.sh rebuilds an image. Verified with bash -n on the updated scripts; no live VM boot was run in this environment.
2026-03-15 19:36:54 -03:00
9191b7e370
Improve VM lifecycle tooling
Make spawned VMs easier to use and restore from the host.

Add shared DNS and runtime helpers, publish <vm-name>.vm records through mapdns, and teach run/customize/interactive/restore to persist the metadata needed for SSH, DNS cleanup, and clean restores.

Seed per-VM /home and /var disks from the rootfs snapshot so package state is present on first boot, add an interactive customization entrypoint plus ssh.sh and human-friendly list output, and let stop/kill/rm operate on multiple VM identifiers.

Tear down stale TAP, dm, and loop state when VMs stop so restore can recreate them safely, and validate the updated scripts with bash -n plus targeted dry-run harnesses for teardown and restore paths.
2026-03-15 17:48:47 -03:00
a8078f2393 customize base rootfs arg 2026-02-05 14:37:03 -03:00
01517dd902 document kernel artifacts 2026-02-05 13:50:11 -03:00
93c3d1a67b docker rootfs defaults 2026-02-05 02:13:14 -03:00
7af04b7535
Store VM metadata as JSON 2026-01-31 23:17:12 -03:00
bbd57d8dd2
Use hostname-safe VM names 2026-01-30 12:13:35 -03:00
306412c995
Add rootfs/kernel overrides 2026-01-30 11:08:10 -03:00
092700b241
Use shared rootfs with per-VM home 2026-01-29 21:41:33 -03:00
e10a51558e
Harden kill script and DNS config 2026-01-29 16:49:54 -03:00
68cf5f2cbb
Add per-VM NAT and DNS config 2026-01-29 16:22:28 -03:00
68a223c463
Store API sockets in runtime dir 2026-01-29 14:59:57 -03:00
f8e7aedeb2
Move VM dirs under state/vms 2026-01-29 14:47:09 -03:00
6aa191663a
Rename vm_id field and add list helpers 2026-01-29 13:25:23 -03:00
eedc1fe1d8
Add runtime options and schema 2026-01-29 01:14:29 -03:00
e4039ca7e9
Add VM metadata and naming 2026-01-29 00:09:25 -03:00
33b7e2ea1a
Document expected log noise
Explain the benign PCI/SELinux log entries and ignore local log files in git.
2026-01-21 19:30:33 -03:00