feat(firecracker): group-owned TAP pool for multi-user hosts

Add a `group` option to the netpool NixOS module + BOT_BOTTLE_FC_GROUP to
the shell script: when set, the pool's TAP devices are owned by a group
instead of a single user, so any group member can open them (the kernel
lets a TAP's owning-group members attach). This lets an interactive user
and, say, a CI-runner user share one pool. `owner`/`group` are mutually
exclusive (asserted). Single-user `owner` remains the default.

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-12 16:17:37 -04:00
parent c44a1ffdc1
commit caf1da580a
3 changed files with 47 additions and 6 deletions
+15 -3
View File
@@ -38,6 +38,10 @@
# BOT_BOTTLE_FC_IP_BASE base IPv4 of the /31 pool (default 10.243.0.0)
# BOT_BOTTLE_FC_IFACE_PREFIX TAP name prefix (default bbfc)
# BOT_BOTTLE_FC_OWNER owning user (default $SUDO_USER or $USER)
# BOT_BOTTLE_FC_GROUP owning group; if set, TAPs are group-owned
# instead of user-owned, so any group member
# (e.g. an interactive user + a CI runner
# user) can open the pool. Overrides OWNER.
set -euo pipefail
@@ -45,6 +49,7 @@ POOL_SIZE="${BOT_BOTTLE_FC_POOL_SIZE:-8}"
IP_BASE="${BOT_BOTTLE_FC_IP_BASE:-10.243.0.0}"
PREFIX="${BOT_BOTTLE_FC_IFACE_PREFIX:-bbfc}"
OWNER="${BOT_BOTTLE_FC_OWNER:-${SUDO_USER:-$USER}}"
GROUP="${BOT_BOTTLE_FC_GROUP:-}"
TABLE="bot_bottle_fc"
# Sidecar ports (must match the backend). egress=9099, supervise=9100,
@@ -73,7 +78,14 @@ require_root() {
cmd_up() {
require_root up
echo "firecracker net pool: $POOL_SIZE slots, base $IP_BASE, owner $OWNER"
# Group ownership (any member can open the pool) overrides single-user
# ownership. The kernel lets a TAP's owning-group members attach.
if [ -n "$GROUP" ]; then
own_args=(group "$GROUP") ; own_desc="group=$GROUP"
else
own_args=(user "$OWNER") ; own_desc="owner=$OWNER"
fi
echo "firecracker net pool: $POOL_SIZE slots, base $IP_BASE, $own_desc"
# VM->sidecar traffic is DNAT'd to the sidecar container and
# forwarded, so forwarding must be enabled (Docker also sets this).
@@ -86,10 +98,10 @@ cmd_up() {
ip link set "$dev" down 2>/dev/null || true
ip tuntap del dev "$dev" mode tap 2>/dev/null || true
fi
ip tuntap add dev "$dev" mode tap user "$OWNER"
ip tuntap add dev "$dev" mode tap "${own_args[@]}"
ip addr add "$host/31" dev "$dev"
ip link set "$dev" up
echo " $dev host=$host guest=$(guest_ip "$i") owner=$OWNER"
echo " $dev host=$host guest=$(guest_ip "$i") $own_desc"
done
_install_nft