#!/usr/bin/env bash set -Eeuo pipefail RUNNER_VERSION="${RUNNER_VERSION:-1.0.8}" RUNNER_USER="${RUNNER_USER:-act_runner}" RUNNER_HOME="${RUNNER_HOME:-/var/lib/act_runner}" RUNNER_CONFIG_DIR="${RUNNER_CONFIG_DIR:-/etc/act_runner}" RUNNER_CONFIG_FILE="${RUNNER_CONFIG_FILE:-$RUNNER_CONFIG_DIR/config.yaml}" RUNNER_BINARY_PATH="${RUNNER_BINARY_PATH:-/usr/local/bin/act_runner}" RUNNER_NAME="${RUNNER_NAME:-$(hostname)}" RUNNER_LABELS="${RUNNER_LABELS:-linux_amd64:host,ubuntu-latest:docker://node:20-bookworm}" GITEA_INSTANCE_URL="${GITEA_INSTANCE_URL:-}" GITEA_RUNNER_TOKEN="${GITEA_RUNNER_TOKEN:-}" REGISTER_RUNNER="${REGISTER_RUNNER:-true}" log() { printf '[RUNNER] %s\n' "$1" } require_root() { if [ "${EUID}" -ne 0 ]; then echo "Dieses Script muss als root laufen." >&2 exit 1 fi } install_packages() { log "Installiere Systempakete" apt update apt install -y docker.io curl wget unzip git ca-certificates python3 systemctl enable --now docker } create_runner_user() { log "Erstelle Runner-User und Verzeichnisse" if ! id -u "$RUNNER_USER" >/dev/null 2>&1; then useradd --system --create-home --shell /bin/bash "$RUNNER_USER" fi usermod -aG docker "$RUNNER_USER" mkdir -p "$RUNNER_HOME" "$RUNNER_CONFIG_DIR" chown -R "$RUNNER_USER:$RUNNER_USER" "$RUNNER_HOME" "$RUNNER_CONFIG_DIR" } install_runner_binary() { local tmp_dir archive_name download_url log "Installiere act_runner ${RUNNER_VERSION}" tmp_dir="$(mktemp -d)" archive_name="act_runner-${RUNNER_VERSION}-linux-amd64" download_url="https://dl.gitea.com/act_runner/${RUNNER_VERSION}/${archive_name}" curl -fsSL "$download_url" -o "${tmp_dir}/act_runner" install -m 0755 "${tmp_dir}/act_runner" "$RUNNER_BINARY_PATH" rm -rf "$tmp_dir" "$RUNNER_BINARY_PATH" --version } generate_config() { log "Erzeuge Runner-Konfiguration" sudo -u "$RUNNER_USER" -H bash -lc "\"$RUNNER_BINARY_PATH\" generate-config > \"$RUNNER_CONFIG_FILE\"" python3 - "$RUNNER_CONFIG_FILE" "$RUNNER_LABELS" <<'PY' from pathlib import Path import sys config_path = Path(sys.argv[1]) labels = [label.strip() for label in sys.argv[2].split(",") if label.strip()] content = config_path.read_text(encoding="utf-8") lines = content.splitlines() out = [] in_runner = False labels_written = False skip_existing_labels = False for idx, line in enumerate(lines): stripped = line.strip() if stripped == "runner:": in_runner = True out.append(line) continue if in_runner and line and not line.startswith(" "): if not labels_written: out.append(" labels:") for label in labels: out.append(f" - \"{label}\"") labels_written = True in_runner = False if in_runner and stripped.startswith("labels:"): skip_existing_labels = True continue if skip_existing_labels: if line.startswith(" - ") or stripped == "": continue skip_existing_labels = False out.append(line) if in_runner and not labels_written: out.append(" labels:") for label in labels: out.append(f" - \"{label}\"") config_path.write_text("\n".join(out) + "\n", encoding="utf-8") PY chown "$RUNNER_USER:$RUNNER_USER" "$RUNNER_CONFIG_FILE" } register_runner() { if [ "$REGISTER_RUNNER" != "true" ]; then log "Runner-Registrierung übersprungen" return fi if [ -z "$GITEA_INSTANCE_URL" ] || [ -z "$GITEA_RUNNER_TOKEN" ]; then echo "Für die Registrierung werden GITEA_INSTANCE_URL und GITEA_RUNNER_TOKEN benötigt." >&2 exit 1 fi log "Registriere Runner bei ${GITEA_INSTANCE_URL}" sudo -u "$RUNNER_USER" -H bash -lc "cd \"$RUNNER_HOME\" && rm -f .runner && \"$RUNNER_BINARY_PATH\" register --no-interactive --instance \"$GITEA_INSTANCE_URL\" --token \"$GITEA_RUNNER_TOKEN\" --name \"$RUNNER_NAME\" --labels \"$RUNNER_LABELS\"" } install_service() { log "Installiere systemd-Service" cat >/etc/systemd/system/act_runner.service <