banger/README.md
Thales Maciel 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

247 lines
5.3 KiB
Markdown

# banger
`banger` manages Firecracker development VMs with a local daemon, managed image artifacts, and a localhost web UI.
## Requirements
- Linux with `/dev/kvm`
- `sudo`
- Firecracker installed on `PATH`, or `firecracker_bin` set in config
- The usual host tools checked by `./build/bin/banger doctor`
`banger` now owns complete managed image sets. A managed image includes:
- `rootfs`
- optional `work-seed`
- `kernel`
- optional `initrd`
- optional `modules`
There is no runtime bundle anymore.
## Build
```bash
make build
```
This writes:
- `./build/bin/banger`
- `./build/bin/bangerd`
- `./build/bin/banger-vsock-agent`
## Install
```bash
make install
```
That installs:
- `banger`
- `bangerd`
- the `banger-vsock-agent` companion helper under `../lib/banger/`
## Config
Config lives at `~/.config/banger/config.toml`.
Supported keys:
- `log_level`
- `web_listen_addr`
- `firecracker_bin`
- `ssh_key_path`
- `default_image_name`
- `auto_stop_stale_after`
- `stats_poll_interval`
- `metrics_poll_interval`
- `bridge_name`
- `bridge_ip`
- `cidr`
- `tap_pool_size`
- `default_dns`
If `ssh_key_path` is unset, banger creates and uses:
- `~/.config/banger/ssh/id_ed25519`
`default_image_name` now only means “use this registered image when `vm create` omits `--image`”. The daemon does not auto-register images from host paths.
## Core Workflow
Check the host:
```bash
./build/bin/banger doctor
```
Register an existing host-side image stack:
```bash
./build/bin/banger image register \
--name base \
--rootfs /abs/path/rootfs.ext4 \
--kernel /abs/path/vmlinux \
--initrd /abs/path/initrd.img \
--modules /abs/path/modules
```
Build a managed image from an existing registered image:
```bash
./build/bin/banger image build \
--name devbox \
--from-image base \
--docker
```
Promote an unmanaged image into daemon-owned managed artifacts:
```bash
./build/bin/banger image promote base
```
Create and use a VM:
```bash
./build/bin/banger vm create --image devbox --name testbox
./build/bin/banger vm ssh testbox
./build/bin/banger vm stop testbox
```
`vm create` stays synchronous by default, but on a TTY it now shows live progress until the VM is fully ready.
Start a repo-backed VM session and attach `opencode` automatically:
```bash
./build/bin/banger vm run
./build/bin/banger vm run ../some-repo --branch feature/alpine --from HEAD
```
`vm run` resolves the enclosing git repository, creates a VM, copies a git checkout plus current tracked and untracked non-ignored files into `/root/<repo-name>`, starts a best-effort guest tooling harness that inspects the repo and installs clearly-needed tools with `mise`, and then prefers a host-side `opencode attach` session when the local client supports it. Older host opencode clients fall back to starting `opencode` inside the guest over SSH. The harness runs asynchronously and logs its output inside the guest.
## Web UI
`bangerd` serves a local web UI by default at:
- `http://127.0.0.1:7777`
See the effective URL with:
```bash
./build/bin/banger daemon status
```
Disable it with:
```toml
web_listen_addr = ""
```
## Guest Services
Provisioned images include:
- `banger-vsock-agent`
- guest networking bootstrap
- `mise`
- `opencode`
- a default guest `opencode` service on `0.0.0.0:4096`
If host `~/.local/share/opencode/auth.json` exists, `banger` syncs it into the guest at `/root/.local/share/opencode/auth.json` on VM start. Changes on the host take effect after the VM is restarted.
From the host:
```bash
./build/bin/banger vm ports testbox
opencode attach http://<guest-ip>:4096
```
## Manual Helpers
The shell helpers are now explicit manual workflows under `./build/manual`.
Rebuild a Debian-style manual rootfs:
```bash
make rootfs ARGS='--base-rootfs /abs/path/rootfs.ext4 --kernel /abs/path/vmlinux --initrd /abs/path/initrd.img --modules /abs/path/modules'
```
The output lands in:
- `./build/manual/rootfs-docker.ext4`
- `./build/manual/rootfs-docker.work-seed.ext4`
## Experimental Void Flow
Stage a Void kernel:
```bash
make void-kernel
```
Build the experimental Void rootfs:
```bash
make rootfs-void
```
Register it:
```bash
make void-register
```
That flow uses:
- `./build/manual/void-kernel/`
- `./build/manual/rootfs-void.ext4`
- `./build/manual/rootfs-void.work-seed.ext4`
## Experimental Alpine Flow
Stage an Alpine virt kernel:
```bash
make alpine-kernel
```
Build the experimental Alpine rootfs:
```bash
make rootfs-alpine
```
Register it:
```bash
make alpine-register
```
Create a VM from it:
```bash
./build/bin/banger vm create --image alpine --name alpine-dev
```
That flow uses:
- `./build/manual/alpine-kernel/`
- `./build/manual/rootfs-alpine.ext4`
- `./build/manual/rootfs-alpine.work-seed.ext4`
The experimental Alpine flow stages a pinned Alpine release by default. Override
that pin with `ALPINE_RELEASE=...` when running the `make alpine-kernel` and
`make rootfs-alpine` helpers if you need a different patch release.
Alpine support currently applies to the explicit register-and-run flow above.
The generic `banger image build --from-image ...` path remains Debian/systemd-
oriented and should not be treated as an Alpine image builder.
## Notes
- Firecracker is resolved from `PATH` by default.
- Managed image delete removes the daemon-owned artifact dir.
- The companion vsock helper is internal to the install/build layout, not a user-configured runtime path.