Commit graph

49 commits

Author SHA1 Message Date
7b7f7e676c
Harden VM stop cleanup for stale snapshots
Stop and delete could fail with device-mapper busy errors when the persisted Firecracker PID was stale or the kernel needed longer to release the root snapshot.

Rediscover a live Firecracker process by API socket during cleanup, kill and wait on that PID instead of trusting only the stored runtime PID, and extend dm snapshot removal retries for transient busy handles.

Add daemon regressions for stale-runtime reconcile, rediscovered process cleanup, and repeated busy dm removal. Validate with go test ./..., make build, and a live ./banger vm stop debug-ssh run that now exits cleanly.
2026-03-18 12:28:15 -03:00
787b234029
Fix VM startup regressions after shell-out cleanup
The shell-out reduction pass introduced two linked startup regressions in the hot path for vm create.

Make flattenNestedWorkHome repair the temporary nested /root tree without trying to read a root-owned 0700 directory as the calling user: chmod the scratch directory under sudo, then copy each child entry individually before removing it. Add a regression test for that overlap/permission case.

Restore the Firecracker launch wrapper that sets umask 000 before exec. Firecracker was creating the API socket, but the SDK could not use it during machine.Start after the direct sudo launch, so vm create timed out waiting on a socket that already existed.

Validated with go test ./... and make build.
2026-03-18 12:18:34 -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
60294e8c90
Fix VM lifecycle issues behind verify.sh
Make the Firecracker and bangerd processes outlive short-lived CLI request contexts so vm create no longer kills the VMM or daemon as soon as the RPC returns.

Fix fresh-VM SSH by flattening the seeded /root work disk when the copied home tree lands under a nested root/ directory, and write a guest sshd override to keep root pubkey auth explicit while debugging.

Harden teardown and smoke diagnostics: verify.sh now reports early Firecracker exit and delete failures directly, while dm snapshot cleanup tolerates already-gone handles and retries busy mapper removal long enough for Firecracker to release the device.

Validation: go test ./..., make build, bash -n verify.sh, direct SSH against a fresh VM, and a live ./verify.sh run that now completes with [verify] ok.
2026-03-17 14:43:09 -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
ccba07ec68
Propagate RPC cancellation to daemon requests
Stop long-running daemon operations from running under context.Background by\nthreading a request-scoped context from handleConn into dispatch. The daemon\nnow cancels in-flight handlers when the client socket goes away, and the RPC\nclient closes its Unix connection when the caller context is canceled so that\ninterrupts actually reach the daemon boundary.\n\nAdd regression coverage for both sides of the path: canceled dispatch calls,\nclient disconnects during handleConn, watcher EOF cancellation, and context\ncancellation without an RPC deadline.\n\nValidated with GOCACHE=/tmp/banger-gocache go test ./... and\nGOCACHE=/tmp/banger-gocache make build.
2026-03-16 18:28:33 -03:00
ebb68c3126 Reconcile stale default image on startup
Upgrades from the pre-bundle layout can leave the unmanaged default image pointing at repo-root artifacts that no longer exist, causing vm start preflight to fail forever. Treat the default image as reconcilable state instead of bailing out when a record exists.

Compute the desired default image from current runtime/config defaults, update an existing unmanaged default in place when its paths diverge, keep managed defaults untouched, and preserve the original ID so existing VMs keep referencing it. Added regression tests covering creation, no-op, reconciliation, managed-image skip, and missing-artifact behavior.
2026-03-16 16:45:54 -03:00
6e00fa690d Reject invalid VM CPU and memory values
VM create and vm set accepted zero or negative CPU and memory values, which either got stored directly or silently fell back to defaults and only surfaced as failures later. This tightens validation so bad settings are rejected at the user boundary and again in the daemon before any VM record is persisted.

Change vm.create CPU and memory request fields to optional pointers so omitted values still mean defaults, while explicit non-positive values can be distinguished and rejected. Update Cobra create/set parsing, keep the TUI aligned with the new API shape, and add regression tests for CLI parsing, daemon-side validation, and the create-defaults path.

Validation: go test ./... and make build. Left my-rootfs.ext4 untracked.
2026-03-16 16:28:17 -03:00
67cfdd659f Remove legacy shell VM entrypoints
The repository had already moved VM lifecycle management onto the Go daemon, CLI, and TUI, but the old shell entrypoints were still sitting in the tree as a second surface for the same operations. Keeping both made the repo harder to understand and invited drift between the supported workflow and the leftover scripts.

Remove the redundant shell commands for run, stop, kill, rm, list, logs, restore, ssh, and ps. This commit only drops the obsolete entrypoints; the Go replacements and supporting docs were handled in earlier work.
2026-03-16 16:21:31 -03:00
67e531aa27 Add VM kill RPC parameters
The Go control plane already exposed banger vm kill and daemon-side kill handling, but the API package was missing the VMKillParams request type. That left the worktree depending on an unstaged type addition even though the rest of the feature was already wired.

Add the missing request struct so the CLI, RPC layer, and daemon share an explicit payload for signal-based VM termination. This commit is intentionally narrow because the rest of the kill-path work was already present.
2026-03-16 16:21:05 -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
5018bc6170
Add regression coverage for VM failure paths
Dangerous lifecycle, store, system, and RPC paths still had little or no automated confidence, and the live smoke harness failed opaquely when guest boot timing drifted. This adds targeted unit coverage for store allocation and decode failures, system helper failure ordering and cleanup, RPC error handling, and daemon lookup/reconcile/editing/stats/preflight edge cases.

It also makes verify.sh wait for daemon-observable VM readiness before SSH, reuse a bounded boot deadline for the SSH phase, and dump VM metadata, logs, tap state, socket state, and NAT rules on timeout so host-level failures are diagnosable instead of surfacing only connection refused.

Validation: go test ./..., go test ./... -cover, bash -n verify.sh. No live ./verify.sh boot was run in this environment.
2026-03-16 15:46:54 -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
ce1be52047
Make installed banger self-contained
Fix the misleading make install path where banger and bangerd still depended on a repo checkout for Firecracker, guest artifacts, image builds, and the SSH key.

Replace repo-root inference with an explicit runtime bundle model: resolve a runtime_dir from env/config/install layout, derive concrete artifact paths from it, and update the daemon, CLI, and image-build flow to use those paths. Keep repo_root only as an explicit compatibility alias instead of auto-detecting it.

Teach customize.sh to run from a read-only bundled runtime tree while writing transient state under XDG/BANGER_STATE_DIR, and make make install copy the runtime assets into PREFIX/lib/banger so installed binaries stay usable outside the repo.

Validate with go test ./..., make build, bash -n customize.sh, and make install DESTDIR=/tmp/banger-install PREFIX=/usr. An out-of-repo installed-binary smoke test was attempted, but this sandbox blocked bangerd from binding its Unix socket (setsockopt: operation not permitted).
2026-03-16 14:26:50 -03:00
375900cf65
Rollback partial dm snapshot startup
Prevent partial VM startup failures from leaking loop devices and dm state on the host.

Move root snapshot setup into a rollback-safe helper that records loop and mapper handles incrementally, tears them down in reverse order on failure, and reuses the same dm/loop cleanup path during normal runtime teardown. Also switch the daemon runner field to a small command-runner interface so the snapshot path can be tested with injected failures.

Add failure-injection coverage for losetup, blockdev, dmsetup, partial teardown, and joined rollback errors. Validated with go test ./... and make build.
2026-03-16 14:06:17 -03:00
171009b30b
Manage NAT directly from VM records
Fix the Go control plane NAT path now that runtime state lives in the daemon instead of the old repo-local vm.json files.

Add a daemon-native NAT helper that derives uplink, guest IP, and TAP rules directly from VMRecord, applies the existing iptables/sysctl behavior idempotently, and removes the broken nat.sh handoff from vm.go.

Cover uplink parsing and rule generation with unit tests. Validated with go test ./... and make build; a live verify.sh --nat run installed host rules but stopped on the same guest SSH-readiness issue seen in the plain smoke test on this host.
2026-03-16 13:50:54 -03:00
2539800f5c
Use Firecracker SDK in daemon
Replace the daemon's hand-rolled Firecracker process/socket client with the official firecracker-go-sdk while keeping the existing VM lifecycle and host-side disk and TAP setup intact.

Build machine configs through the SDK, launch Firecracker through a sudo process runner, resolve the real VM PID after startup, and use the SDK client for Ctrl-Alt-Del instead of raw REST calls. Drop the unused cached Firecracker state and add focused adapter tests for config and process-runner wiring.

Validated with go mod tidy, go test ./..., and make build. A live KVM/Firecracker smoke boot was not run in this environment.
2026-03-16 13:26:41 -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
5f3d60ef0f Fix restore config parsing 2026-02-01 15:37:24 -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
f7e372d8db
Customize rootfs without home disk 2026-01-30 10:55:24 -03:00
092700b241
Use shared rootfs with per-VM home 2026-01-29 21:41:33 -03:00
dee329cf39
Add customize workflow 2026-01-29 19:29:13 -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
60b1865ece
Add logs helper 2026-01-29 15:33:27 -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
75f03aeb04
Add vm control scripts 2026-01-29 14:36:16 -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
5b1de19cf5
Add repo guidelines and verify script 2026-01-27 16:44:44 -03:00
dba2f327f5
lol 2026-01-26 18:05:54 -03:00
87a04e4076
ignore 2026-01-26 18:01:50 -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
f07b2da0af
Ignore transient VM artifacts
Prevent state directories, sockets, and scratch rootfs files from being tracked.
2026-01-21 19:09:21 -03:00
a0c298d9b0
Add Firecracker runtime artifacts
Store the microVM binary, kernel, rootfs, and SSH key so the local launcher can boot without external downloads.
2026-01-21 18:55:34 -03:00
50c851cf07
init 2026-01-21 18:45:45 -03:00