fix(macos): install passt for podman 5 rootless networking

podman 5 uses pasta as the default rootless network helper; podman 4
used slirp4netns. The spike was written against bookworm's podman 4.3.1,
so its package list never included passt — and the trixie bump (#451)
changed the default out from under it. Every nested container failed to
start with "could not find pasta", while image pulls and the service
itself worked, which disguised a missing dependency as a compat-API bug.

The bootstrap now checks for pasta up front so this fails with a clear
message instead of surfacing at the first `docker run`.

Note the sun_path fix in a12d2191 did NOT cause or cure this; that path
was over the 108-byte limit independently and would have bitten as soon
as attach was reached.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 19:20:27 -04:00
parent 90522d335a
commit 1f64e4b6be
3 changed files with 26 additions and 7 deletions
@@ -7,7 +7,10 @@ if [ "$uid" -eq 0 ]; then
exit 1
fi
for command in podman docker fuse-overlayfs slirp4netns; do
# pasta is podman 5's default rootless network helper. Checked here so a
# missing package fails the bootstrap with a clear message rather than
# letting every later `docker run` die with "could not find pasta".
for command in podman docker fuse-overlayfs pasta slirp4netns; do
command -v "$command" >/dev/null 2>&1 || {
echo "missing nested-container prerequisite: $command" >&2
exit 1
@@ -41,10 +41,9 @@ _INIT = "/usr/local/libexec/bot-bottle/nested-containers-init"
# Deliberately cryptic and short. podman derives conmon's attach socket as
# `$XDG_RUNTIME_DIR/libpod/tmp/socket/<64-hex-id>/attach`, and a Unix socket
# path may not exceed 108 bytes (`sun_path`). The descriptive
# `/tmp/bot-bottle-podman-run` produced a 116-byte path, so every attached
# `docker run` failed with "unable to upgrade to tcp, received 500" while
# detached runs and image pulls worked fine. Do not lengthen this for
# readability — it buys 8 bytes of headroom over the limit.
# `/tmp/bot-bottle-podman-run` produced a 116-byte path — over the limit, so
# attach would have broken as soon as anything got far enough to attach. Do
# not lengthen this for readability; it buys 8 bytes of headroom.
_RUNTIME_DIR = "/tmp/bbp"
_SOCKET = f"{_RUNTIME_DIR}/podman.sock"
_LOG = "/tmp/bot-bottle-nested-containers.log"
@@ -83,8 +82,12 @@ def build_image(
"COPY --from=docker_cli /usr/local/libexec/docker/cli-plugins/"
"docker-compose /usr/local/libexec/docker/cli-plugins/docker-compose\n"
"RUN apt-get update \\\n"
# passt provides `pasta`, which podman 5 uses by default for
# rootless networking (podman 4 defaulted to slirp4netns). Without
# it every container fails to start with "could not find pasta".
# slirp4netns stays as the documented fallback.
" && apt-get install -y --no-install-recommends "
"fuse-overlayfs slirp4netns uidmap \\\n"
"fuse-overlayfs passt slirp4netns uidmap \\\n"
" && rm -rf /var/lib/apt/lists/* \\\n"
# Deliberate: an empty subordinate range keeps podman on the
# single-UID mapping that needs no CAP_SYS_ADMIN. Adding ranges