Compare commits

...
5 Commits
Author SHA1 Message Date
Damien d86848eb71 openbao,gitea-runner: use shared ensure_template_present, gitea-runner parity fixes
openbao: removed its now-duplicate ensure_template_present() definition,
using the one factored into lib/common.sh (call site unchanged).

gitea-runner: replaced its ad-hoc template-download check (which skipped
`pveam update`, risking a stale cached template list now that the template
is auto-detected) with a call to the shared ensure_template_present().
Also added ca-certificates to exec_in_lxc's apk add, matching openbao, and
added require_root() to the inside-LXC dispatch path in main(), which
openbao already does but gitea-runner was missing.
2026-07-30 14:05:50 +02:00
Damien 936ab2c2fb lib/common.sh: fix refresh_os_packages contract, drop set -e, add ensure_template_present
- refresh_os_packages()'s header claimed it was callable both host-side (via
  pct exec) and inside the LXC; it's a plain bash function in this process,
  it cannot cross a pct exec boundary. Corrected to match the comment
  already present at its one host-side non-call-site in openbao/install.sh.
- Removed `set -euo pipefail`: a sourced file must not impose shell options
  on the caller. Both install scripts already set these before sourcing.
- Added ensure_template_present(), ported from openbao/install.sh, so
  gitea-runner can reuse it (issue #12 follow-up) instead of duplicating a
  template-download check that skipped `pveam update` and could silently
  settle for a stale cached template list.
2026-07-30 14:05:43 +02:00
Damien 3e4ede907e openbao,gitea-runner: fail loudly if lib/common.sh sourcing fails
source <(curl ...) swallows curl failures (404, network error): an empty
stream still makes `source` return 0, so the failure would otherwise only
surface later as a confusing "command not found" for one of lib/common.sh's
functions. Check that a known function landed after the source, and exit 1
with the attempted URL if not.
2026-07-30 13:34:05 +02:00
Damien fef37d2676 gitea-runner: make SCRIPT_URL overridable, matching openbao
Was a fixed value, unlike openbao's SCRIPT_URL="${SCRIPT_URL:-...}". Two
consequences: exec_in_lxc forwarded SCRIPT_URL into the container where it
was immediately overwritten by the hardcoded value, making the forward a
no-op; and the lib/common.sh sourcing fallback derives its fetch URL from
SCRIPT_URL, so it always pointed at main (where lib/common.sh doesn't exist
yet), making this branch untestable end-to-end for gitea-runner.
2026-07-30 13:33:35 +02:00
Damien 82540472ae gitea-runner: fix log_info/warn/error writing to stdout, corrupting TEMPLATE
log_info() etc. wrote to stdout, unlike openbao's identical functions
which write to stderr specifically so $(fn) capture is safe. lib/common.sh's
detect_latest_alpine_template() does `log_info "Selected..."; echo "$tmpl"` —
in gitea-runner, TEMPLATE=$(detect_latest_alpine_template) therefore captured
the log line and ANSI codes along with the template name, breaking both the
pveam list lookup and pct create's template argument.
2026-07-30 13:33:20 +02:00
3 changed files with 68 additions and 31 deletions
+30 -16
View File
@@ -17,7 +17,10 @@ RAM="${RAM:-2048}"
DISK="${DISK:-8}"
BRIDGE="${BRIDGE:-vmbr0}"
LXC_TAG="${LXC_TAG:-gitea-runner}" # stable identifier for the container
SCRIPT_URL="https://gitea.arnodo.fr/Damien/infra-scripts/raw/branch/main/gitea-runner/install.sh"
# SCRIPT_URL is what the host-side flow pipes into the LXC. Override it when
# testing from a non-main branch, e.g.
# SCRIPT_URL="https://gitea.arnodo.fr/.../branch/chore/standardize-lxc-scripts/gitea-runner/install.sh"
SCRIPT_URL="${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"
@@ -28,9 +31,10 @@ 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"; }
# Logs go to stderr so callers can safely use $(fn) without capturing log noise.
log_info() { echo -e "${GREEN}[INFO]${NC} $1" >&2; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" >&2; }
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
require_root() {
if [[ "$(id -u)" -ne 0 ]]; then
@@ -53,10 +57,20 @@ require_root() {
# failure mode.
# ============================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" 2>/dev/null && pwd || true)"
LIB_COMMON_URL="$(dirname "$(dirname "$SCRIPT_URL")")/lib/common.sh"
if [[ -n "$SCRIPT_DIR" && -f "${SCRIPT_DIR}/../lib/common.sh" ]]; then
source "${SCRIPT_DIR}/../lib/common.sh"
else
source <(curl -fsSL "$(dirname "$(dirname "$SCRIPT_URL")")/lib/common.sh")
source <(curl -fsSL "$LIB_COMMON_URL")
fi
# `source <(curl ...)` swallows curl failures: an empty stream still makes
# `source` return 0, so a 404/network error would otherwise only surface
# later as a confusing "command not found" for detect_latest_alpine_template
# et al. Fail loudly here instead, with the URL that was tried.
if ! declare -F detect_latest_alpine_template >/dev/null; then
log_error "Failed to load lib/common.sh (tried: ${LIB_COMMON_URL})."
exit 1
fi
# --- Helpers ---
@@ -103,7 +117,7 @@ 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"
pct exec "$ctid" -- sh -c "apk add --no-cache bash curl jq ca-certificates > /dev/null 2>&1"
curl -fsSL "$SCRIPT_URL" \
| pct exec "$ctid" -- env \
SCRIPT_URL="$SCRIPT_URL" \
@@ -130,11 +144,7 @@ create_lxc() {
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
ensure_template_present "$TEMPLATE"
log_info "Creating LXC $CTID ($HOSTNAME_LXC)..."
pct create "$CTID" "${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE}" \
@@ -382,12 +392,16 @@ main() {
else
create_lxc
fi
elif [[ -f /usr/local/bin/act_runner ]]; then
# act_runner exists — update mode
update_runner
else
# Fresh LXC — install mode
install_runner
# Inside a container (no Proxmox tooling)
require_root
if [[ -f /usr/local/bin/act_runner ]]; then
# act_runner exists — update mode
update_runner
else
# Fresh LXC — install mode
install_runner
fi
fi
}
+27 -3
View File
@@ -17,8 +17,10 @@
# config`. Reusable as-is by any LXC creator script.
# - refresh_os_packages(): Alpine only (apk update && apk upgrade). A
# future Debian-based script needs its own apt-get variant.
set -euo pipefail
#
# Does not set shell options (set -e/-u/-o pipefail): a sourced file must
# not impose those on the caller's shell. Both openbao/install.sh and
# gitea-runner/install.sh already set them before sourcing this file.
# ============================================================
# #12 - Detect newest Alpine LXC template available from the Proxmox repos.
@@ -65,6 +67,23 @@ enable_tty1_autologin() {
pkill -KILL -f '(getty|agetty).*tty1' 2>/dev/null || true
}
# ============================================================
# #12 - Ensure the given template is downloaded to TEMPLATE_STORAGE, doing a
# `pveam update` first so a stale local cache doesn't silently settle for an
# older version than the one detect_latest_alpine_template() just picked.
# Expects TEMPLATE_STORAGE to be set by the caller.
# ============================================================
ensure_template_present() {
local tmpl="$1"
if ! pveam list "$TEMPLATE_STORAGE" 2>/dev/null | grep -q "$tmpl"; then
log_info "Downloading template ${tmpl} to storage ${TEMPLATE_STORAGE}..."
pveam update >/dev/null
pveam download "$TEMPLATE_STORAGE" "$tmpl"
else
log_info "Template ${tmpl} already present on ${TEMPLATE_STORAGE}."
fi
}
# ============================================================
# #15 - Find an existing LXC by tag or hostname (host-side, requires pct).
# Echoes the CTID on match, returns 1 if none found.
@@ -88,7 +107,12 @@ find_existing_lxc() {
# ============================================================
# #15 - Refresh OS packages (Alpine: apk update && apk upgrade).
# Callable both host-side (via pct exec) and inside the LXC.
# Callable only from inside the LXC: this is a plain bash function in the
# current process, so it cannot run across a `pct exec ... sh -c` boundary
# without shipping its definition into the container. Host-side callers
# (see openbao/install.sh's update_lxc()) invoke apk update/upgrade inline
# via `pct exec` instead — do not try to dedupe that call site onto this
# function.
# ============================================================
refresh_os_packages() {
log_info "Refreshing Alpine packages..."
+11 -12
View File
@@ -73,10 +73,20 @@ log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }
# download the bao binary, so this adds no new failure mode.
# ============================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" 2>/dev/null && pwd || true)"
LIB_COMMON_URL="$(dirname "$(dirname "$SCRIPT_URL")")/lib/common.sh"
if [[ -n "$SCRIPT_DIR" && -f "${SCRIPT_DIR}/../lib/common.sh" ]]; then
source "${SCRIPT_DIR}/../lib/common.sh"
else
source <(curl -fsSL "$(dirname "$(dirname "$SCRIPT_URL")")/lib/common.sh")
source <(curl -fsSL "$LIB_COMMON_URL")
fi
# `source <(curl ...)` swallows curl failures: an empty stream still makes
# `source` return 0, so a 404/network error would otherwise only surface
# later as a confusing "command not found" for detect_latest_alpine_template
# et al. Fail loudly here instead, with the URL that was tried.
if ! declare -F detect_latest_alpine_template >/dev/null; then
log_error "Failed to load lib/common.sh (tried: ${LIB_COMMON_URL})."
exit 1
fi
# ============================================================
@@ -227,17 +237,6 @@ configure_tailscale_proxy() {
# Proxmox-host helpers
# ============================================================
ensure_template_present() {
local tmpl="$1"
if ! pveam list "$TEMPLATE_STORAGE" 2>/dev/null | grep -q "$tmpl"; then
log_info "Downloading template ${tmpl} to storage ${TEMPLATE_STORAGE}..."
pveam update >/dev/null
pveam download "$TEMPLATE_STORAGE" "$tmpl"
else
log_info "Template ${tmpl} already present on ${TEMPLATE_STORAGE}."
fi
}
# Pick next available CTID if user did not provide one.
allocate_ctid() {
pvesh get /cluster/nextid 2>/dev/null \