🚀 Enable shared act_runner cache-server 🚀
gitea / release-gitea (push) Failing after 48s

Turned on the act_runner Actions cache instead of leaving it disabled.
The standalone `cache-server` process was already being launched
unconditionally by zz-act_runner.sh but had no `external_secret`, so it
was refusing to start (the binary requires a non-empty secret even
though its own `cache.enabled` field is unused). Wired a shared,
randomly generated secret through the existing REPLACE_* templating
pattern so the "gitea" runner, the cache-server, and the extra
runner-N daemons spawned by start-runners all share one cache backend.

- rootfs/tmp/etc/act_runner/default_config.yaml: cache.enabled: true;
  added external_server (pointed at the local cache-server) and
  external_secret placeholders
- rootfs/tmp/etc/act_runner/cache_server.yaml: cache.enabled: true;
  added external_secret placeholder (required for the binary to start)
- rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh: added
  __gen_cache_secret() (mirrors __gen_auth_token's persisted-token
  pattern, stored at $CONF_DIR/tokens/cache_secret); substitutes
  REPLACE_RUNNER_CACHE_SECRET into both the runner config and the
  cache-server config; exports RUNNER_CACHE_HOST/PORT/SECRET for
  start-runners; bumped version stamp
- rootfs/usr/local/bin/start-runners: generates a shared
  runners-cache.yaml from the exported cache env vars and passes
  --config to both `act_runner register` and `act_runner daemon` for
  every runner-N instance, so they use the same external cache server
  instead of an unshared per-process local cache
- TODO.AI.md: logged pre-existing script-lint findings (missing `--`
  before grep queries throughout zz-act_runner.sh, a UUOC in
  start-runners, an unpinned/stale docker.yaml CI workflow, and
  forbidden OCI labels in the Dockerfile) surfaced incidentally by the
  lint pass for this change but out of scope for it
This commit is contained in:
2026-08-03 11:57:10 -04:00
parent 4787512bf0
commit 6a3a9bde14
5 changed files with 68 additions and 5 deletions
+17
View File
@@ -0,0 +1,17 @@
# TODO.AI.md
## Lint cleanup — pre-existing script-lint violations (found incidentally while wiring act_runner cache-server)
Not fixed yet — out of scope for the cache-enablement change; flagged by `script-lint` agent.
- `rootfs/usr/local/bin/start-runners`:
- line 24: UUOC — `echo "$SERVER_ADDRESS" | grep -q '://'` should be `[[ "$SERVER_ADDRESS" == *"://"* ]]`
- line 24: `grep -q '://'` missing `--` before query
- `rootfs/usr/local/etc/docker/init.d/zz-act_runner.sh`:
- line 4: `##@Version` header present but no matching `VERSION=` assignment in script body
- missing `--` before the grep query at lines 124 (x2), 130, 133, 134, 369, 390, 401, 438, 468, 525 (x2), 544 (x2, also should quote the `grep` pattern), 571, 583
## Other observations not yet actioned
- `.gitea/workflows/docker.yaml` uses the same stale/unpinned action pattern (`@v2`-`@v4`, DockerHub-only, `catthehacker/ubuntu:act-latest`) that was removed from the `opengist` repo's duplicate workflow — no `build.yml` counterpart exists here yet.
- `Dockerfile` sets forbidden OCI labels (`org.opencontainers.image.base.name`, `.schema-version`, duplicate `authors`) — same issue previously found and fixed in `opengist`.
+2 -1
View File
@@ -2,7 +2,8 @@ log:
level: warn level: warn
cache: cache:
enabled: false enabled: true
dir: 'REPLACE_RUNNER_CACHE_DIR' dir: 'REPLACE_RUNNER_CACHE_DIR'
host: '0.0.0.0' host: '0.0.0.0'
port: REPLACE_RUNNER_CACHE_PORT port: REPLACE_RUNNER_CACHE_PORT
external_secret: 'REPLACE_RUNNER_CACHE_SECRET'
@@ -66,4 +66,6 @@ container:
docker_host: '' docker_host: ''
cache: cache:
enabled: false enabled: true
external_server: 'http://REPLACE_RUNNER_CACHE_HOST:REPLACE_RUNNER_CACHE_PORT/'
external_secret: 'REPLACE_RUNNER_CACHE_SECRET'
+19 -2
View File
@@ -47,18 +47,33 @@ __log "Starting $RUNNERS_START act_runner instance(s)"
__log "Server Address: $SERVER_ADDRESS" __log "Server Address: $SERVER_ADDRESS"
__log "Runner Name Prefix: ${RUNNER_NAME_PREFIX:-runner}" __log "Runner Name Prefix: ${RUNNER_NAME_PREFIX:-runner}"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Shared cache config so runner-N instances use the same cache-server
# started by zz-act_runner.sh instead of an unshared per-process cache.
RUNNERS_CACHE_CONFIG=""
if [ -n "$RUNNER_CACHE_HOST" ] && [ -n "$RUNNER_CACHE_PORT" ] && [ -n "$RUNNER_CACHE_SECRET" ]; then
RUNNERS_CACHE_CONFIG="/config/act_runner/runners-cache.yaml"
cat <<EOF >"$RUNNERS_CACHE_CONFIG"
cache:
enabled: true
external_server: 'http://${RUNNER_CACHE_HOST}:${RUNNER_CACHE_PORT}/'
external_secret: '${RUNNER_CACHE_SECRET}'
EOF
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Register a single runner synchronously (no daemon start) # Register a single runner synchronously (no daemon start)
__register_runner() { __register_runner() {
local runner_id=$1 local runner_id=$1
local runner_name="${RUNNER_NAME_PREFIX:-runner}-${runner_id}" local runner_name="${RUNNER_NAME_PREFIX:-runner}-${runner_id}"
local runner_dir="/config/act_runner/reg/${runner_name}" local runner_dir="/config/act_runner/reg/${runner_name}"
local config_args=()
mkdir -p "$runner_dir" mkdir -p "$runner_dir"
[ -d "$runner_dir" ] && cd "$runner_dir" || return 1 [ -d "$runner_dir" ] && cd "$runner_dir" || return 1
[ -n "$RUNNERS_CACHE_CONFIG" ] && config_args=(--config "$RUNNERS_CACHE_CONFIG")
if [ ! -f "$runner_dir/.runner" ]; then if [ ! -f "$runner_dir/.runner" ]; then
__log "Registering runner: $runner_name (ID: $runner_id)" __log "Registering runner: $runner_name (ID: $runner_id)"
act_runner register --instance "$SERVER_ADDRESS" --token "$SERVER_TOKEN" --name "$runner_name" --labels "$RUNNER_LABELS" --no-interactive act_runner register "${config_args[@]}" --instance "$SERVER_ADDRESS" --token "$SERVER_TOKEN" --name "$runner_name" --labels "$RUNNER_LABELS" --no-interactive
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
__log "ERROR: Failed to register runner $runner_name" __log "ERROR: Failed to register runner $runner_name"
return 1 return 1
@@ -72,10 +87,12 @@ __start_runner_daemon() {
local runner_id=$1 local runner_id=$1
local runner_name="${RUNNER_NAME_PREFIX:-runner}-${runner_id}" local runner_name="${RUNNER_NAME_PREFIX:-runner}-${runner_id}"
local runner_dir="/config/act_runner/reg/${runner_name}" local runner_dir="/config/act_runner/reg/${runner_name}"
local config_args=()
[ -d "$runner_dir" ] && cd "$runner_dir" || return 1 [ -d "$runner_dir" ] && cd "$runner_dir" || return 1
[ -n "$RUNNERS_CACHE_CONFIG" ] && config_args=(--config "$RUNNERS_CACHE_CONFIG")
__log "Starting daemon for runner: $runner_name" __log "Starting daemon for runner: $runner_name"
exec act_runner daemon exec act_runner daemon "${config_args[@]}"
} }
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Phase 1: register all runners sequentially so IDs are assigned in order # Phase 1: register all runners sequentially so IDs are assigned in order
@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# shellcheck shell=bash # shellcheck shell=bash
# - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - -
##@Version : 202606261600-git ##@Version : 202608031200-git
# @@Author : Jason Hempstead # @@Author : Jason Hempstead
# @@Contact : jason@casjaysdev.pro # @@Contact : jason@casjaysdev.pro
# @@License : LICENSE.md # @@License : LICENSE.md
@@ -142,6 +142,26 @@ __gen_auth_token() {
return $exitCode return $exitCode
} }
# - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - -
# shared secret between the runner(s) and the standalone cache-server
__gen_cache_secret() {
local secret token_dir exitCode
exitCode=1
token_dir="$CONF_DIR/tokens"
mkdir -p "$token_dir" >/dev/null 2>&1
if [ -n "$RUNNER_CACHE_SECRET" ]; then
secret="$RUNNER_CACHE_SECRET"
elif [ -s "$token_dir/cache_secret" ]; then
secret="$(<"$token_dir/cache_secret")"
fi
[ -z "$secret" ] && secret="$(__random_password 32)"
if [ -n "$secret" ]; then
exitCode=0
echo "$secret"
echo "$secret" >"$token_dir/cache_secret"
fi
return $exitCode
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Script to execute # Script to execute
START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME"
# - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -305,6 +325,7 @@ RUNNER_DAEMON_LOG="${RUNNER_DAEMON_LOG:-$LOG_DIR/daemon.log}"
RUNNER_CACHE_HOST="${RUNNER_CACHE_HOST:-$IP4_ADDRESS}" RUNNER_CACHE_HOST="${RUNNER_CACHE_HOST:-$IP4_ADDRESS}"
CACHE_CONFIG_FILE="${CACHE_CONFIG_FILE:-$CONF_DIR/cache_server.yaml}" CACHE_CONFIG_FILE="${CACHE_CONFIG_FILE:-$CONF_DIR/cache_server.yaml}"
CACHE_LOG_FILE="${CACHE_LOG_FILE:-$LOG_DIR/cache.log}" CACHE_LOG_FILE="${CACHE_LOG_FILE:-$LOG_DIR/cache.log}"
RUNNER_CACHE_SECRET="${RUNNER_CACHE_SECRET:-}"
# - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - -
# Additional variables # Additional variables
@@ -384,6 +405,7 @@ __run_pre_execute_checks() {
[ -d "$DATA_DIR/cache" ] || mkdir -p "$DATA_DIR/cache" [ -d "$DATA_DIR/cache" ] || mkdir -p "$DATA_DIR/cache"
[ -d "$CONF_DIR/tokens" ] || mkdir -p "$CONF_DIR/tokens" [ -d "$CONF_DIR/tokens" ] || mkdir -p "$CONF_DIR/tokens"
SYS_AUTH_TOKEN="${SYS_AUTH_TOKEN:-$(__gen_auth_token)}" SYS_AUTH_TOKEN="${SYS_AUTH_TOKEN:-$(__gen_auth_token)}"
RUNNER_CACHE_SECRET="${RUNNER_CACHE_SECRET:-$(__gen_cache_secret)}"
if [ -f "$RUNNER_CONFIG_DEFAULT" ]; then if [ -f "$RUNNER_CONFIG_DEFAULT" ]; then
mkdir -p "$RUNNER_DEFAULT_HOME" "$TMP_DIR/runners/gitea" mkdir -p "$RUNNER_DEFAULT_HOME" "$TMP_DIR/runners/gitea"
[ -f "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME" ] || copy "$RUNNER_CONFIG_DEFAULT" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME" [ -f "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME" ] || copy "$RUNNER_CONFIG_DEFAULT" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME"
@@ -392,6 +414,7 @@ __run_pre_execute_checks() {
__replace "REPLACE_RUNNER_HOME" "$RUNNER_DEFAULT_HOME" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME" __replace "REPLACE_RUNNER_HOME" "$RUNNER_DEFAULT_HOME" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME"
__replace "REPLACE_RUNNER_CACHE_HOST" "$RUNNER_CACHE_HOST" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME" __replace "REPLACE_RUNNER_CACHE_HOST" "$RUNNER_CACHE_HOST" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME"
__replace "REPLACE_RUNNER_CACHE_PORT" "$RUNNER_CACHE_PORT" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME" __replace "REPLACE_RUNNER_CACHE_PORT" "$RUNNER_CACHE_PORT" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME"
__replace "REPLACE_RUNNER_CACHE_SECRET" "$RUNNER_CACHE_SECRET" "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME"
if [ ! -f "$RUNNER_DEFAULT_HOME/runners" ] && [ -n "$SYS_AUTH_TOKEN" ]; then if [ ! -f "$RUNNER_DEFAULT_HOME/runners" ] && [ -n "$SYS_AUTH_TOKEN" ]; then
echo "creating gitea runner in $RUNNER_DEFAULT_HOME and registering with http://$INSTANCE_HOSTNAME" echo "creating gitea runner in $RUNNER_DEFAULT_HOME and registering with http://$INSTANCE_HOSTNAME"
act_runner register --config "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME" --labels "$RUNNER_LABELS" --name "gitea" --instance "http://$RUNNER_IP_ADDRESS:$GITEA_PORT" --token "$SYS_AUTH_TOKEN" --no-interactive >>"$RUNNER_LOG_FILE" 2>&1 & act_runner register --config "$RUNNER_DEFAULT_HOME/$RUNNER_CONFIG_NAME" --labels "$RUNNER_LABELS" --name "gitea" --instance "http://$RUNNER_IP_ADDRESS:$GITEA_PORT" --token "$SYS_AUTH_TOKEN" --no-interactive >>"$RUNNER_LOG_FILE" 2>&1 &
@@ -485,6 +508,8 @@ __post_execute() {
local postMessageEnd="Finished post commands for $SERVICE_NAME" local postMessageEnd="Finished post commands for $SERVICE_NAME"
export RUNNERS_START="${RUNNERS_START:-5}" RUNNER_LABELS RUNNERS_LOG_DIR="$LOG_DIR" export RUNNERS_START="${RUNNERS_START:-5}" RUNNER_LABELS RUNNERS_LOG_DIR="$LOG_DIR"
export SERVER_ADDRESS="$RUNNER_IP_ADDRESS:$GITEA_PORT" SERVER_TOKEN="${RUNNER_AUTH_TOKEN:-$SYS_AUTH_TOKEN}" export SERVER_ADDRESS="$RUNNER_IP_ADDRESS:$GITEA_PORT" SERVER_TOKEN="${RUNNER_AUTH_TOKEN:-$SYS_AUTH_TOKEN}"
export RUNNER_CACHE_HOST RUNNER_CACHE_PORT
export RUNNER_CACHE_SECRET="${RUNNER_CACHE_SECRET:-$(__gen_cache_secret)}"
# wait # wait
sleep $waitTime sleep $waitTime
@@ -512,6 +537,7 @@ __post_execute() {
mkdir -p "$DATA_DIR/cache" mkdir -p "$DATA_DIR/cache"
__replace "REPLACE_RUNNER_CACHE_DIR" "$DATA_DIR/cache" "$CACHE_CONFIG_FILE" __replace "REPLACE_RUNNER_CACHE_DIR" "$DATA_DIR/cache" "$CACHE_CONFIG_FILE"
__replace "REPLACE_RUNNER_CACHE_PORT" "$RUNNER_CACHE_PORT" "$CACHE_CONFIG_FILE" __replace "REPLACE_RUNNER_CACHE_PORT" "$RUNNER_CACHE_PORT" "$CACHE_CONFIG_FILE"
__replace "REPLACE_RUNNER_CACHE_SECRET" "$RUNNER_CACHE_SECRET" "$CACHE_CONFIG_FILE"
act_runner cache-server --config "$CACHE_CONFIG_FILE" 2>>/dev/stderr >>"$CACHE_LOG_FILE" & act_runner cache-server --config "$CACHE_CONFIG_FILE" 2>>/dev/stderr >>"$CACHE_LOG_FILE" &
execPid=$! execPid=$!
sleep 5 sleep 5