Files
infra-scripts/gitea-runner/install.sh
Damien 145c0018bf gitea-runner: paramétrer le hostname Gitea via GITEA_HOSTNAME
Remplace le hostname Tailscale hardcodé par la variable GITEA_HOSTNAME
(défaut: gitea.taila5ad8.ts.net), cohérent avec GITEA_API et VERSION_FILE.

Le heredoc étant single-quoted (<<'EOF'), la valeur est injectée à
l'écriture du service via sed, évitant tout conflit avec les variables
OpenRC runtime ($PATH, ${RC_SVCNAME}, etc.).
2026-06-20 10:53:23 +02:00

324 lines
10 KiB
Bash

#!/bin/bash
# install.sh - Gitea Act Runner: LXC creation, installation & update
# Usage:
# From Proxmox host : curl -fsSL https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/main/gitea-runner/install.sh | bash
# From inside LXC : bash /root/install.sh (updates act_runner binary)
set -euo pipefail
# --- Config (override via environment) ---
CTID="${CTID:-}"
HOSTNAME="${RUNNER_HOSTNAME:-gitea-runner}"
TEMPLATE="${TEMPLATE:-alpine-3.23-default_20260116_amd64.tar.xz}"
STORAGE="${STORAGE:-local-lvm}"
TEMPLATE_STORAGE="${TEMPLATE_STORAGE:-local}"
CORES="${CORES:-2}"
RAM="${RAM:-2048}"
DISK="${DISK:-8}"
BRIDGE="${BRIDGE:-vmbr0}"
SCRIPT_URL="https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/main/gitea-runner/install.sh"
GITEA_HOSTNAME="${GITEA_HOSTNAME:-gitea.taila5ad8.ts.net}"
GITEA_API="https://gitea.com/api/v1/repos/gitea/act_runner/releases"
VERSION_FILE="/opt/gitea-runner_version.txt"
# --- Colors ---
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# --- Helpers ---
get_latest_release() {
local release
release=$(curl -fsSL "$GITEA_API" | jq -r '.[0].tag_name')
if [[ -z "$release" || "$release" == "null" ]]; then
log_error "Failed to fetch latest release from Gitea API"
exit 1
fi
echo "$release"
}
get_arch() {
local arch
arch=$(uname -m)
case "$arch" in
x86_64) echo "amd64" ;;
aarch64) echo "arm64" ;;
armv7l) echo "armv7" ;;
*) log_error "Unsupported architecture: $arch"; exit 1 ;;
esac
}
download_runner() {
local release="$1"
local version="${release#v}"
local arch
arch=$(get_arch)
local url="https://gitea.com/gitea/act_runner/releases/download/${release}/gitea-runner-${version}-linux-${arch}"
log_info "Downloading act_runner ${release} (${arch})..."
curl -fsSL "$url" -o /usr/local/bin/act_runner
chmod +x /usr/local/bin/act_runner
ln -sf /usr/local/bin/act_runner /usr/bin/act_runner
echo "$release" > "$VERSION_FILE"
}
# ============================================================
# MODE 1: Proxmox host — create LXC container
# ============================================================
create_lxc() {
log_info "=== Gitea Act Runner — LXC Creation ==="
# Auto-select next CTID if not specified
if [[ -z "$CTID" ]]; then
CTID=$(pvesh get /cluster/resources --type vm --output-format json 2>/dev/null \
| jq '[.[].vmid] | max + 1' 2>/dev/null || echo "100")
log_info "Auto-selected CTID: $CTID"
fi
# Download template if needed
if ! pveam list "$TEMPLATE_STORAGE" 2>/dev/null | grep -q "$TEMPLATE"; then
log_info "Downloading template $TEMPLATE..."
pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
fi
log_info "Creating LXC $CTID ($HOSTNAME)..."
pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" \
--hostname "$HOSTNAME" \
--cores "$CORES" \
--memory "$RAM" \
--rootfs "${STORAGE}:${DISK}" \
--net0 "name=eth0,bridge=${BRIDGE},ip=dhcp" \
--unprivileged 1 \
--features nesting=1,keyctl=1 \
--tags "infra-script,cicd" \
--start 0
log_info "Configuring LXC for Docker and Tailscale..."
cat >> "/etc/pve/lxc/${CTID}.conf" <<EOF
lxc.apparmor.profile: unconfined
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net dev/net none bind,create=dir
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
EOF
log_info "Starting LXC $CTID..."
pct start "$CTID"
sleep 5
log_info "Injecting install script into container..."
pct exec "$CTID" -- sh -c "apk add --no-cache bash curl jq > /dev/null 2>&1"
curl -fsSL "$SCRIPT_URL" | pct exec "$CTID" -- bash -s -- --install
local ip
ip=$(pct exec "$CTID" -- ip -4 addr show eth0 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1)
echo ""
log_info "========================================="
log_info "LXC $CTID created successfully!"
log_info "========================================="
echo ""
echo " Hostname : $HOSTNAME"
echo " IP : ${ip:-pending}"
echo ""
echo "Next steps:"
echo " pct enter $CTID"
echo " cd /var/lib/gitea-runner"
echo " su -s /bin/bash gitea-runner -c 'act_runner register'"
echo " rc-service gitea-runner start"
echo ""
}
# ============================================================
# MODE 2: Inside LXC — fresh install
# ============================================================
install_runner() {
log_info "=== Gitea Act Runner — Installation ==="
log_info "Updating system..."
apk update > /dev/null && apk upgrade > /dev/null
log_info "Installing dependencies..."
apk add --no-cache curl jq tar bash docker docker-cli-compose > /dev/null
log_info "Installing Tailscale..."
apk add --no-cache tailscale > /dev/null
rc-update add tailscale default > /dev/null 2>&1
rc-service tailscale start > /dev/null 2>&1
log_info "Starting Docker..."
rc-update add docker default > /dev/null 2>&1
rc-service docker start > /dev/null 2>&1
local release
release=$(get_latest_release)
download_runner "$release"
log_info "act_runner $(act_runner --version 2>&1 || true)"
log_info "Creating gitea-runner user..."
adduser -S -D -H -h /var/lib/gitea-runner -s /bin/bash -G docker gitea-runner 2>/dev/null || true
addgroup gitea-runner docker 2>/dev/null || true
mkdir -p /var/lib/gitea-runner
chown -R gitea-runner:docker /var/lib/gitea-runner
log_info "Generating act_runner config with Prometheus metrics enabled..."
act_runner generate-config > /var/lib/gitea-runner/config.yaml
sed -i '/^metrics:/,/enabled:/{s/enabled: false/enabled: true/}' /var/lib/gitea-runner/config.yaml
chown gitea-runner:docker /var/lib/gitea-runner/config.yaml
chmod 640 /var/lib/gitea-runner/config.yaml
log_info "Creating OpenRC service..."
cat <<'EOF' > /etc/init.d/gitea-runner
#!/sbin/openrc-run
name="Gitea Act Runner"
description="Gitea Actions Runner Daemon"
command="/usr/local/bin/act_runner"
command_args="daemon --config /var/lib/gitea-runner/config.yaml"
command_user="gitea-runner:docker"
command_background=true
pidfile="/run/${RC_SVCNAME}.pid"
directory="/var/lib/gitea-runner"
output_log="/var/log/gitea-runner.log"
error_log="/var/log/gitea-runner.log"
depend() {
need net docker tailscale
after docker tailscale
}
start_pre() {
export PATH="/usr/local/bin:$PATH"
checkpath --directory --owner gitea-runner:docker --mode 0755 /var/lib/gitea-runner
checkpath --file --owner gitea-runner:docker --mode 0644 /var/log/gitea-runner.log
local timeout=30
local elapsed=0
ebegin "Waiting for Tailscale MagicDNS to resolve __GITEA_HOSTNAME__"
while ! getent hosts "__GITEA_HOSTNAME__" > /dev/null 2>&1; do
if [ "$elapsed" -ge "$timeout" ]; then
eend 1
eerror "Timed out after ${timeout}s waiting for MagicDNS resolution of __GITEA_HOSTNAME__"
return 1
fi
sleep 1
elapsed=$(( elapsed + 1 ))
done
eend 0
}
EOF
sed -i "s/__GITEA_HOSTNAME__/${GITEA_HOSTNAME}/g" /etc/init.d/gitea-runner
chmod +x /etc/init.d/gitea-runner
rc-update add gitea-runner default > /dev/null
log_info "Configuring logrotate for gitea-runner..."
apk add --no-cache logrotate > /dev/null
cat > /etc/logrotate.d/gitea-runner << 'LOGROTATE'
/var/log/gitea-runner.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
LOGROTATE
ln -sf /usr/sbin/logrotate /etc/periodic/daily/logrotate 2>/dev/null || true
log_info "Enabling console auto-login on tty1..."
# Alpine ships busybox getty by default; agetty (from util-linux) is what
# supports --autologin.
apk add --no-cache agetty >/dev/null 2>&1 || apk add --no-cache util-linux >/dev/null
# Replace any existing tty1 entry, then append our autologin line. Doing it
# in two steps (delete + append) is more robust than an in-place sed against
# a pattern that may drift across Alpine releases.
sed -i '/^tty1::/d' /etc/inittab
echo 'tty1::respawn:/sbin/agetty --autologin root --noclear 38400 tty1' >> /etc/inittab
# Tell PID 1 to re-read /etc/inittab so the change takes effect without a reboot.
kill -HUP 1 2>/dev/null || true
# Kick any getty/agetty still attached to tty1 so init respawns it *now* with
# the new line — otherwise the first web-console session lands on the stale
# process and the operator has to type `exit` once before autologin kicks in.
pkill -KILL -f '(getty|agetty).*tty1' 2>/dev/null || true
log_info "Cleaning up..."
rm -rf /var/cache/apk/*
echo ""
log_info "========================================="
log_info "Installation complete!"
log_info "========================================="
echo ""
echo "Connect to Tailscale first:"
echo " tailscale up --ssh"
echo ""
echo "Register the runner:"
echo " cd /var/lib/gitea-runner"
echo " su -s /bin/bash gitea-runner -c 'act_runner register'"
echo " rc-service gitea-runner start"
echo ""
}
# ============================================================
# MODE 3: Inside LXC — update binary
# ============================================================
update_runner() {
log_info "=== Gitea Act Runner — Update ==="
local release
release=$(get_latest_release)
if [[ -f "$VERSION_FILE" && "$release" == "$(cat "$VERSION_FILE")" ]]; then
log_info "Already at latest version: $release"
exit 0
fi
local current
current=$(cat "$VERSION_FILE" 2>/dev/null || echo "unknown")
log_info "Updating: $current$release"
log_info "Stopping service..."
rc-service gitea-runner stop 2>/dev/null || true
log_info "Backing up current binary..."
cp /usr/local/bin/act_runner "/usr/local/bin/act_runner.bak.$(date +%s)"
download_runner "$release"
log_info "Starting service..."
rc-service gitea-runner start
log_info "Updated to $release"
}
# ============================================================
# Main — detect context
# ============================================================
main() {
if [[ "${1:-}" == "--install" ]]; then
# Explicitly called in install mode (from pct exec)
install_runner
elif command -v pct &> /dev/null; then
# We're on the Proxmox host
create_lxc
elif [[ -f /usr/local/bin/act_runner ]]; then
# act_runner exists — update mode
update_runner
else
# Fresh LXC — install mode
install_runner
fi
}
main "$@"