140 lines
5.5 KiB
Bash
140 lines
5.5 KiB
Bash
|
|
#!/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}"
|