deploy_data/deploy_app plays now run from INSIDE the forgejo-runner container with ansible_connection=local, but the unprivileged runner's root user (mapped to a high host UID) was being rejected by the incus daemon — \"You don't have the needed permissions to talk to the incus daemon\". runner-grant-incus.sh: privileged + nesting + raw.idmap=\"both 0 0\" so root inside the runner = root on the host. The mounted incus socket becomes fully usable. One-shot script; idempotent. Threat-model note in the script header: we accept this because the deploy workflow already has incus-admin scope via socket+nesting, and the trigger surface is gated to push:main + workflow_dispatch (no fork PRs). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
58 lines
1.9 KiB
Bash
Executable file
58 lines
1.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Give the forgejo-runner container real admin access to the host's
|
|
# Incus daemon. Required for deploy_data.yml + deploy_app.yml plays
|
|
# that run `incus launch` / `incus exec` from inside the runner.
|
|
#
|
|
# Run on the R720: sudo bash runner-grant-incus.sh
|
|
#
|
|
# Trade-off: the runner becomes a privileged container with full
|
|
# root access to incus. Consistent with the existing threat model
|
|
# (deploy.yml workflow already has incus admin via socket + nesting),
|
|
# but worth re-evaluating if the runner is ever exposed to untrusted
|
|
# inputs (PR triggers from forks etc — currently gated, see
|
|
# .forgejo/workflows/deploy.yml header).
|
|
set -euo pipefail
|
|
|
|
CONT=forgejo-runner
|
|
|
|
echo "→ stopping ${CONT}"
|
|
incus stop "${CONT}" --force 2>/dev/null || true
|
|
|
|
echo "→ enabling privileged + nesting + idmap-passthrough"
|
|
incus config set "${CONT}" security.privileged true
|
|
incus config set "${CONT}" security.nesting true
|
|
# Map host root (uid/gid 0) to container root so the mounted incus
|
|
# socket is readable+writable by root inside the container.
|
|
incus config set "${CONT}" raw.idmap "both 0 0"
|
|
|
|
echo "→ ensuring incus socket is mounted in"
|
|
if ! incus config device show "${CONT}" | grep -q "^incus-socket:"; then
|
|
incus config device add "${CONT}" incus-socket disk \
|
|
source=/var/lib/incus/unix.socket \
|
|
path=/var/lib/incus/unix.socket
|
|
fi
|
|
|
|
echo "→ starting ${CONT}"
|
|
incus start "${CONT}"
|
|
|
|
# Wait for the runner's userspace to come up
|
|
for i in $(seq 1 30); do
|
|
if incus exec "${CONT}" -- /bin/true 2>/dev/null; then
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
echo
|
|
echo "→ verifying incus access from inside the runner"
|
|
incus exec "${CONT}" -- bash -c '
|
|
if incus info >/dev/null 2>&1; then
|
|
echo " ✓ runner can talk to incus daemon"
|
|
else
|
|
echo " ✗ runner still cannot reach incus daemon"
|
|
exit 1
|
|
fi
|
|
'
|
|
|
|
echo
|
|
echo "✓ runner now has incus admin. Re-trigger Veza deploy."
|