#!/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}"