406 lines
14 KiB
Bash
Executable File
406 lines
14 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Non-secret installer for the 188 user-level AWOOOI runner service. It never
|
|
# registers a runner, never reads .runner contents, and does not start the
|
|
# service unless --enable is explicitly requested after registration exists.
|
|
|
|
RUNNER_USER="${RUNNER_USER:-$(id -un)}"
|
|
RUNNER_HOME="${RUNNER_HOME:-${HOME}}"
|
|
RUNNER_DIR="${RUNNER_DIR:-${RUNNER_HOME}/act-runner-awoooi}"
|
|
RUNNER_BINARY="${RUNNER_BINARY:-${RUNNER_DIR}/act_runner}"
|
|
RUNNER_CONFIG="${RUNNER_CONFIG:-${RUNNER_DIR}/config.yaml}"
|
|
RUNNER_REGISTRATION="${RUNNER_REGISTRATION:-${RUNNER_DIR}/.runner}"
|
|
ENABLE_SENTINEL="${ENABLE_SENTINEL:-${RUNNER_DIR}/.awoooi-non110-runner-enabled}"
|
|
SERVICE_NAME="${SERVICE_NAME:-awoooi-non110-runner.service}"
|
|
ROLLBACK_SERVICE_NAME="${ROLLBACK_SERVICE_NAME:-awoooi-non110-runner-rollback.service}"
|
|
AUTOSTART_SERVICE_NAME="${AUTOSTART_SERVICE_NAME:-awoooi-non110-runner-autostart.service}"
|
|
AUTOSTART_PATH_NAME="${AUTOSTART_PATH_NAME:-awoooi-non110-runner-autostart.path}"
|
|
KEEPALIVE_SERVICE_NAME="${KEEPALIVE_SERVICE_NAME:-awoooi-non110-runner-keepalive.service}"
|
|
KEEPALIVE_TIMER_NAME="${KEEPALIVE_TIMER_NAME:-awoooi-non110-runner-keepalive.timer}"
|
|
KEEPALIVE_INTERVAL_SECONDS="${KEEPALIVE_INTERVAL_SECONDS:-15}"
|
|
USER_SERVICE_DIR="${USER_SERVICE_DIR:-${RUNNER_HOME}/.config/systemd/user}"
|
|
RUNNER_LABELS="${RUNNER_LABELS:-awoooi-non110-host:host,awoooi-non110-ubuntu:docker://192.168.0.110:5000/awoooi/ci-runner:act-22.04}"
|
|
WRITE_CONFIG_IF_MISSING="${WRITE_CONFIG_IF_MISSING:-1}"
|
|
RESTORE_BINARY_IF_MISSING="${RESTORE_BINARY_IF_MISSING:-1}"
|
|
CPU_QUOTA="${CPU_QUOTA:-200%}"
|
|
MEMORY_HIGH="${MEMORY_HIGH:-6G}"
|
|
MEMORY_MAX="${MEMORY_MAX:-8G}"
|
|
TASKS_MAX="${TASKS_MAX:-512}"
|
|
PRESSURE_GUARD="${PRESSURE_GUARD:-${RUNNER_HOME}/.local/bin/awoooi-wait-host-web-build-pressure.sh}"
|
|
PRESSURE_GUARD_ATTEMPTS="${PRESSURE_GUARD_ATTEMPTS:-1}"
|
|
PRESSURE_GUARD_SLEEP_SECONDS="${PRESSURE_GUARD_SLEEP_SECONDS:-0}"
|
|
|
|
ACTION="check"
|
|
if [ "$#" -gt 0 ]; then
|
|
case "$1" in
|
|
--check|--apply|--enable|--rollback)
|
|
ACTION="${1#--}"
|
|
shift
|
|
;;
|
|
*)
|
|
echo "usage: $0 [--check|--apply|--enable|--rollback]" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
service_path() {
|
|
printf '%s/%s\n' "$USER_SERVICE_DIR" "$SERVICE_NAME"
|
|
}
|
|
|
|
rollback_service_path() {
|
|
printf '%s/%s\n' "$USER_SERVICE_DIR" "$ROLLBACK_SERVICE_NAME"
|
|
}
|
|
|
|
autostart_service_path() {
|
|
printf '%s/%s\n' "$USER_SERVICE_DIR" "$AUTOSTART_SERVICE_NAME"
|
|
}
|
|
|
|
autostart_path_path() {
|
|
printf '%s/%s\n' "$USER_SERVICE_DIR" "$AUTOSTART_PATH_NAME"
|
|
}
|
|
|
|
keepalive_service_path() {
|
|
printf '%s/%s\n' "$USER_SERVICE_DIR" "$KEEPALIVE_SERVICE_NAME"
|
|
}
|
|
|
|
keepalive_timer_path() {
|
|
printf '%s/%s\n' "$USER_SERVICE_DIR" "$KEEPALIVE_TIMER_NAME"
|
|
}
|
|
|
|
metadata_path() {
|
|
local path="$1"
|
|
if [ -e "$path" ]; then
|
|
stat -c 'PATH=%n exists=1 type=%F mode=%a size=%s' "$path" 2>/dev/null || printf 'PATH=%s exists=1 stat=unavailable\n' "$path"
|
|
return 0
|
|
fi
|
|
printf 'PATH=%s exists=0\n' "$path"
|
|
}
|
|
|
|
write_runner_service() {
|
|
cat >"$(service_path)" <<EOF
|
|
[Unit]
|
|
Description=AWOOOI non-110 Gitea runner user service, capacity 1
|
|
After=default.target
|
|
ConditionPathExists=${ENABLE_SENTINEL}
|
|
ConditionPathExists=${RUNNER_CONFIG}
|
|
ConditionPathExists=${RUNNER_REGISTRATION}
|
|
|
|
[Service]
|
|
Type=simple
|
|
WorkingDirectory=${RUNNER_DIR}
|
|
Environment=HOME=${RUNNER_HOME}
|
|
ExecStartPre=/usr/bin/test -x ${RUNNER_BINARY}
|
|
ExecStartPre=/usr/bin/test -S /var/run/docker.sock
|
|
ExecStartPre=/usr/bin/test -x ${PRESSURE_GUARD}
|
|
ExecStartPre=/usr/bin/env HOST_WEB_BUILD_PRESSURE_ATTEMPTS=${PRESSURE_GUARD_ATTEMPTS} HOST_WEB_BUILD_PRESSURE_SLEEP_SECONDS=${PRESSURE_GUARD_SLEEP_SECONDS} ${PRESSURE_GUARD}
|
|
ExecStart=${RUNNER_BINARY} daemon --config ${RUNNER_CONFIG}
|
|
Restart=always
|
|
RestartSec=20
|
|
KillSignal=SIGINT
|
|
TimeoutStartSec=120
|
|
TimeoutStopSec=3700
|
|
CPUQuota=${CPU_QUOTA}
|
|
MemoryHigh=${MEMORY_HIGH}
|
|
MemoryMax=${MEMORY_MAX}
|
|
TasksMax=${TASKS_MAX}
|
|
NoNewPrivileges=true
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
EOF
|
|
}
|
|
|
|
write_default_config() {
|
|
if [ "$WRITE_CONFIG_IF_MISSING" != "1" ] || [ -s "$RUNNER_CONFIG" ]; then
|
|
return 0
|
|
fi
|
|
umask 077
|
|
cat >"$RUNNER_CONFIG" <<EOF
|
|
log:
|
|
level: info
|
|
|
|
runner:
|
|
file: ${RUNNER_REGISTRATION}
|
|
capacity: 1
|
|
envs: {}
|
|
env_file: ""
|
|
timeout: 3h
|
|
shutdown_timeout: 1h
|
|
insecure: false
|
|
fetch_timeout: 5s
|
|
fetch_interval: 2s
|
|
fetch_interval_max: 5s
|
|
labels:
|
|
$(printf '%s' "$RUNNER_LABELS" | tr ',' '\n' | awk '{ printf " - \"%s\"\n", $0 }')
|
|
|
|
cache:
|
|
enabled: false
|
|
|
|
container:
|
|
network: ""
|
|
privileged: false
|
|
valid_volumes: []
|
|
docker_host: "unix:///var/run/docker.sock"
|
|
force_pull: false
|
|
force_rebuild: false
|
|
require_docker: true
|
|
|
|
host:
|
|
workdir_parent: ${RUNNER_DIR}/host-workdir
|
|
|
|
metrics:
|
|
enabled: false
|
|
addr: "127.0.0.1:9101"
|
|
EOF
|
|
printf 'CONFIG_WRITE_PERFORMED=1 path=%s secret_values_collected=false\n' "$RUNNER_CONFIG"
|
|
}
|
|
|
|
restore_binary_from_disabled() {
|
|
if [ "$RESTORE_BINARY_IF_MISSING" != "1" ] || [ -x "$RUNNER_BINARY" ]; then
|
|
return 0
|
|
fi
|
|
local source=""
|
|
if [ -n "${ACT_RUNNER_SOURCE:-}" ]; then
|
|
source="$ACT_RUNNER_SOURCE"
|
|
else
|
|
source="$(find "$RUNNER_HOME" -maxdepth 1 -type d -name "$(basename "$RUNNER_DIR")-disabled-*" -print 2>/dev/null \
|
|
| sort -r \
|
|
| while IFS= read -r dir; do
|
|
if [ -x "${dir}/act_runner" ]; then
|
|
printf '%s/act_runner\n' "$dir"
|
|
break
|
|
fi
|
|
done)"
|
|
fi
|
|
if [ -n "$source" ] && [ -x "$source" ]; then
|
|
install -m 0755 "$source" "$RUNNER_BINARY"
|
|
printf 'BINARY_RESTORE_PERFORMED=1 source=%s target=%s\n' "$source" "$RUNNER_BINARY"
|
|
return 0
|
|
fi
|
|
printf 'BINARY_RESTORE_PERFORMED=0 reason=no_disabled_binary_source target=%s\n' "$RUNNER_BINARY"
|
|
}
|
|
|
|
write_rollback_service() {
|
|
cat >"$(rollback_service_path)" <<EOF
|
|
[Unit]
|
|
Description=Rollback AWOOOI non-110 user Gitea runner to inactive
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=-/usr/bin/systemctl --user stop ${SERVICE_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user disable ${SERVICE_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user reset-failed ${SERVICE_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user stop ${KEEPALIVE_TIMER_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user disable ${KEEPALIVE_TIMER_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user stop ${KEEPALIVE_SERVICE_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user reset-failed ${KEEPALIVE_SERVICE_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user stop ${AUTOSTART_PATH_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user disable ${AUTOSTART_PATH_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user reset-failed ${AUTOSTART_SERVICE_NAME}
|
|
ExecStart=-/usr/bin/rm -f ${ENABLE_SENTINEL}
|
|
RemainAfterExit=no
|
|
EOF
|
|
}
|
|
|
|
write_autostart_units() {
|
|
cat >"$(autostart_service_path)" <<EOF
|
|
[Unit]
|
|
Description=Enable AWOOOI non-110 runner after registration metadata appears
|
|
ConditionPathExists=!${ENABLE_SENTINEL}
|
|
ConditionPathExists=${RUNNER_CONFIG}
|
|
ConditionPathExists=${RUNNER_REGISTRATION}
|
|
ConditionPathExists=${RUNNER_BINARY}
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/bin/test -x ${RUNNER_BINARY}
|
|
ExecStart=/usr/bin/test -s ${RUNNER_CONFIG}
|
|
ExecStart=/usr/bin/test -s ${RUNNER_REGISTRATION}
|
|
ExecStart=/usr/bin/test -x ${PRESSURE_GUARD}
|
|
ExecStart=/usr/bin/env HOST_WEB_BUILD_PRESSURE_ATTEMPTS=${PRESSURE_GUARD_ATTEMPTS} HOST_WEB_BUILD_PRESSURE_SLEEP_SECONDS=${PRESSURE_GUARD_SLEEP_SECONDS} ${PRESSURE_GUARD}
|
|
ExecStart=/usr/bin/touch ${ENABLE_SENTINEL}
|
|
ExecStart=/usr/bin/systemctl --user reset-failed ${SERVICE_NAME}
|
|
ExecStart=/usr/bin/systemctl --user enable ${SERVICE_NAME}
|
|
ExecStart=/usr/bin/systemctl --user start ${SERVICE_NAME}
|
|
ExecStart=/usr/bin/systemctl --user enable --now ${KEEPALIVE_TIMER_NAME}
|
|
ExecStart=-/usr/bin/systemctl --user disable --now ${AUTOSTART_PATH_NAME}
|
|
RemainAfterExit=no
|
|
EOF
|
|
|
|
cat >"$(autostart_path_path)" <<EOF
|
|
[Unit]
|
|
Description=Watch AWOOOI non-110 runner registration metadata
|
|
|
|
[Path]
|
|
PathExists=${RUNNER_REGISTRATION}
|
|
Unit=${AUTOSTART_SERVICE_NAME}
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
EOF
|
|
}
|
|
|
|
write_keepalive_units() {
|
|
cat >"$(keepalive_service_path)" <<EOF
|
|
[Unit]
|
|
Description=Keep AWOOOI non-110 runner active while enable sentinel exists
|
|
ConditionPathExists=${ENABLE_SENTINEL}
|
|
ConditionPathExists=${RUNNER_CONFIG}
|
|
ConditionPathExists=${RUNNER_REGISTRATION}
|
|
ConditionPathExists=${RUNNER_BINARY}
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/bin/test -x ${RUNNER_BINARY}
|
|
ExecStart=/usr/bin/test -s ${RUNNER_CONFIG}
|
|
ExecStart=/usr/bin/test -s ${RUNNER_REGISTRATION}
|
|
ExecStart=/usr/bin/test -x ${PRESSURE_GUARD}
|
|
ExecStart=/usr/bin/env HOST_WEB_BUILD_PRESSURE_ATTEMPTS=${PRESSURE_GUARD_ATTEMPTS} HOST_WEB_BUILD_PRESSURE_SLEEP_SECONDS=${PRESSURE_GUARD_SLEEP_SECONDS} ${PRESSURE_GUARD}
|
|
ExecStart=/usr/bin/systemctl --user daemon-reload
|
|
ExecStart=-/usr/bin/systemctl --user reset-failed ${SERVICE_NAME}
|
|
ExecStart=/usr/bin/systemctl --user enable ${SERVICE_NAME}
|
|
ExecStart=/usr/bin/systemctl --user start ${SERVICE_NAME}
|
|
RemainAfterExit=no
|
|
EOF
|
|
|
|
cat >"$(keepalive_timer_path)" <<EOF
|
|
[Unit]
|
|
Description=Periodically verify AWOOOI non-110 runner user service is active
|
|
|
|
[Timer]
|
|
OnBootSec=30s
|
|
OnUnitInactiveSec=${KEEPALIVE_INTERVAL_SECONDS}s
|
|
AccuracySec=10s
|
|
Unit=${KEEPALIVE_SERVICE_NAME}
|
|
|
|
[Install]
|
|
WantedBy=timers.target
|
|
EOF
|
|
}
|
|
|
|
systemd_user_reload() {
|
|
systemctl --user daemon-reload
|
|
}
|
|
|
|
readback() {
|
|
printf 'AWOOOI_NON110_USER_INSTALLER action=%s\n' "$ACTION"
|
|
printf 'runner_user=%s\n' "$RUNNER_USER"
|
|
printf 'runner_home=%s\n' "$RUNNER_HOME"
|
|
printf 'runner_dir=%s\n' "$RUNNER_DIR"
|
|
printf 'service_name=%s\n' "$SERVICE_NAME"
|
|
printf 'rollback_service_name=%s\n' "$ROLLBACK_SERVICE_NAME"
|
|
printf 'autostart_service_name=%s\n' "$AUTOSTART_SERVICE_NAME"
|
|
printf 'autostart_path_name=%s\n' "$AUTOSTART_PATH_NAME"
|
|
printf 'keepalive_service_name=%s\n' "$KEEPALIVE_SERVICE_NAME"
|
|
printf 'keepalive_timer_name=%s\n' "$KEEPALIVE_TIMER_NAME"
|
|
printf 'pressure_guard=%s\n' "$PRESSURE_GUARD"
|
|
printf 'pressure_guard_attempts=%s\n' "$PRESSURE_GUARD_ATTEMPTS"
|
|
printf 'pressure_guard_sleep_seconds=%s\n' "$PRESSURE_GUARD_SLEEP_SECONDS"
|
|
printf 'secret_values_collected=false\n'
|
|
printf 'runner_token_read=false\n'
|
|
printf 'raw_runner_registration_read=false\n'
|
|
loginctl show-user "$RUNNER_USER" -p Linger 2>/dev/null || true
|
|
metadata_path "$RUNNER_DIR"
|
|
metadata_path "$RUNNER_BINARY"
|
|
metadata_path "$RUNNER_CONFIG"
|
|
metadata_path "$RUNNER_REGISTRATION"
|
|
metadata_path "$ENABLE_SENTINEL"
|
|
printf 'RUNNER_REGISTRATION content_read=false\n'
|
|
metadata_path "$(service_path)"
|
|
metadata_path "$(rollback_service_path)"
|
|
metadata_path "$(autostart_service_path)"
|
|
metadata_path "$(autostart_path_path)"
|
|
metadata_path "$(keepalive_service_path)"
|
|
metadata_path "$(keepalive_timer_path)"
|
|
systemctl --user show "$SERVICE_NAME" -p LoadState -p ActiveState -p UnitFileState -p MainPID --no-pager 2>/dev/null || true
|
|
systemctl --user show "$ROLLBACK_SERVICE_NAME" -p LoadState -p ActiveState -p UnitFileState -p MainPID --no-pager 2>/dev/null || true
|
|
systemctl --user show "$AUTOSTART_PATH_NAME" -p LoadState -p ActiveState -p UnitFileState -p MainPID --no-pager 2>/dev/null || true
|
|
systemctl --user show "$KEEPALIVE_TIMER_NAME" -p LoadState -p ActiveState -p UnitFileState -p MainPID --no-pager 2>/dev/null || true
|
|
}
|
|
|
|
apply_units() {
|
|
mkdir -p "$RUNNER_DIR" "$USER_SERVICE_DIR"
|
|
restore_binary_from_disabled
|
|
write_default_config
|
|
write_runner_service
|
|
write_rollback_service
|
|
write_autostart_units
|
|
write_keepalive_units
|
|
chmod 0644 \
|
|
"$(service_path)" \
|
|
"$(rollback_service_path)" \
|
|
"$(autostart_service_path)" \
|
|
"$(autostart_path_path)" \
|
|
"$(keepalive_service_path)" \
|
|
"$(keepalive_timer_path)"
|
|
systemd_user_reload
|
|
if registration_ready; then
|
|
printf 'AUTOSTART_PATH_ENABLE_PERFORMED=0 reason=registration_ready_requires_explicit_enable\n'
|
|
else
|
|
systemctl --user enable --now "$AUTOSTART_PATH_NAME" >/dev/null
|
|
printf 'AUTOSTART_PATH_ENABLE_PERFORMED=1\n'
|
|
fi
|
|
printf 'APPLY_PERFORMED=1\n'
|
|
printf 'SERVICE_START_PERFORMED=0\n'
|
|
printf 'SERVICE_ENABLE_PERFORMED=0\n'
|
|
}
|
|
|
|
registration_ready() {
|
|
[ -x "$RUNNER_BINARY" ] && [ -s "$RUNNER_CONFIG" ] && [ -s "$RUNNER_REGISTRATION" ]
|
|
}
|
|
|
|
enable_runner() {
|
|
apply_units
|
|
if [ "${AWOOOI_NON110_ENABLE:-0}" != "1" ]; then
|
|
echo "Refusing --enable without AWOOOI_NON110_ENABLE=1" >&2
|
|
exit 1
|
|
fi
|
|
if ! registration_ready; then
|
|
echo "Refusing --enable: binary/config/.runner metadata is not complete" >&2
|
|
exit 1
|
|
fi
|
|
touch "$ENABLE_SENTINEL"
|
|
systemctl --user reset-failed "$SERVICE_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user reset-failed "$AUTOSTART_SERVICE_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user disable --now "$AUTOSTART_PATH_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user enable --now "$KEEPALIVE_TIMER_NAME"
|
|
systemctl --user enable "$SERVICE_NAME"
|
|
systemctl --user start "$SERVICE_NAME"
|
|
printf 'SERVICE_ENABLE_PERFORMED=1\n'
|
|
printf 'SERVICE_START_PERFORMED=1\n'
|
|
printf 'KEEPALIVE_TIMER_ENABLE_PERFORMED=1\n'
|
|
}
|
|
|
|
rollback_runner() {
|
|
systemctl --user stop "$KEEPALIVE_TIMER_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user disable "$KEEPALIVE_TIMER_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user stop "$KEEPALIVE_SERVICE_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user reset-failed "$KEEPALIVE_SERVICE_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user stop "$SERVICE_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user disable "$SERVICE_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user reset-failed "$SERVICE_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user stop "$AUTOSTART_PATH_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user disable "$AUTOSTART_PATH_NAME" >/dev/null 2>&1 || true
|
|
systemctl --user reset-failed "$AUTOSTART_SERVICE_NAME" >/dev/null 2>&1 || true
|
|
rm -f "$ENABLE_SENTINEL"
|
|
printf 'ROLLBACK_PERFORMED=1\n'
|
|
}
|
|
|
|
case "$ACTION" in
|
|
check)
|
|
;;
|
|
apply)
|
|
apply_units
|
|
;;
|
|
enable)
|
|
enable_runner
|
|
;;
|
|
rollback)
|
|
rollback_runner
|
|
;;
|
|
esac
|
|
|
|
readback
|