Skip to content

Commit 9b669c3

Browse files
committed
the probes gate the shipped podman too and clear the userns exec restriction
1 parent c821376 commit 9b669c3

1 file changed

Lines changed: 56 additions & 40 deletions

File tree

‎.github/actions/install-boot/action.yml‎

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -65,48 +65,64 @@ runs:
6565
major=$(podman --version | awk '{print $NF}' | cut -d. -f1)
6666
if [ "${major:-0}" -ge 5 ]; then
6767
for d in /usr/local/bin /usr/local/sbin /usr/bin /usr/sbin /bin /sbin; do
68-
[ -x "$d/podman" ] && echo "already at $d/podman" && exit 0
68+
# Found, not exited: the probes at the bottom gate a shipped
69+
# podman the same as a repaired one, because a shipped one
70+
# drifts too.
71+
[ -x "$d/podman" ] && echo "already at $d/podman" && podman_ok=1 && break
72+
done
73+
if [ -z "$podman_ok" ]; then
74+
sudo ln -s "$(command -v podman)" /usr/bin/podman
75+
echo "linked $(command -v podman) -> /usr/bin/podman"
76+
fi
77+
else
78+
# Presence is not the whole gate. The install's own build mounts
79+
# its working container with lowerdirs from the additional image
80+
# store, and podman 4.9.3 cannot make that mount: the first COPY
81+
# dies with "no such file or directory" whatever the sync
82+
# unpacked first. Measured on 2026-09-04, where every job that
83+
# drew apt's 4.9.3 at /usr/bin died there while the same commits
84+
# on 5.8.4 installed and booted. So an old podman is repaired
85+
# with a new one rather than accepted, into /usr/local/bin, which
86+
# TOOL_DIRS orders ahead of /usr/bin and sudo's secure_path reads
87+
# first as well. Homebrew is preinstalled on these images and
88+
# bottles podman for linux, so the repair pours rather than
89+
# builds; a runner without it fails here, naming the absence,
90+
# instead of twenty minutes later at the COPY.
91+
[ -x /home/linuxbrew/.linuxbrew/bin/brew ] \
92+
|| { echo "podman $major is too old for the install's build and there is no Homebrew to repair with" >&2; exit 1; }
93+
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
94+
HOMEBREW_NO_AUTO_UPDATE=1 brew install podman
95+
sudo ln -sf "$(command -v podman)" /usr/local/bin/podman
96+
echo "podman version now: $(podman --version)"
97+
# The poured podman brings matching helpers, but linking podman
98+
# alone left the repair running the apt ones: podman resolves
99+
# crun and pasta from fixed path lists that read /usr/bin before
100+
# anywhere brew pours, and sudo's PATH never reaches the brew
101+
# prefix either. The apt crun 0.17 rejected the OCI spec the new
102+
# podman writes ("crun: unknown version specified") and the apt
103+
# pasta rejected its --map-guest-addr ("pasta failed with exit
104+
# code 1"), both measured 2026-09-04, each wall costing a run.
105+
# So the repair replaces the old helpers where the lists look
106+
# first, like the podman above. conmon is shadowed the same way
107+
# but the apt one starts containers fine, so it is left alone.
108+
for helper in crun pasta; do
109+
[ -x "$(command -v "$helper")" ] \
110+
|| { echo "brew poured podman but no $helper came with it" >&2; exit 1; }
111+
sudo ln -sf "$(command -v "$helper")" "/usr/bin/$helper"
112+
echo "$helper now at: $(readlink "/usr/bin/$helper")"
69113
done
70-
sudo ln -s "$(command -v podman)" /usr/bin/podman
71-
echo "linked $(command -v podman) -> /usr/bin/podman"
72-
exit 0
73114
fi
74-
# Presence is not the whole gate. The install's own build mounts
75-
# its working container with lowerdirs from the additional image
76-
# store, and podman 4.9.3 cannot make that mount: the first COPY
77-
# dies with "no such file or directory" whatever the sync
78-
# unpacked first. Measured on 2026-09-04, where every job that
79-
# drew apt's 4.9.3 at /usr/bin died there while the same commits
80-
# on 5.8.4 installed and booted. So an old podman is repaired
81-
# with a new one rather than accepted, into /usr/local/bin, which
82-
# TOOL_DIRS orders ahead of /usr/bin and sudo's secure_path reads
83-
# first as well. Homebrew is preinstalled on these images and
84-
# bottles podman for linux, so the repair pours rather than
85-
# builds; a runner without it fails here, naming the absence,
86-
# instead of twenty minutes later at the COPY.
87-
[ -x /home/linuxbrew/.linuxbrew/bin/brew ] \
88-
|| { echo "podman $major is too old for the install's build and there is no Homebrew to repair with" >&2; exit 1; }
89-
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
90-
HOMEBREW_NO_AUTO_UPDATE=1 brew install podman
91-
sudo ln -sf "$(command -v podman)" /usr/local/bin/podman
92-
echo "podman version now: $(podman --version)"
93-
# The poured podman brings matching helpers, but linking podman
94-
# alone left the repair running the apt ones: podman resolves
95-
# crun and pasta from fixed path lists that read /usr/bin before
96-
# anywhere brew pours, and sudo's PATH never reaches the brew
97-
# prefix either. The apt crun 0.17 rejected the OCI spec the new
98-
# podman writes ("crun: unknown version specified") and the apt
99-
# pasta rejected its --map-guest-addr ("pasta failed with exit
100-
# code 1"), both measured 2026-09-04, each wall costing a run.
101-
# So the repair replaces the old helpers where the lists look
102-
# first, like the podman above. conmon is shadowed the same way
103-
# but the apt one starts containers fine, so it is left alone.
104-
for helper in crun pasta; do
105-
[ -x "$(command -v "$helper")" ] \
106-
|| { echo "brew poured podman but no $helper came with it" >&2; exit 1; }
107-
sudo ln -sf "$(command -v "$helper")" "/usr/bin/$helper"
108-
echo "$helper now at: $(readlink "/usr/bin/$helper")"
109-
done
115+
# Rootless podman re-executes itself inside a fresh user namespace
116+
# before it does anything else, and a 2026-09-04 runner image
117+
# denied that exec ("failed to reexec: Permission denied") where
118+
# the morning's image allowed it: the kernel gained AppArmor's
119+
# unprivileged-userns restriction, under which an unprofiled
120+
# binary can enter a userns but not exec inside one. Rootless
121+
# containers cannot exist without unprivileged user namespaces,
122+
# so the restriction is cleared rather than worked around. The
123+
# old value is printed either way, to name the next drift.
124+
echo "apparmor_restrict_unprivileged_userns: $(cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns 2>/dev/null || echo 'no such knob on this kernel')"
125+
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 >/dev/null 2>&1 || true
110126
# A new podman that cannot run as root would fail the install
111127
# twenty minutes in at the same COPY. Running a container as root
112128
# here costs seconds, exercises the store, the runtime and the

0 commit comments

Comments
 (0)