feat(firecracker): show binary/KVM prerequisites in backend setup
`backend setup --backend=firecracker` only covered the network pool. Lead with the other prerequisites: the firecracker binary (with a release install pointer when it's not on PATH, plus a NixOS note), a /dev/kvm check, and a reminder about the cached guest kernel + static dropbear and mke2fs. The network pool is now step 2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
This commit is contained in:
@@ -14,16 +14,51 @@ generic `./cli.py backend {setup,status}` command dispatches to.
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from . import netpool
|
from . import netpool
|
||||||
|
from . import util
|
||||||
|
|
||||||
|
|
||||||
|
_FC_RELEASES = "https://github.com/firecracker-microvm/firecracker/releases"
|
||||||
|
|
||||||
|
|
||||||
def _owner() -> str:
|
def _owner() -> str:
|
||||||
return os.environ.get("USER", "youruser")
|
return os.environ.get("USER", "youruser")
|
||||||
|
|
||||||
|
|
||||||
|
def _print_prereqs() -> None:
|
||||||
|
"""The firecracker binary + KVM + guest artifacts, shown before the
|
||||||
|
privileged network-pool step so operators see the full picture."""
|
||||||
|
fc = shutil.which("firecracker")
|
||||||
|
if fc:
|
||||||
|
sys.stderr.write(f"1) firecracker binary: found ({fc}).\n")
|
||||||
|
else:
|
||||||
|
sys.stderr.write(
|
||||||
|
"1) firecracker binary: NOT found on PATH. Install a release binary "
|
||||||
|
"and put it on PATH:\n"
|
||||||
|
f" {_FC_RELEASES}\n"
|
||||||
|
" e.g.: download firecracker-vX.Y.Z-$(uname -m).tgz, extract, and\n"
|
||||||
|
" install -m755 release-*/firecracker-* ~/.local/bin/firecracker\n"
|
||||||
|
" (NixOS: not packaged as a user binary — fetch the release, pin\n"
|
||||||
|
" the version, and add it to PATH.)\n"
|
||||||
|
)
|
||||||
|
if util.is_host_capable():
|
||||||
|
sys.stderr.write(" KVM: /dev/kvm present.\n")
|
||||||
|
else:
|
||||||
|
sys.stderr.write(
|
||||||
|
" KVM: /dev/kvm missing/unusable — load kvm-intel/kvm-amd, enable\n"
|
||||||
|
" virtualization in firmware, and add your user to the `kvm` group.\n"
|
||||||
|
)
|
||||||
|
sys.stderr.write(
|
||||||
|
" Guest artifacts: a kernel (BOT_BOTTLE_FC_KERNEL) and static dropbear\n"
|
||||||
|
" (BOT_BOTTLE_FC_DROPBEAR) must be cached, and `mke2fs` (e2fsprogs) is\n"
|
||||||
|
" needed to build the rootfs.\n\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _is_nixos() -> bool:
|
def _is_nixos() -> bool:
|
||||||
if Path("/etc/NIXOS").exists():
|
if Path("/etc/NIXOS").exists():
|
||||||
return True
|
return True
|
||||||
@@ -50,11 +85,13 @@ def _warn_overlaps() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def setup() -> int:
|
def setup() -> int:
|
||||||
|
sys.stderr.write("Firecracker backend — one-time host setup.\n\n")
|
||||||
|
_print_prereqs()
|
||||||
slots = netpool.all_slots()
|
slots = netpool.all_slots()
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
f"Firecracker network pool: {len(slots)} slots "
|
f"2) network pool: {len(slots)} slots "
|
||||||
f"({slots[0].iface}..{slots[-1].iface}), base {netpool.ip_base()}.\n"
|
f"({slots[0].iface}..{slots[-1].iface}), base {netpool.ip_base()} — "
|
||||||
f"This is a one-time privileged setup (needs root once).\n\n"
|
f"TAP devices + nft isolation table, privileged (needs root once).\n\n"
|
||||||
)
|
)
|
||||||
_warn_overlaps()
|
_warn_overlaps()
|
||||||
if _is_nixos():
|
if _is_nixos():
|
||||||
|
|||||||
Reference in New Issue
Block a user