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.
247 lines
5 KiB
Markdown
247 lines
5 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>`, and then runs `opencode attach` from the host against 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.
|