Files
forgerunner/docker/runner/docker-entrypoint.sh
T

140 lines
5.5 KiB
Bash
Raw Normal View History

2026-06-29 21:56:12 -05:00
#!/usr/bin/env bash
# docker-entrypoint.sh — custom-gitea-runner bootstrap and daemon startup
# Runs as PID 1 via tini. Handles validation, optional CA trust, registration, and daemon start.
set -euo pipefail
RUNNER_CONFIG_PATH="${RUNNER_CONFIG_PATH:-/config/runner.yaml}"
RUNNER_WORKDIR="${RUNNER_WORKDIR:-/work}"
# ─── Banner ───────────────────────────────────────────────────────────────────
print_banner() {
echo "======================================================"
echo " custom-gitea-runner"
echo " Image version : ${IMAGE_VERSION:-unknown}"
echo " Git revision : ${GIT_REVISION:-unknown}"
echo "======================================================"
echo "Runtime:"
echo " act_runner : $(act_runner --version 2>&1 | head -1 || echo 'unknown')"
echo " node : $(node --version 2>&1 || echo 'unknown')"
echo " npm : $(npm --version 2>&1 || echo 'unknown')"
echo " git : $(git --version 2>&1 | awk '{print $3}' || echo 'unknown')"
echo " docker : $(docker --version 2>&1 | awk '{print $3}' | tr -d ',' || echo 'unavailable')"
echo "Config:"
echo " Config path : ${RUNNER_CONFIG_PATH}"
echo " Work dir : ${RUNNER_WORKDIR}"
echo " Gitea URL : ${GITEA_INSTANCE_URL:-[not set]}"
echo " Runner name : ${GITEA_RUNNER_NAME:-[not set]}"
echo " Labels : ${GITEA_RUNNER_LABELS:-[not set]}"
echo "======================================================"
}
# ─── Binary validation ────────────────────────────────────────────────────────
validate_binaries() {
local missing=0
for bin in act_runner git node npm; do
if ! command -v "$bin" &>/dev/null; then
echo "[ERROR] Required binary not found: ${bin}"
missing=1
fi
done
if [ "$missing" -ne 0 ]; then
echo "[FATAL] Missing required binaries. This is an image build issue."
exit 1
fi
echo "[OK] All required binaries present."
}
# ─── Custom CA trust (optional) ───────────────────────────────────────────────
install_custom_ca() {
local ca_dir="/config/trusted-ca"
if [ -d "$ca_dir" ] && compgen -G "${ca_dir}/*.crt" >/dev/null 2>&1; then
echo "[CA] Installing custom CA certificates from ${ca_dir} ..."
cp "${ca_dir}"/*.crt /usr/local/share/ca-certificates/ 2>/dev/null || true
update-ca-certificates --fresh 2>&1 | grep -v "^$" || true
echo "[CA] Custom CA trust updated."
fi
}
# ─── Registration (Mode B: bootstrap from env vars) ───────────────────────────
require_env() {
local var="$1"
if [ -z "${!var:-}" ]; then
echo "[FATAL] Required environment variable not set: ${var}"
exit 1
fi
}
# Rewrite the `labels:` list in the runner config. act_runner reads labels
# from the config file at registration time and IGNORES the `register --labels`
# flag whenever the config already exists — so to honor GITEA_RUNNER_LABELS we
# must edit the generated config before registering.
apply_labels() {
local labels_csv="$1" config="$2" tmp
echo "[BOOTSTRAP] Applying labels: ${labels_csv}"
tmp="$(mktemp)"
awk -v csv="${labels_csv}" '
BEGIN { n = split(csv, arr, ",") }
/^[[:space:]]+labels:[[:space:]]*$/ {
print
for (i = 1; i <= n; i++) {
gsub(/^[ \t]+|[ \t]+$/, "", arr[i])
printf " - \"%s\"\n", arr[i]
}
inlabels = 1
next
}
inlabels == 1 {
if ($0 ~ /^[[:space:]]+-[[:space:]]/) { next }
inlabels = 0
}
{ print }
' "${config}" > "${tmp}" && mv "${tmp}" "${config}"
}
register_runner() {
echo "[BOOTSTRAP] No config found at ${RUNNER_CONFIG_PATH}. Initiating registration."
require_env GITEA_INSTANCE_URL
require_env GITEA_RUNNER_TOKEN
require_env GITEA_RUNNER_NAME
mkdir -p "$(dirname "${RUNNER_CONFIG_PATH}")"
# Generate the default config template (includes cache/container defaults),
# then inject the operator's labels into it before registering.
act_runner generate-config > "${RUNNER_CONFIG_PATH}"
local labels="${GITEA_RUNNER_LABELS:-ubuntu-latest:docker://node:20-bullseye}"
apply_labels "${labels}" "${RUNNER_CONFIG_PATH}"
act_runner register \
--config "${RUNNER_CONFIG_PATH}" \
--instance "${GITEA_INSTANCE_URL}" \
--token "${GITEA_RUNNER_TOKEN}" \
--name "${GITEA_RUNNER_NAME}" \
--no-interactive
echo "[BOOTSTRAP] Registration complete. Config at ${RUNNER_CONFIG_PATH}."
}
# ─── Main ─────────────────────────────────────────────────────────────────────
print_banner
validate_binaries
install_custom_ca
mkdir -p "${RUNNER_WORKDIR}"
if [ ! -f "${RUNNER_CONFIG_PATH}" ]; then
register_runner
else
echo "[INFO] Existing config found at ${RUNNER_CONFIG_PATH}. Skipping registration."
fi
echo "[START] Starting act_runner daemon ..."
exec act_runner daemon --config "${RUNNER_CONFIG_PATH}"