refactor(firecracker): non-invasive NixOS module (no firewall switch)

The module used `networking.nftables.tables.*` (which forces
`networking.nftables.enable = true`, flipping the host firewall backend)
and `systemd.network.enable` (handing interfaces to systemd-networkd) —
disruptive on an iptables + Docker daily driver.

Rewrite it to a single systemd oneshot that brings the pool up: idempotent
`ip tuntap` for the TAPs + `nft -f` for the independent `inet bot_bottle_fc`
table (its own hooks at priority -10), with ExecStop teardown. Same as the
imperative script, but declarative. It touches neither the firewall backend
nor networkd, so it coexists with iptables/Docker/ufw/firewalld. Verified
through the NixOS module system (service present, firewall untouched).

Drop the now-redundant `render_nixos_module()` paste generator (the module
is a real importable file) and point `backend setup` at importing it (flake
output or the file path), noting it's non-invasive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
This commit is contained in:
2026-07-11 17:25:50 -04:00
parent 949b001464
commit 480269b116
4 changed files with 98 additions and 125 deletions
+11 -10
View File
@@ -55,16 +55,17 @@ class TestNetpoolSlots(unittest.TestCase):
class TestNetpoolRenderers(unittest.TestCase):
def test_nixos_module_has_table_and_taps(self):
with patch.dict(os.environ, {"BOT_BOTTLE_FC_POOL_SIZE": "2"}):
out = netpool.render_nixos_module()
self.assertIn('networking.nftables.tables."bot_bottle_fc"', out)
self.assertIn('Name = "bbfc0"', out)
self.assertIn('Name = "bbfc1"', out)
self.assertIn("net.ipv4.ip_forward", out)
# fail-closed isolation rules present
self.assertIn('iifname != "bbfc*" return', out)
self.assertIn("ct status dnat accept", out)
def test_nixos_module_is_non_invasive(self):
# The NixOS module must NOT flip the host firewall backend or
# hand interfaces to systemd-networkd; it brings the pool up via
# a systemd oneshot that coexists with an iptables firewall.
root = Path(__file__).resolve().parents[2]
mod = (root / "nix" / "firecracker-netpool.nix").read_text()
self.assertNotIn("networking.nftables.enable = true", mod)
self.assertNotIn("systemd.network.enable = true", mod)
self.assertIn("bot-bottle-firecracker-netpool", mod) # the oneshot
self.assertIn(netpool.NFT_TABLE, mod)
self.assertIn('iifname != "${cfg.ifacePrefix}*" return', mod)
def test_shell_setup_reflects_overrides(self):
with patch.dict(os.environ, {"BOT_BOTTLE_FC_POOL_SIZE": "3"}):