diff --git a/infra/start.sh b/infra/start.sh index d5275d8..6c62396 100755 --- a/infra/start.sh +++ b/infra/start.sh @@ -59,6 +59,16 @@ EOF echo "[hiy] Generated proxy/caddy.json for ${DOMAIN_SUFFIX}" +# ── Ensure newuidmap/newgidmap setuid binaries are present ──────────────────── +# These binaries (from the 'uidmap' package) allow rootless Podman to map a +# full range of UIDs/GIDs in user namespaces. Without them Podman can only +# map UID 0 → the calling user and any layer file owned by a non-zero UID/GID +# (e.g. gid=42 for /etc/shadow) will cause an "invalid argument" lchown error. +if ! command -v newuidmap &>/dev/null; then + echo "[hiy] Installing uidmap (provides newuidmap/newgidmap)…" + sudo apt-get install -y uidmap +fi + # ── Ensure subuid/subgid entries exist for rootless Podman ──────────────────── # Rootless Podman maps UIDs/GIDs inside containers using subordinate ID ranges # from /etc/subuid and /etc/subgid. Without a sufficient range, pulling or @@ -72,7 +82,7 @@ fi if ! grep -q "^${_HIY_USER}:" /etc/subgid 2>/dev/null; then echo "${_HIY_USER}:100000:65536" | sudo tee -a /etc/subgid > /dev/null fi -# Always migrate so Podman storage reflects the current subuid/subgid mappings. +# Migrate storage so Podman picks up the current subuid/subgid mappings. podman system migrate # ── Allow rootless processes to bind ports 80/443 ───────────────────────────── @@ -102,16 +112,25 @@ export XDG_RUNTIME_DIR="$_HIY_XDG" PODMAN_SOCK="${_HIY_XDG}/podman.sock" export PODMAN_SOCK export DOCKER_HOST="unix://${PODMAN_SOCK}" -if [ ! -S "$PODMAN_SOCK" ]; then - echo "[hiy] Starting Podman socket via podman system service…" - podman system service --time=0 "unix://${PODMAN_SOCK}" & - # Wait up to 5 s for the socket to appear - for i in 1 2 3 4 5; do - [ -S "$PODMAN_SOCK" ] && break - sleep 1 - done - [ -S "$PODMAN_SOCK" ] || { echo "ERROR: Podman socket did not appear"; exit 1; } + +# Always (re)start the Podman socket service so it reflects the current +# subuid/subgid configuration. A stale service started before the entries +# existed will silently fall back to single-UID mapping and cause lchown +# failures when extracting image layers that contain non-root UIDs/GIDs. +if [ -S "$PODMAN_SOCK" ]; then + echo "[hiy] Restarting Podman socket service (refreshing user namespace config)…" + pkill -f "podman system service.*${PODMAN_SOCK}" 2>/dev/null || true + # Give the process a moment to exit and release the socket. + sleep 1 + rm -f "$PODMAN_SOCK" fi +echo "[hiy] Starting Podman socket via podman system service…" +podman system service --time=0 "unix://${PODMAN_SOCK}" & +for i in 1 2 3 4 5; do + [ -S "$PODMAN_SOCK" ] && break + sleep 1 +done +[ -S "$PODMAN_SOCK" ] || { echo "ERROR: Podman socket did not appear"; exit 1; } # ── Build images ─────────────────────────────────────────────────────────────── make -C "$SCRIPT_DIR" build