gitea-runner: detect existing LXC on re-run, refresh OS on update

Ports openbao's host-side update path to gitea-runner: main() now uses
find_existing_lxc (hostname/tag match) to switch into a new update_lxc()
instead of always recreating the container, with an explicit --update
dispatch case reaching update_runner() (previously inferred only from
/usr/local/bin/act_runner presence). require_root is ported from openbao
for the host-side pct branch.

Extracted a small exec_in_lxc() helper (option a from the two offered)
rather than duplicating the curl-pipe invocation, since main() now needs
to drive both the create and update paths through the same piping logic
with only the trailing --install/--update flag differing — matching
openbao's own exec_in_lxc for consistency.

update_runner() now calls refresh_os_packages before touching the binary,
mirroring openbao's update_inside_lxc(). Also switched create_lxc's LXC
tag from the hardcoded "cicd" to the LXC_TAG variable (added in the prior
commit but unused until now) so find_existing_lxc's tag match actually
works.

Documented the OS-refresh-on-update behavior in both READMEs.

Closes #15
This commit is contained in:
Damien
2026-07-30 11:28:14 +02:00
parent 51f2474db6
commit 294960f44d
3 changed files with 74 additions and 10 deletions
+1 -1
View File
@@ -60,7 +60,7 @@ From inside the LXC:
curl -fsSL https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/main/gitea-runner/install.sh | bash curl -fsSL https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/main/gitea-runner/install.sh | bash
``` ```
The script detects that act_runner is already installed and switches to update mode automatically. The script detects that act_runner is already installed and switches to update mode automatically. Re-running from the Proxmox host does the same, plus refreshes the LXC's Alpine packages first (`apk update && apk upgrade`).
### Architecture ### Architecture
+70 -8
View File
@@ -32,6 +32,14 @@ log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
require_root() {
if [[ "$(id -u)" -ne 0 ]]; then
log_error "This script must be run as root (current uid: $(id -u))."
log_error "On Proxmox, launch it from the host shell or via the Web UI shell, both of which run as root."
exit 1
fi
}
# ============================================================ # ============================================================
# Load shared helpers (lib/common.sh: detect_latest_alpine_template, # Load shared helpers (lib/common.sh: detect_latest_alpine_template,
# enable_tty1_autologin, find_existing_lxc, refresh_os_packages). # enable_tty1_autologin, find_existing_lxc, refresh_os_packages).
@@ -87,6 +95,22 @@ download_runner() {
echo "$release" > "$VERSION_FILE" echo "$release" > "$VERSION_FILE"
} }
# Inject the script into the container and execute it in the requested mode.
# Forwards the runtime configuration the inner invocation needs to reproduce
# what the user requested on the host (mirrors openbao/install.sh's helper
# of the same name).
exec_in_lxc() {
local ctid="$1"
local mode="$2" # --install or --update
pct exec "$ctid" -- sh -c "apk add --no-cache bash curl jq > /dev/null 2>&1"
curl -fsSL "$SCRIPT_URL" \
| pct exec "$ctid" -- env \
SCRIPT_URL="$SCRIPT_URL" \
GITEA_HOSTNAME="$GITEA_HOSTNAME" \
bash -s -- "$mode"
}
# ============================================================ # ============================================================
# MODE 1: Proxmox host — create LXC container # MODE 1: Proxmox host — create LXC container
# ============================================================ # ============================================================
@@ -121,7 +145,7 @@ create_lxc() {
--net0 "name=eth0,bridge=${BRIDGE},ip=dhcp" \ --net0 "name=eth0,bridge=${BRIDGE},ip=dhcp" \
--unprivileged 1 \ --unprivileged 1 \
--features nesting=1,keyctl=1 \ --features nesting=1,keyctl=1 \
--tags "infra-script,cicd" \ --tags "infra-script,${LXC_TAG}" \
--start 0 --start 0
log_info "Configuring LXC for Docker and Tailscale..." log_info "Configuring LXC for Docker and Tailscale..."
@@ -137,8 +161,7 @@ EOF
sleep 5 sleep 5
log_info "Injecting install script into container..." log_info "Injecting install script into container..."
pct exec "$CTID" -- sh -c "apk add --no-cache bash curl jq > /dev/null 2>&1" exec_in_lxc "$CTID" "--install"
curl -fsSL "$SCRIPT_URL" | pct exec "$CTID" -- bash -s -- --install
local ip local ip
ip=$(pct exec "$CTID" -- ip -4 addr show eth0 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1) ip=$(pct exec "$CTID" -- ip -4 addr show eth0 2>/dev/null | awk '/inet /{print $2}' | cut -d/ -f1)
@@ -159,6 +182,28 @@ EOF
echo "" echo ""
} }
# ============================================================
# MODE 1b: Proxmox host — update an existing LXC
# ============================================================
update_lxc() {
local ctid="$1"
log_info "=== Gitea Act Runner — updating existing LXC ${ctid} ==="
if ! pct status "$ctid" | grep -q running; then
log_info "Starting LXC ${ctid}..."
pct start "$ctid"
sleep 3
fi
log_info "Refreshing Alpine packages inside LXC ${ctid}..."
pct exec "$ctid" -- sh -c "apk update >/dev/null && apk upgrade >/dev/null"
log_info "Upgrading act_runner binary inside LXC ${ctid}..."
exec_in_lxc "$ctid" "--update"
log_info "Update of LXC ${ctid} complete."
}
# ============================================================ # ============================================================
# MODE 2: Inside LXC — fresh install # MODE 2: Inside LXC — fresh install
# ============================================================ # ============================================================
@@ -284,6 +329,8 @@ LOGROTATE
update_runner() { update_runner() {
log_info "=== Gitea Act Runner — Update ===" log_info "=== Gitea Act Runner — Update ==="
refresh_os_packages
local release local release
release=$(get_latest_release) release=$(get_latest_release)
@@ -314,12 +361,27 @@ update_runner() {
# Main — detect context # Main — detect context
# ============================================================ # ============================================================
main() { main() {
if [[ "${1:-}" == "--install" ]]; then case "${1:-}" in
# Explicitly called in install mode (from pct exec) --install)
install_runner install_runner
elif command -v pct &> /dev/null; then return
;;
--update)
update_runner
return
;;
esac
if command -v pct &> /dev/null; then
# We're on the Proxmox host # We're on the Proxmox host
create_lxc require_root
local existing=""
if existing=$(find_existing_lxc); then
log_info "Found existing gitea-runner LXC (CTID ${existing}, hostname/tag match) — switching to update mode."
update_lxc "$existing"
else
create_lxc
fi
elif [[ -f /usr/local/bin/act_runner ]]; then elif [[ -f /usr/local/bin/act_runner ]]; then
# act_runner exists — update mode # act_runner exists — update mode
update_runner update_runner
+3 -1
View File
@@ -110,7 +110,9 @@ curl -fsSL https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/feat/lxc-Open
The script auto-detects the presence of `/usr/local/bin/bao` and switches to The script auto-detects the presence of `/usr/local/bin/bao` and switches to
update mode. The OpenRC service is stopped, the binary is swapped (the old one update mode. The OpenRC service is stopped, the binary is swapped (the old one
is kept as `bao.bak.<ts>`), then the service is restarted. is kept as `bao.bak.<ts>`), then the service is restarted. Re-running from the
Proxmox host does the same, plus refreshes the LXC's Alpine packages first
(`apk update && apk upgrade`).
### Architecture ### Architecture