feat(firecracker): Linux microVM backend to replace smolmachines #343
Reference in New Issue
Block a user
Delete Branch "firecracker-backend"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Replaces the smolmachines backend on Linux with a Firecracker-based one. Closes #342 (and follows through on the smolmachines dead-end in #332).
What
A new
firecrackerbackend providing mature KVM microVM isolation:dropbearis injected into the rootfs; the host drives exec/cp/interactive over a point-to-point TAP link.ssh -tforwards SIGWINCH to the remote PTY natively (no resize bridge, unlike smolmachines).docker0/virbr0/cni0/br-*collisions), each a/31host↔guest link, plus a dedicatedtable inet bot_bottle_fcnftables table that coexists with Docker/ufw/firewalld rules instead of editing them../cli.py firecracker setupprints the host-appropriate config — a NixOS module (declarative, survives rebuilds) or the sudo script (scripts/firecracker-netpool.sh).docker export→ ext4 viamke2fs -d(rootless, no mount), cached by image digest. Per-bottle SSH pubkey + IP are passed via the kernel cmdline, so nothing bottle-specific touches the cached image.nft.Linux hosts with Firecracker + KVM now default to
firecracker; macOS stays onmacos-container;smolmachinesremains selectable.Design decisions
Testing status
tests/unit/test_firecracker_backend.py), pyright clean, backend registration/selection tests updated.docker export→ext4 pipeline, static dropbear../cli.py firecracker setup). Live validation + any fixes will follow in this branch before merge.Follow-ups
🤖 Generated with Claude Code
https://claude.ai/code/session_01G8p32HJgPoS1hLPWubbftM
Add abstract `setup()`/`status()` classmethods to BottleBackend (same per-host, no-instance shape as is_available) so host provisioning is part of the backend contract, not a per-backend command. Replace the `./cli.py firecracker {setup,status}` command with a generic `./cli.py backend {setup,status} [--backend=NAME]` that resolves a backend (flag / $BOT_BOTTLE_BACKEND / host default) and dispatches — swapping backends is just a different --backend. Implementations: - firecracker: moved out of cli/ into backend/firecracker/setup.py (network pool module/script + range-overlap check), unchanged output. - docker: new backend/docker/setup.py — reports docker on PATH, daemon reachability, and gVisor runsc; setup notes no privileged pool is needed. Minimal placeholder; richer version tracked in #345. - macos-container: new setup.py — container CLI + system-service checks. Also retarget the launch-preflight / isolation-probe pointers to the new command. New test_cli_backend covers dispatch + docker setup/status. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCckbackend teardownbackend setupFirst real end-to-end launch (there was no firecracker integration test) surfaced three bugs in the control/provision path, all now verified fixed by tests/integration/test_firecracker_launch: 1. Guest SSH rejected the correct key. The rootless rootfs build (`docker export | tar` as a non-root user) can't preserve uid 0, so every path — including /root — is owned by the build uid (node in guest). dropbear refuses root's authorized_keys when /root isn't root-owned, so auth fell back to password → denied. bb-init now `chown -R 0:0 /root`. 2. The SSH client (newer OpenSSH) didn't reliably present the -i key against the operator's ~/.ssh config; add `IdentitiesOnly=yes` to ssh_base_argv so only the per-bottle key is offered. 3. cp_in double-wrapped the remote command as `sh -c <remote>`, but ssh space-joins everything after the host into one string for the guest shell, collapsing `sh -c mkdir -p X && …` to `mkdir` with no operand ("missing operand"). Pass the command as a single arg and let the guest login shell run it (stdin still carries the tar). Also stop discarding dropbear's stderr (`-E` now reaches the host-side console.log) so future guest-auth issues are debuggable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCckView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.