daemon: split owner daemon from root helper
Move the supported systemd path to two services: an owner-user bangerd for orchestration and a narrow root helper for bridge/tap, NAT/resolver, dm/loop, and Firecracker ownership. This removes repeated sudo from daily vm and image flows without leaving the general daemon running as root. Add install metadata, system install/status/restart/uninstall commands, and a system-owned runtime layout. Keep user SSH/config material in the owner home, lock file_sync to the owner home, and move daemon known_hosts handling out of the old root-owned control path. Route privileged lifecycle steps through typed privilegedOps calls, harden the two systemd units, and rewrite smoke plus docs around the supported service model. Verified with make build, make test, make lint, and make smoke on the supported systemd host path.
This commit is contained in:
parent
3edd7c6de7
commit
59e48e830b
53 changed files with 3239 additions and 726 deletions
102
README.md
102
README.md
|
|
@ -5,7 +5,8 @@ One-command development sandboxes on Firecracker microVMs.
|
|||
## Quick start
|
||||
|
||||
```bash
|
||||
make install
|
||||
make build
|
||||
sudo ./build/bin/banger system install --owner "$USER"
|
||||
banger vm run --name sandbox
|
||||
```
|
||||
|
||||
|
|
@ -15,46 +16,95 @@ dev tools) and kernel, creates a VM, starts it, and drops you into
|
|||
an interactive ssh session. First run takes a couple minutes (bundle
|
||||
download); subsequent `vm run`s are seconds.
|
||||
|
||||
## Supported host path
|
||||
|
||||
banger's supported host/runtime path is:
|
||||
|
||||
- Linux on `x86_64 / amd64`
|
||||
- `systemd` as the host init/service manager
|
||||
- `bangerd.service` running as the installed owner user
|
||||
- `bangerd-root.service` running as the privileged host helper
|
||||
|
||||
Other setups may work with manual adaptation, but they are not the
|
||||
supported operating model for this repo.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **x86_64 / amd64 Linux** — arm64 is not supported today. The companion
|
||||
binaries, the published kernel catalog, and the OCI import path all
|
||||
assume `linux/amd64`. `banger doctor` surfaces this as a failing
|
||||
check on other architectures.
|
||||
- **systemd on the host** — this is the supported service-management
|
||||
path. banger's supported install/run model is the owner-user
|
||||
`bangerd.service` plus the privileged `bangerd-root.service`
|
||||
installed by `banger system install`.
|
||||
- `/dev/kvm`
|
||||
- `sudo`
|
||||
- `sudo` for the install/admin commands (`system install`,
|
||||
`system restart`, `system uninstall`)
|
||||
- Firecracker on `PATH`, or `firecracker_bin` set in config
|
||||
- host tools checked by `banger doctor`
|
||||
|
||||
## Build + install
|
||||
|
||||
```bash
|
||||
make install
|
||||
make build
|
||||
sudo ./build/bin/banger system install --owner "$USER"
|
||||
```
|
||||
|
||||
Installs `banger` (CLI), `bangerd` (daemon, auto-starts on first
|
||||
CLI call), and `banger-vsock-agent` (companion, under
|
||||
`$PREFIX/lib/banger/`).
|
||||
This installs two systemd units, copies the current `banger`,
|
||||
`bangerd`, and `banger-vsock-agent` binaries into `/usr/local`, writes
|
||||
install metadata under `/etc/banger`, and starts both services:
|
||||
|
||||
To remove the binaries (and stop the daemon):
|
||||
- `bangerd.service` runs as the configured owner user and exposes the
|
||||
public CLI socket at `/run/banger/bangerd.sock`.
|
||||
- `bangerd-root.service` runs as root and handles the narrow set of
|
||||
privileged host operations over the private helper socket at
|
||||
`/run/banger-root/bangerd-root.sock`.
|
||||
|
||||
After that, normal daily commands such as `banger vm run` and
|
||||
`banger image pull` are unprivileged.
|
||||
|
||||
This `systemd` service flow is the supported path. If you're not on a
|
||||
host that can run both services, you're outside the supported host
|
||||
model even if some pieces happen to work.
|
||||
|
||||
The split matters:
|
||||
|
||||
- `bangerd.service` runs as the owner user, keeps its writable state in
|
||||
`/var/lib/banger`, `/var/cache/banger`, and `/run/banger`, and sees
|
||||
the owner home read-only.
|
||||
- `bangerd-root.service` is the only process that keeps elevated host
|
||||
capabilities, and that capability set is limited to the host-kernel
|
||||
primitives banger actually uses (`CAP_CHOWN`, `CAP_SYS_ADMIN`,
|
||||
`CAP_NET_ADMIN`).
|
||||
|
||||
To inspect or refresh the services:
|
||||
|
||||
```bash
|
||||
make uninstall
|
||||
banger system status
|
||||
sudo banger system restart
|
||||
```
|
||||
|
||||
User data stays in place — the target prints the paths so you can
|
||||
`rm -rf` them if you want a full purge:
|
||||
To remove the system services:
|
||||
|
||||
- `~/.config/banger/` — config, managed SSH keys
|
||||
- `~/.local/state/banger/` — VM records, rootfs images, kernels, daemon DB/log
|
||||
- `~/.cache/banger/` — OCI layer cache
|
||||
```bash
|
||||
sudo banger system uninstall
|
||||
```
|
||||
|
||||
Add `--purge` if you also want to remove system-owned VM/image/cache
|
||||
state under `/var/lib/banger`, `/var/cache/banger`, `/run/banger`, and
|
||||
`/run/banger-root`. User config stays in place under your home
|
||||
directory:
|
||||
|
||||
- `~/.config/banger/` — config, optional `ssh_config`
|
||||
- `~/.local/state/banger/ssh/` — user SSH key + known_hosts
|
||||
|
||||
### Shell completion
|
||||
|
||||
`banger` ships completion scripts for bash, zsh, fish, and
|
||||
powershell. Tab-completion covers subcommands, flags, and live
|
||||
resource names (VM, image, kernel) looked up from the
|
||||
daemon. With the daemon down, resource completion silently
|
||||
resource names (VM, image, kernel) looked up from the installed
|
||||
services. With the services down, resource completion silently
|
||||
returns nothing — no file-completion fallback.
|
||||
|
||||
```bash
|
||||
|
|
@ -105,10 +155,12 @@ logs` inspection.
|
|||
|
||||
## Hostnames: reaching `<vm>.vm`
|
||||
|
||||
banger's daemon runs a DNS server for the `.vm` zone. With host-side
|
||||
DNS routing you can `curl http://sandbox.vm:3000` from anywhere on
|
||||
the host — no copy-pasting guest IPs. On systemd-resolved hosts this
|
||||
is auto-wired; everywhere else there's a short recipe. See
|
||||
banger's owner daemon runs a DNS server for the `.vm` zone. With
|
||||
host-side DNS routing you can `curl http://sandbox.vm:3000` from
|
||||
anywhere on the host — no copy-pasting guest IPs. On
|
||||
systemd-resolved hosts the owner daemon asks the root helper to
|
||||
auto-wire this and that is the supported path. Everywhere else
|
||||
there's a best-effort manual recipe. See
|
||||
[`docs/dns-routing.md`](docs/dns-routing.md).
|
||||
|
||||
### Optional: `ssh <name>.vm` shortcut
|
||||
|
|
@ -125,7 +177,9 @@ banger ssh-config # show the include line to paste manually
|
|||
```
|
||||
|
||||
banger never touches `~/.ssh/config` on its own — the daemon keeps its
|
||||
file fresh at `~/.config/banger/ssh_config`; whether and how it's
|
||||
own known_hosts under `/var/lib/banger/ssh/known_hosts`, while
|
||||
`banger ssh-config` keeps the user-facing file fresh at
|
||||
`~/.config/banger/ssh_config`; whether and how it's
|
||||
pulled into your SSH config is up to you.
|
||||
|
||||
## Image catalog
|
||||
|
|
@ -200,8 +254,12 @@ mode = "0755" # optional; default 0600 for files
|
|||
|
||||
Runs at `vm create` time. Each entry copies `host` → `guest` onto
|
||||
the VM's work disk (mounted at `/root` in the guest). Guest paths
|
||||
must live under `~/` or `/root/...`. Default is no entries — add the
|
||||
ones you want. Symlinks encountered while recursing into a synced
|
||||
must live under `~/` or `/root/...`. Host paths must live under the
|
||||
installed owner's home directory; `~/...` is the intended form, and
|
||||
absolute paths are accepted only when they still point inside that
|
||||
home. Default is no entries — add the ones you want. A top-level
|
||||
symlink is followed only when its resolved target stays inside the
|
||||
owner home. Symlinks encountered while recursing into a synced
|
||||
directory are skipped with a warning — they'd otherwise leak files
|
||||
from outside the named tree (e.g. a symlink inside `~/.aws` pointing
|
||||
to an unrelated credential dir).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue