Add a host-level CI runner + one-click "deploy from scratch" workflow
setup-forgejo-runner.sh gained RUNNER_LABEL/RUNNER_DIR/SERVICE_NAME/ RUNNER_USER params so the same script can register either kind of runner: - inside the container (unchanged defaults, root - already scoped to just that container) - on the Proxmox host itself, where RUNNER_USER=claude-deploy is required: a root-owned systemd service with no User= would hand every CI job unrestricted root on the host, defeating the whole point of claude-deploy's narrowly-scoped sudoers rules. deploy-from-scratch.yml runs create-graylog-lxc.sh on the host-level runner. Deliberately does NOT run pct destroy - that stays a manual, deliberate human step. The idempotent create+install path is safe to trigger any time: repairs an existing container in place, or fully recreates one if it was destroyed beforehand. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
83a3388d41
commit
71ba82e0f0
2 changed files with 71 additions and 14 deletions
36
.forgejo/workflows/deploy-from-scratch.yml
Normal file
36
.forgejo/workflows/deploy-from-scratch.yml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
name: Deploy Graylog from scratch (host-level)
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: proxmox-host
|
||||
steps:
|
||||
# No actions/checkout: same reasoning as deploy.yml - this runner has
|
||||
# no Node.js and shouldn't need one just for CI checkout.
|
||||
#
|
||||
# Destroying the existing container (pct destroy) is deliberately NOT
|
||||
# part of this workflow - that stays a manual, deliberate step run by
|
||||
# a human on the Proxmox host. This workflow only re-runs the
|
||||
# idempotent create+install path, safe to trigger any time: if VMID
|
||||
# 200 already exists it just repairs/updates it in place; if it was
|
||||
# destroyed manually beforehand, this recreates it from scratch.
|
||||
- name: Deploy from scratch
|
||||
env:
|
||||
CI_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run: |
|
||||
rm -rf /tmp/graylog-deploy-ci-host
|
||||
git clone --depth 1 --branch main "https://x-access-token:${CI_TOKEN}@git.zotac.keenetic.link/zotac/graylog-deploy.git" /tmp/graylog-deploy-ci-host
|
||||
cd /tmp/graylog-deploy-ci-host
|
||||
chmod +x create-graylog-lxc.sh
|
||||
./create-graylog-lxc.sh \
|
||||
--vmid 200 \
|
||||
--ip 10.254.254.202/24 \
|
||||
--gw 10.254.254.235 \
|
||||
--vlan 1254 \
|
||||
--disk 50 \
|
||||
--template-storage local-btrfs \
|
||||
--rootfs-storage EX-Ceph \
|
||||
--external-uri http://93.171.241.5:9000/ \
|
||||
--discord-webhook "$DISCORD_WEBHOOK_URL"
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
# Runs INSIDE the Graylog LXC container as root (invoked via `pct exec <vmid> -- bash setup-forgejo-runner.sh`).
|
||||
# Idempotent: safe to re-run after a partial failure.
|
||||
# Runs as root - either INSIDE the Graylog LXC container (via
|
||||
# `pct exec <vmid> -- bash setup-forgejo-runner.sh`, for redeploying
|
||||
# Graylog config) or directly ON the Proxmox host (for a runner that can
|
||||
# do host-level work like create-graylog-lxc.sh - the container can't run
|
||||
# that against itself). Idempotent: safe to re-run after a partial failure.
|
||||
#
|
||||
# Registers a Forgejo Actions self-hosted runner in "host" mode (no Docker -
|
||||
# it runs shell steps directly on this container, which already has
|
||||
# everything install-graylog.sh needs) and wires it up as a systemd service
|
||||
# so it survives reboots.
|
||||
# it runs shell steps directly on the machine it's installed on) and wires
|
||||
# it up as a systemd service so it survives reboots.
|
||||
#
|
||||
# The registration token is a one-time credential from Forgejo itself, not
|
||||
# something this script invents - get it from:
|
||||
|
|
@ -17,8 +19,17 @@ set -euo pipefail
|
|||
FORGEJO_URL="${FORGEJO_URL:?Set FORGEJO_URL, e.g. https://git.zotac.keenetic.link}"
|
||||
FORGEJO_RUNNER_TOKEN="${FORGEJO_RUNNER_TOKEN:?Set FORGEJO_RUNNER_TOKEN (registration token from the repo's Actions -> Runners page)}"
|
||||
RUNNER_NAME="${RUNNER_NAME:-graylog-container-$(hostname)}"
|
||||
RUNNER_LABEL="${RUNNER_LABEL:-self-hosted:host}"
|
||||
RUNNER_VERSION="12.13.1"
|
||||
RUNNER_DIR="/opt/forgejo-runner"
|
||||
RUNNER_DIR="${RUNNER_DIR:-/opt/forgejo-runner}"
|
||||
SERVICE_NAME="${SERVICE_NAME:-forgejo-runner}"
|
||||
# Empty (default) = service runs as root, appropriate INSIDE the container
|
||||
# (its root is already scoped to just that container). On the Proxmox HOST
|
||||
# this must be set to an unprivileged account (e.g. claude-deploy) - a
|
||||
# root-owned systemd service with no User= would give every CI job full,
|
||||
# unrestricted root on the host, defeating the whole point of claude-deploy's
|
||||
# narrowly-scoped sudoers rules.
|
||||
RUNNER_USER="${RUNNER_USER:-}"
|
||||
|
||||
if [ -t 2 ]; then
|
||||
C_RESET=$'\033[0m'; C_CYAN=$'\033[36m'; C_GREEN=$'\033[32m'; C_YELLOW=$'\033[33m'; C_RED=$'\033[1;31m'
|
||||
|
|
@ -57,12 +68,12 @@ step_register() {
|
|||
skip "runner already registered ($RUNNER_DIR/.runner exists)"
|
||||
return
|
||||
fi
|
||||
log "Registering runner '$RUNNER_NAME' with $FORGEJO_URL (host mode, label self-hosted:host)..."
|
||||
log "Registering runner '$RUNNER_NAME' with $FORGEJO_URL (host mode, label $RUNNER_LABEL)..."
|
||||
( cd "$RUNNER_DIR" && /usr/local/bin/forgejo-runner register --no-interactive \
|
||||
--instance "$FORGEJO_URL" \
|
||||
--token "$FORGEJO_RUNNER_TOKEN" \
|
||||
--name "$RUNNER_NAME" \
|
||||
--labels self-hosted:host )
|
||||
--labels "$RUNNER_LABEL" )
|
||||
ok "runner registered"
|
||||
}
|
||||
|
||||
|
|
@ -75,18 +86,27 @@ step_config() {
|
|||
ok "generated config.yaml"
|
||||
}
|
||||
|
||||
step_ownership() {
|
||||
[ -n "$RUNNER_USER" ] || return
|
||||
chown -R "$RUNNER_USER" "$RUNNER_DIR"
|
||||
ok "chowned $RUNNER_DIR to $RUNNER_USER"
|
||||
}
|
||||
|
||||
step_service() {
|
||||
if systemctl is-active --quiet forgejo-runner; then
|
||||
skip "forgejo-runner service already running"
|
||||
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||
skip "$SERVICE_NAME service already running"
|
||||
return
|
||||
fi
|
||||
cat > /etc/systemd/system/forgejo-runner.service <<EOF
|
||||
local user_line=""
|
||||
[ -n "$RUNNER_USER" ] && user_line="User=$RUNNER_USER"
|
||||
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
|
||||
[Unit]
|
||||
Description=Forgejo Actions Runner
|
||||
Description=Forgejo Actions Runner ($RUNNER_NAME)
|
||||
After=network.target docker.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
$user_line
|
||||
WorkingDirectory=$RUNNER_DIR
|
||||
ExecStart=/usr/local/bin/forgejo-runner daemon --config $RUNNER_DIR/config.yaml
|
||||
Restart=on-failure
|
||||
|
|
@ -96,14 +116,15 @@ RestartSec=5
|
|||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now forgejo-runner
|
||||
ok "forgejo-runner service started and enabled"
|
||||
systemctl enable --now "$SERVICE_NAME"
|
||||
ok "$SERVICE_NAME service started and enabled${RUNNER_USER:+ (as $RUNNER_USER)}"
|
||||
}
|
||||
|
||||
main() {
|
||||
step_install_binary
|
||||
step_register
|
||||
step_config
|
||||
step_ownership
|
||||
step_service
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue