131 lines
5.0 KiB
Bash
Executable File
131 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ============================================================================
|
|
# Install a Gitea Actions runner (act_runner) on THIS host for tlam89/sciagent.
|
|
# Target: the Gitea + app box 103.149.170.102 (run this ON that box, as root).
|
|
#
|
|
# Registers ONE runner with two labels so the CI/CD pipeline can use both:
|
|
# ci -> docker mode (clean ephemeral containers; backend + frontend jobs)
|
|
# deploy -> host mode (runs on the host so it can drive `docker compose`)
|
|
#
|
|
# Prereqs installed/verified here: Docker + compose plugin, Node.js (needed by
|
|
# host-mode actions/checkout). Re-runnable: skips steps already done.
|
|
#
|
|
# Usage (token already minted for this repo; rotate via Gitea if it expires):
|
|
# sudo bash setup-gitea-runner.sh
|
|
# Override:
|
|
# GITEA_URL=http://localhost:3000 RUNNER_TOKEN=xxx bash setup-gitea-runner.sh
|
|
# ============================================================================
|
|
set -euo pipefail
|
|
|
|
GITEA_URL="${GITEA_URL:-http://localhost:3000}"
|
|
RUNNER_TOKEN="${RUNNER_TOKEN:-aCd3rpPnJTAPVHqsTIme9SaJm3pUbnbyOQqMrt9O}"
|
|
RUNNER_NAME="${RUNNER_NAME:-sciagent-box-runner}"
|
|
RUNNER_LABELS="${RUNNER_LABELS:-ci:docker://catthehacker/ubuntu:act-22.04,deploy:host}"
|
|
ACT_VERSION="${ACT_VERSION:-0.2.11}"
|
|
RUNNER_DIR="${RUNNER_DIR:-/opt/act_runner}"
|
|
|
|
log(){ printf '\n\033[36m==> %s\033[0m\n' "$*"; }
|
|
|
|
[[ "$(id -u)" -eq 0 ]] || { echo "Run as root (sudo)."; exit 1; }
|
|
|
|
# --- 1. Docker + compose plugin --------------------------------------------
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
log "Installing Docker (get.docker.com convenience script)"
|
|
curl -fsSL https://get.docker.com | sh
|
|
fi
|
|
if ! docker compose version >/dev/null 2>&1; then
|
|
log "docker compose plugin missing — installing docker-compose-plugin"
|
|
(apt-get update && apt-get install -y docker-compose-plugin) || \
|
|
echo "WARN: install the compose plugin manually for your distro."
|
|
fi
|
|
systemctl enable --now docker >/dev/null 2>&1 || true
|
|
docker version --format '{{.Server.Version}}' >/dev/null 2>&1 || { echo "Docker daemon not running"; exit 1; }
|
|
|
|
# --- 2. Node.js (host-mode jobs run actions/checkout, which needs node) -----
|
|
if ! command -v node >/dev/null 2>&1; then
|
|
log "Installing Node.js 20"
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs || \
|
|
echo "WARN: install Node.js 20 manually if your distro is non-Debian."
|
|
fi
|
|
|
|
# --- 3. Download act_runner -------------------------------------------------
|
|
mkdir -p "$RUNNER_DIR"
|
|
cd "$RUNNER_DIR"
|
|
if [[ ! -x "$RUNNER_DIR/act_runner" ]]; then
|
|
log "Downloading act_runner ${ACT_VERSION}"
|
|
arch="$(uname -m)"; case "$arch" in x86_64) arch=amd64;; aarch64) arch=arm64;; esac
|
|
curl -fsSL -o act_runner \
|
|
"https://dl.gitea.com/act_runner/${ACT_VERSION}/act_runner-${ACT_VERSION}-linux-${arch}"
|
|
chmod +x act_runner
|
|
fi
|
|
|
|
# --- 4. Register ------------------------------------------------------------
|
|
if [[ ! -f "$RUNNER_DIR/.runner" ]]; then
|
|
log "Registering with Gitea ($GITEA_URL) labels: $RUNNER_LABELS"
|
|
./act_runner register --no-interactive \
|
|
--instance "$GITEA_URL" \
|
|
--token "$RUNNER_TOKEN" \
|
|
--name "$RUNNER_NAME" \
|
|
--labels "$RUNNER_LABELS"
|
|
else
|
|
log ".runner already exists — skipping register"
|
|
fi
|
|
[[ -f "$RUNNER_DIR/config.yaml" ]] || ./act_runner generate-config > config.yaml
|
|
|
|
# generate-config injects DEFAULT labels (ubuntu-latest/22.04/20.04) into config.yaml
|
|
# which OVERRIDE the --labels passed at registration. Force our labels into config.yaml
|
|
# so the daemon advertises ci (docker) + deploy (host), not the defaults.
|
|
python3 - "$RUNNER_DIR/config.yaml" "$RUNNER_LABELS" <<'PY'
|
|
import sys,re
|
|
path,labels=sys.argv[1],sys.argv[2].split(",")
|
|
s=open(path).read().splitlines(keepends=True)
|
|
o=[];i=0;n=len(s);done=False
|
|
while i<n:
|
|
if not done and re.match(r'^\s{2}labels:\s*$',s[i]):
|
|
o.append(" labels:\n")
|
|
for x in labels: o.append(' - "%s"\n'%x)
|
|
i+=1
|
|
while i<n and re.match(r'^\s{4}(- |#)',s[i]): i+=1
|
|
done=True; continue
|
|
o.append(s[i]); i+=1
|
|
if not done:
|
|
o2=[];ins=False
|
|
for line in o:
|
|
o2.append(line)
|
|
if not ins and re.match(r'^runner:\s*$',line):
|
|
o2.append(" labels:\n")
|
|
for x in labels: o2.append(' - "%s"\n'%x)
|
|
ins=True
|
|
o=o2
|
|
open(path,"w").write("".join(o))
|
|
print("config.yaml labels ->", ", ".join(labels))
|
|
PY
|
|
|
|
# --- 5. systemd service -----------------------------------------------------
|
|
log "Installing systemd service act_runner"
|
|
cat > /etc/systemd/system/act_runner.service <<UNIT
|
|
[Unit]
|
|
Description=Gitea Actions runner (sciagent)
|
|
After=docker.service network-online.target
|
|
Wants=docker.service
|
|
|
|
[Service]
|
|
WorkingDirectory=${RUNNER_DIR}
|
|
ExecStart=${RUNNER_DIR}/act_runner daemon --config ${RUNNER_DIR}/config.yaml
|
|
Restart=always
|
|
RestartSec=5
|
|
User=root
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
UNIT
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable --now act_runner
|
|
sleep 3
|
|
systemctl --no-pager --full status act_runner | head -12
|
|
|
|
echo
|
|
echo "Done. Verify in Gitea: Repo → Settings → Actions → Runners — '$RUNNER_NAME' should be Online."
|
|
echo "Logs: journalctl -u act_runner -f"
|