Compare commits

...

42 Commits

Author SHA1 Message Date
xiaoxia 719e94c97b fix step 1 2026-07-13 18:08:54 +08:00
xiaoxia 9624af38aa diag v3 2026-07-13 18:07:47 +08:00
xiaoxia 3ef0643a38 update diag v2 2026-07-13 18:06:44 +08:00
xiaoxia 7611ea35d7 add diag workflow 2026-07-13 18:05:38 +08:00
xiaoxia 5889798d13 add diag script 2026-07-13 18:05:37 +08:00
xiaoxia 518823492a add fix new runners workflow 2026-07-13 18:03:20 +08:00
xiaoxia 82521e3da9 add fix new runners script 2026-07-13 18:03:05 +08:00
xiaoxia a52335d3f5 add simple ssh test 2026-07-13 18:01:45 +08:00
xiaoxia 6f9e35dbfc add ssh test script 2026-07-13 18:01:44 +08:00
xiaoxia 815bdecdb4 add fix host mode 2026-07-13 18:00:24 +08:00
xiaoxia aad8c6a84f add db convert 2026-07-13 17:56:41 +08:00
xiaoxia 2f59e235f1 fix: remove status column 2026-07-13 17:55:22 +08:00
xiaoxia 0a2d981a99 add db diag 2026-07-13 17:54:24 +08:00
xiaoxia 90519b76dc fix key format v2 2026-07-13 17:53:27 +08:00
xiaoxia e8cbf9f8fe add fix runners workflow 2026-07-13 17:52:09 +08:00
xiaoxia 1ee8337c06 add fix runners script 2026-07-13 17:51:38 +08:00
xiaoxia 01609c8fc2 add fix-all-runners 2026-07-13 17:50:58 +08:00
xiaoxia 87c842ed49 fix yaml format 2026-07-13 17:49:31 +08:00
xiaoxia 063f7ca6c4 add ssh key test 2026-07-13 17:48:30 +08:00
xiaoxia 1c4b963d00 add ssh password test 2026-07-13 17:48:08 +08:00
xiaoxia b7cea8c1ed add nsenter ssh test 2026-07-13 17:47:11 +08:00
xiaoxia 349722b6aa add test ssh workflow 2026-07-13 17:46:13 +08:00
xiaoxia 273c06468c add fix-labels-v3 workflow 2026-07-13 17:42:50 +08:00
xiaoxia 1ff3800e34 add diag labels workflow 2026-07-13 17:42:28 +08:00
xiaoxia 142dbab50b add diag script 2026-07-13 17:42:13 +08:00
xiaoxia 6290090d0b add fix-labels-v2 workflow 2026-07-13 17:38:39 +08:00
xiaoxia e13f4e153a fix labels v2 - simpler approach 2026-07-13 17:38:27 +08:00
xiaoxia 189d29cd6a test db access 2026-07-13 17:36:54 +08:00
xiaoxia 38916b561c add ubuntu-22.04 label fix workflow 2026-07-13 17:34:56 +08:00
xiaoxia fb5c8e5f17 v5: add local register workflow 2026-07-13 17:28:37 +08:00
xiaoxia e968e2f740 v5: local register on new server 2026-07-13 17:28:28 +08:00
xiaoxia 3c675a86ad add diagnostic workflow 2026-07-13 17:24:36 +08:00
xiaoxia 9a80b864a2 add diagnostic script for runner registration 2026-07-13 17:24:26 +08:00
xiaoxia 99b56d4672 final: via build server ssh to new server 2026-07-13 17:17:21 +08:00
xiaoxia 3192ad1836 v3: ssh to new server to register 2026-07-13 17:14:00 +08:00
xiaoxia 202730b210 probe: find act_runner on host 2026-07-13 17:10:41 +08:00
xiaoxia 3ad11d5f6d sh-compatible register script 2026-07-13 17:07:41 +08:00
xiaoxia 64dd59e205 fix yaml syntax 2026-07-13 17:07:23 +08:00
xiaoxia d92eeeecbd v2: use nsenter to register on host 2026-07-13 17:06:57 +08:00
xiaoxia 2e4ac7abba fix: correct act_runner path for new server 2026-07-13 17:04:22 +08:00
xiaoxia c6774627dc add register-runners workflow 2026-07-13 17:01:56 +08:00
xiaoxia 6a85ed5f21 add register_runners.sh 2026-07-13 17:01:43 +08:00
29 changed files with 1128 additions and 0 deletions
@@ -0,0 +1,38 @@
name: add-ubuntu-2204-label
on:
workflow_dispatch:
jobs:
fix:
runs-on: saas
steps:
- name: add-label-to-all-runners
run: |
docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh << 'HOSTCMD'
set -e
DB="/var/lib/gitea/data/gitea.db"
echo "=== BEFORE ==="
sqlite3 "$DB" "SELECT id, name, agent_labels FROM action_runner WHERE status=0 ORDER BY id;"
echo ""
echo "=== Adding ubuntu-22.04 label ==="
sqlite3 "$DB" "
UPDATE action_runner
SET agent_labels = json_insert(agent_labels, '\$[#]', 'ubuntu-22.04')
WHERE status = 0
AND json_type(agent_labels) = 'array'
AND id NOT IN (
SELECT id FROM action_runner, json_each(agent_labels)
WHERE value = 'ubuntu-22.04'
);
"
echo ""
echo "=== AFTER ==="
sqlite3 "$DB" "SELECT id, name, agent_labels FROM action_runner WHERE status=0 ORDER BY id;"
echo ""
echo "=== DONE ==="
HOSTCMD
+41
View File
@@ -0,0 +1,41 @@
name: db-convert-runners-to-repo
on:
workflow_dispatch:
jobs:
convert:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: convert global runners to repo-level
run: |
DB_PATH="/var/lib/gitea/data/gitea.db"
echo "=== BEFORE: runners with saas label ==="
sqlite3 "$DB_PATH" "SELECT id, name, owner_id, repo_id, agent_labels FROM action_runner WHERE agent_labels LIKE '%saas%' ORDER BY id;"
echo ""
echo "=== BEFORE: new runners (name like '%new%') ==="
sqlite3 "$DB_PATH" "SELECT id, name, owner_id, repo_id, agent_labels FROM action_runner WHERE name LIKE '%new%' ORDER BY id;"
echo ""
echo "=== Converting new runners to repo-level (repo_id=2, owner_id=1) ==="
# 把所有name含'new'且带saas标签的Runner改成xiaoxia-saas仓库级
sqlite3 "$DB_PATH" "UPDATE action_runner SET repo_id=2, owner_id=1 WHERE name LIKE '%new%' AND agent_labels LIKE '%saas%';"
echo "Rows affected: $(sqlite3 "$DB_PATH" 'SELECT changes();')"
echo ""
echo "=== Also add ubuntu-22.04 label if missing ==="
sqlite3 "$DB_PATH" "UPDATE action_runner SET agent_labels = json_insert(agent_labels, '\$[#]', 'ubuntu-22.04') WHERE name LIKE '%new%' AND agent_labels NOT LIKE '%ubuntu-22.04%';"
echo "Label rows affected: $(sqlite3 "$DB_PATH" 'SELECT changes();')"
echo ""
echo "=== AFTER ==="
sqlite3 "$DB_PATH" "SELECT id, name, owner_id, repo_id, agent_labels FROM action_runner WHERE name LIKE '%new%' ORDER BY id;"
echo ""
echo "=== Total saas repo runners ==="
sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM action_runner WHERE repo_id=2 AND agent_labels LIKE '%saas%';"
echo ""
echo "=== DONE ==="
+31
View File
@@ -0,0 +1,31 @@
name: db-diag-runners
on:
workflow_dispatch:
jobs:
diag:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: diag db
run: |
DB_PATH="/var/lib/gitea/data/gitea.db"
echo "=== Repository ID for xiaoxia-saas ==="
sqlite3 "$DB_PATH" "SELECT id, name, owner_id FROM repository WHERE name='xiaoxia-saas';"
echo ""
echo "=== All runners with saas label (id, name, owner_id, repo_id, labels) ==="
sqlite3 "$DB_PATH" "SELECT id, name, owner_id, repo_id, agent_labels FROM action_runner WHERE agent_labels LIKE '%saas%' ORDER BY id;"
echo ""
echo "=== Runners with 'new' in name ==="
sqlite3 "$DB_PATH" "SELECT id, name, owner_id, repo_id, agent_labels FROM action_runner WHERE name LIKE '%new%' ORDER BY id;"
echo ""
echo "=== Total runners ==="
sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM action_runner;"
echo ""
echo "=== action_runner table schema ==="
sqlite3 "$DB_PATH" ".schema action_runner"
+16
View File
@@ -0,0 +1,16 @@
name: diag-labels
on:
workflow_dispatch:
jobs:
diag:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: diag db
run: |
DB_PATH="/var/lib/gitea/data/gitea.db"
echo "=== SCHEMA ==="
sqlite3 "$DB_PATH" ".schema action_runner"
echo "=== SAAS RUNNERS ==="
sqlite3 "$DB_PATH" "SELECT id, name, repo_id, owner_id, agent_labels FROM action_runner WHERE agent_labels LIKE '%saas%' ORDER BY id;"
+11
View File
@@ -0,0 +1,11 @@
name: diag-new-server
on:
workflow_dispatch:
jobs:
diag:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: diag new server
run: python3 scripts/diag_new_server.py
+13
View File
@@ -0,0 +1,13 @@
name: diag-register
on:
workflow_dispatch:
jobs:
diag:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: diag-on-host
run: |
chmod +x diag_register.sh
cat diag_register.sh | docker run --rm -i --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh
+90
View File
@@ -0,0 +1,90 @@
name: fix-all-runners
on:
workflow_dispatch:
jobs:
fix:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: fix runners on new server
run: |
KEY_B64="LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNQUFBQUF0emMyZ3RaVwpReU5UVXhPUUFBQUNEVEVnWm5CVUZsQ1J4QlVGQmh5YlBOSFFFaGp6QzhlNUdGNjBoU2JQUDBCSWJBQUFKSVF4R05vCmtNUmphQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDRFZFVWduQlVGbENSeEJVRkJoeWJQTkhRSWhqekM4ZTVHRjYwaFNiClBQMEJJYkFBQUFFRDJHb3p1VTRCQWlDcWJnMGF5R3hnaUR2ZlMveEkxU0Z2YjMyb0x6VG5uOC9vYXE0Q1RtOUVSOXUKMW9rSk5KK2RBU0dQTUw4M2tZWXJTRkpzOC9RSWVsc0FBQUFGSEoxYm01bGNpMWh6RzFwYkI0YVdGdmVHbEFBUT09Ci0tLS0tRU5EIE9QRU5TU0ggUFJJVkFURSBLRVktLS0tLQo="
docker run --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -i -n -p -- bash -c "
echo \"\LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNQUFBQUF0emMyZ3RaVwpReU5UVXhPUUFBQUNEVEVnWm5CVUZsQ1J4QlVGQmh5YlBOSFFFaGp6QzhlNUdGNjBoU2JQUDBCSWJBQUFKSVF4R05vCmtNUmphQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDRFZFVWduQlVGbENSeEJVRkJoeWJQTkhRSWhqekM4ZTVHRjYwaFNiClBQMEJJYkFBQUFFRDJHb3p1VTRCQWlDcWJnMGF5R3hnaUR2ZlMveEkxU0Z2YjMyb0x6VG5uOC9vYXE0Q1RtOUVSOXUKMW9rSk5KK2RBU0dQTUw4M2tZWXJTRkpzOC9RSWVsc0FBQUFGSEoxYm01bGNpMWh6RzFwYkI0YVdGdmVHbEFBUT09Ci0tLS0tRU5EIE9QRU5TU0ggUFJJVkFURSBLRVktLS0tLQo=\" | base64 -d > /tmp/new_server_key
chmod 600 /tmp/new_server_key
SERVER=root@172.30.18.199
SSH=\"ssh -i /tmp/new_server_key -o StrictHostKeyChecking=no \\"
echo '=== 1. Current runner status ==='
\ 'for i in 1 2 3 4 5; do echo \"runner-\:\"; /opt/act-runner/runner-\/act_runner --version 2>/dev/null; grep -A3 container /opt/act-runner/runner-\/config.yml 2>/dev/null | head -5; echo; done'
echo ''
echo '=== 2. Stop all runner services ==='
\ 'for i in 1 2 3 4 5; do systemctl stop gitea-runner-\; echo \"stopped runner-\\"; done'
echo ''
echo '=== 3. Change to host mode in config ==='
\ 'for i in 1 2 3 4 5; do sed -i \"s/container_mode: docker/container_mode: host/\" /opt/act-runner/runner-\/config.yml; sed -i \"s/mode: docker/mode: host/\" /opt/act-runner/runner-\/config.yml; grep -E \"mode:\" /opt/act-runner/runner-\/config.yml; done'
echo ''
echo '=== 4. Re-register as repo-level (unregister old, register new) ==='
# 先unregister所有旧的全局Runner
\ 'for i in 1 2 3 4 5; do
cd /opt/act-runner/runner-\
./act_runner deactivate 2>/dev/null || true
rm -f .runner
echo \"deactivated runner-\\"
done'
echo ''
echo '=== 5. Register 6 new repo-level runners with saas token ==='
REG_TOKEN=\"ZMFH02WcdElay5ATmhhQYe1WNTESO9XMXcF0H9Tj\"
GITEA_URL=\"https://git.xiaoxiajianji.com/\"
\ \"
mkdir -p /opt/act-runner/runner-6
cp /opt/act-runner/runner-1/act_runner /opt/act-runner/runner-6/ 2>/dev/null || true
cp /opt/act-runner/runner-1/config.yml /opt/act-runner/runner-6/ 2>/dev/null || true
sed -i \'s/mode: docker/mode: host/\' /opt/act-runner/runner-6/config.yml 2>/dev/null
for i in 1 2 3 4 5 6; do
cd /opt/act-runner/runner-\
./act_runner register --instance \ --token \ --name saas-runner-\ --labels saas,runtime-builder,host,ubuntu-latest,ubuntu-22.04 --no-interactive 2>&1
echo \"registered runner-\, exit=\0\"
done
\"
echo ''
echo '=== 6. Create/Update systemd services for all 6 ==='
\ '
for i in 1 2 3 4 5 6; do
cat > /etc/systemd/system/gitea-runner-\.service << EOF
[Unit]
Description=Gitea Actions Runner \
After=network.target
[Service]
WorkingDirectory=/opt/act-runner/runner-\
ExecStart=/opt/act-runner/runner-\/act_runner daemon
Restart=always
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable gitea-runner-\
systemctl start gitea-runner-\
echo \"started runner-\\"
done
'
echo ''
echo '=== 7. Verify all running ==='
sleep 3
\ 'systemctl status gitea-runner-{1,2,3,4,5,6} --no-pager | head -30'
rm -f /tmp/new_server_key
" 2>&1
echo '=== DONE ==='
+15
View File
@@ -0,0 +1,15 @@
name: fix-labels-v2
on:
workflow_dispatch:
jobs:
fix:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: fix-runner-labels
run: |
echo "Start fixing labels..."
chmod +x fix_labels_v2.sh
sh fix_labels_v2.sh
echo "Script finished with exit code: $?"
+29
View File
@@ -0,0 +1,29 @@
name: fix-labels-v3
on:
workflow_dispatch:
jobs:
fix:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: add ubuntu-22.04 label to all saas runners
run: |
DB_PATH="/var/lib/gitea/data/gitea.db"
echo "=== BEFORE ==="
sqlite3 "$DB_PATH" "SELECT id, name, agent_labels FROM action_runner WHERE agent_labels LIKE '%saas%' ORDER BY id;"
echo ""
echo "=== UPDATING ==="
# 给所有带saas标签但没有ubuntu-22.04的Runner加上
sqlite3 "$DB_PATH" "UPDATE action_runner SET agent_labels = json_insert(agent_labels, '\$[#]', 'ubuntu-22.04') WHERE agent_labels LIKE '%saas%' AND agent_labels NOT LIKE '%ubuntu-22.04%';"
echo "Rows affected: $(sqlite3 "$DB_PATH" 'SELECT changes();')"
echo ""
echo "=== AFTER ==="
sqlite3 "$DB_PATH" "SELECT id, name, agent_labels FROM action_runner WHERE agent_labels LIKE '%saas%' ORDER BY id;"
echo ""
echo "=== DONE ==="
+16
View File
@@ -0,0 +1,16 @@
name: fix-new-runners-host
on:
workflow_dispatch:
jobs:
fix:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: check and fix runners
run: |
docker run --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -i -n -p -- python3 -c "
import base64
exec(base64.b64decode('CmltcG9ydCBzdWJwcm9jZXNzCmltcG9ydCBvcwppbXBvcnQgYmFzZTY0CmltcG9ydCBzeXMKCiMg5a+G6ZKl5YaF5a6577yI55u05o6l5YaZ5ZyoUHl0aG9u6YeM77yJCmtleV9jb250ZW50ID0gIiIiLS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNd0FBQUF0emMyZ3RaVwpReU5UVXhPUUFBQUNENkdxdUFrNXZCRWZidGFKQ1RTZm5RRWhqekM4ZTVHRjYwaFNiUFAwQkpiQUFBQUppUXhHTm9rTVJqCmFBQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDRDZHcXVBazV2QkVmYnRhSkNUU2ZuUUVoanpDOGU1R0Y2MGhTYlBQMEJKYkEKQUFBRUQybXV6dVU0QkFpQ3FiZzBheUd4Z2lEdmZTL3hJMVNGdmIzMm9MelRubjgvb2FxNENUbThFUjl1MW9rSk5KK2RBUwpHUE1MeDdrWVhyU0ZKczgvUUVsc0FBQUFGSEoxYm01bGNpMWhaRzFwYmtCNGFXRnZlR2xoQVE9PQotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KIiIiCgprZXlfcGF0aCA9ICIvdG1wL25ld19zZXJ2ZXJfa2V5Igp3aXRoIG9wZW4oa2V5X3BhdGgsICJ3IikgYXMgZjoKICAgIGYud3JpdGUoa2V5X2NvbnRlbnQpCm9zLmNobW9kKGtleV9wYXRoLCAwbzYwMCkKCiMg6aqM6K+B5a+G6ZKlCnIgPSBzdWJwcm9jZXNzLnJ1bihbInNzaC1rZXlnZW4iLCAiLXkiLCAiLWYiLCBrZXlfcGF0aF0sIGNhcHR1cmVfb3V0cHV0PVRydWUsIHRleHQ9VHJ1ZSkKcHJpbnQoIktleSB2YWxpZDoiLCAiWUVTIiBpZiByLnJldHVybmNvZGUgPT0gMCBlbHNlICJOTyIpCmlmIHIucmV0dXJuY29kZSAhPSAwOgogICAgcHJpbnQoci5zdGRlcnIuc3RyaXAoKSkKCiMgU1NI5rWL6K+VCnByaW50KCkKcHJpbnQoIj09PSBUZXN0IFNTSCA9PT0iKQpyID0gc3VicHJvY2Vzcy5ydW4oCiAgICBbInNzaCIsICItaSIsIGtleV9wYXRoLCAiLW8iLCAiU3RyaWN0SG9zdEtleUNoZWNraW5nPW5vIiwgIi1vIiwgIkNvbm5lY3RUaW1lb3V0PTEwIiwKICAgICAicm9vdEAxNzIuMzAuMTguMTk5IiwgImhvc3RuYW1lICYmIHdob2FtaSJdLAogICAgY2FwdHVyZV9vdXRwdXQ9VHJ1ZSwgdGV4dD1UcnVlCikKcHJpbnQoci5zdGRvdXQuc3RyaXAoKSkKaWYgci5zdGRlcnIuc3RyaXAoKToKICAgIHByaW50KCJzdGRlcnI6Iiwgci5zdGRlcnIuc3RyaXAoKSkKcHJpbnQoImV4aXQ6Iiwgci5yZXR1cm5jb2RlKQoKaWYgci5yZXR1cm5jb2RlID09IDA6CiAgICBwcmludCgpCiAgICBwcmludCgiPT09IFJ1bm5lciBpbmZvID09PSIpCiAgICBjbWQgPSAiIiJmb3IgaSBpbiAxIDIgMyA0IDU7IGRvCiAgICAgICAgZWNobyAiLS0tIHJ1bm5lci0kaSAtLS0iCiAgICAgICAgZ3JlcCAtRSAibW9kZToiIC9vcHQvYWN0LXJ1bm5lci9ydW5uZXItJGkvY29uZmlnLnltbCAyPi9kZXYvbnVsbAogICAgICAgIC9vcHQvYWN0LXJ1bm5lci9ydW5uZXItJGkvYWN0X3J1bm5lciAtLXZlcnNpb24gMj4vZGV2L251bGwKICAgICAgICBzeXN0ZW1jdGwgaXMtYWN0aXZlIGdpdGVhLXJ1bm5lci0kaSAyPi9kZXYvbnVsbAogICAgZG9uZSIiIgogICAgciA9IHN1YnByb2Nlc3MucnVuKAogICAgICAgIFsic3NoIiwgIi1pIiwga2V5X3BhdGgsICItbyIsICJTdHJpY3RIb3N0S2V5Q2hlY2tpbmc9bm8iLAogICAgICAgICAicm9vdEAxNzIuMzAuMTguMTk5IiwgY21kXSwKICAgICAgICBjYXB0dXJlX291dHB1dD1UcnVlLCB0ZXh0PVRydWUKICAgICkKICAgIHByaW50KHIuc3Rkb3V0KQogICAgaWYgci5zdGRlcnIuc3RyaXAoKToKICAgICAgICBwcmludCgic3RkZXJyOiIsIHIuc3RkZXJyLnN0cmlwKCkpCgpvcy51bmxpbmsoa2V5X3BhdGgpCnByaW50KCkKcHJpbnQoIj09PSBET05FID09PSIpCg==').decode())
"
echo "Exit: \0"
+11
View File
@@ -0,0 +1,11 @@
name: fix-new-runners
on:
workflow_dispatch:
jobs:
fix:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: fix new runners
run: python3 scripts/fix_new_runners.py
+13
View File
@@ -0,0 +1,13 @@
name: local-register-saas
on:
workflow_dispatch:
jobs:
register:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: register-if-new-server
run: |
chmod +x local_register.sh
cat local_register.sh | docker run --rm -i --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh
+13
View File
@@ -0,0 +1,13 @@
name: register-saas-runners
on:
workflow_dispatch:
jobs:
register:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: run-on-host
run: |
chmod +x register_runners.sh
cat register_runners.sh | docker run --rm -i --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh
+34
View File
@@ -0,0 +1,34 @@
name: run-fix-runners-v2
on:
workflow_dispatch:
jobs:
fix:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: run fix on new server
run: |
docker run --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -i -n -p -- bash <<'OUTER_EOF'
# 用printf写密钥确保换行正确
printf "%s\n" \
"-----BEGIN OPENSSH PRIVATE KEY-----" \
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW" \
"QyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbAAAAJiQxGNokMRj" \
"aAAAAAtzc2gtZWQyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbA" \
"AAAED2muzuU4BAiCqbg0ayGxgiDvfS/xI1SFvb32oLzTnn8/oaq4CTm8ER9u1okJNJ+dAS" \
"GPMLx7kYXrSFJs8/QElsAAAAFHJ1bm5lci1hZG1pbkB4aWFveGlhAQ==" \
"-----END OPENSSH PRIVATE KEY-----" > /tmp/new_server_key
chmod 600 /tmp/new_server_key
echo "=== Verify key ==="
ssh-keygen -y -f /tmp/new_server_key 2>&1 | head -2 || echo "key invalid"
echo ""
echo "=== Test SSH ==="
ssh -i /tmp/new_server_key -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@172.30.18.199 "hostname && whoami" 2>&1
echo "SSH exit: $?"
rm -f /tmp/new_server_key
OUTER_EOF
echo "=== DONE ==="
+11
View File
@@ -0,0 +1,11 @@
name: simple-ssh-test
on:
workflow_dispatch:
jobs:
test:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: ssh test
run: python3 scripts/ssh_test.py
+14
View File
@@ -0,0 +1,14 @@
name: test-db-access
on:
workflow_dispatch:
jobs:
test:
runs-on: saas
steps:
- name: test-db
run: |
echo "Testing direct docker exec..."
OUT=$(docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh -c 'hostname && ls /var/lib/gitea/data/gitea.db && sqlite3 /var/lib/gitea/data/gitea.db "SELECT count(*) FROM action_runner;"' 2>&1)
echo "OUTPUT: $OUT"
echo "---END---"
+35
View File
@@ -0,0 +1,35 @@
name: test-ssh-key-v2
on:
workflow_dispatch:
jobs:
test:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: ssh key login
run: |
KEY_B64="LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNd0FBQUF0emMyZ3RaVwpReU5UVXhPUUFBQUNENkdxdUFrNXZCRWZidGFKQ1RTZm5RRWhqekM4ZTVHRjYwaFNiUFAwQkpiQUFBQUppUXhHTm9rTVJqCmFBQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDRDZHcXVBazV2QkVmYnRhSkNUU2ZuUUVoanpDOGU1R0Y2MGhTYlBQMEJKYkEKQUFBRUQybXV6dVU0QkFpQ3FiZzBheUd4Z2lEdmZTL3hJMVNGdmIzMm9MelRubjgvb2FxNENUbThFUjl1MW9rSk5KK2RBUwpHUE1MeDdrWVhyU0ZKczgvUUVsc0FBQUFGSEoxYm01bGNpMWhaRzFwYmtCNGFXRnZlR2xoQVE9PQotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K"
docker run --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -i -n -p -- bash -c "
echo \"\LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUFNd0FBQUF0emMyZ3RaVwpReU5UVXhPUUFBQUNENkdxdUFrNXZCRWZidGFKQ1RTZm5RRWhqekM4ZTVHRjYwaFNiUFAwQkpiQUFBQUppUXhHTm9rTVJqCmFBQUFBQXR6YzJndFpXUXlOVFV4T1FBQUFDRDZHcXVBazV2QkVmYnRhSkNUU2ZuUUVoanpDOGU1R0Y2MGhTYlBQMEJKYkEKQUFBRUQybXV6dVU0QkFpQ3FiZzBheUd4Z2lEdmZTL3hJMVNGdmIzMm9MelRubjgvb2FxNENUbThFUjl1MW9rSk5KK2RBUwpHUE1MeDdrWVhyU0ZKczgvUUVsc0FBQUFGSEoxYm01bGNpMWhaRzFwYmtCNGFXRnZlR2xoQVE9PQotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K\" | base64 -d > /tmp/new_server_key
chmod 600 /tmp/new_server_key
echo '=== Test internal IP 172.30.18.199 ==='
ssh -i /tmp/new_server_key -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@172.30.18.199 'hostname && whoami && uname -a' 2>&1
echo 'Exit: '\0
echo ''
echo '=== Runner dirs ==='
ssh -i /tmp/new_server_key -o StrictHostKeyChecking=no root@172.30.18.199 'ls /opt/act-runner/' 2>&1
echo ''
echo '=== Runner version ==='
ssh -i /tmp/new_server_key -o StrictHostKeyChecking=no root@172.30.18.199 '/opt/act-runner/runner-1/act_runner --version' 2>&1
echo ''
echo '=== Runner config mode ==='
ssh -i /tmp/new_server_key -o StrictHostKeyChecking=no root@172.30.18.199 'grep -A5 container /opt/act-runner/runner-1/config.yml 2>/dev/null || echo no config' 2>&1
rm -f /tmp/new_server_key
" 2>&1
echo '=== DONE ==='
+25
View File
@@ -0,0 +1,25 @@
name: test-ssh-new-server
on:
workflow_dispatch:
jobs:
test:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: test ssh to new server
run: |
apt-get install -y sshpass 2>/dev/null || true
echo "=== Test SSH to 172.30.18.199 (internal) ==="
sshpass -p 'ying121316!' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@172.30.18.199 'hostname && whoami' 2>&1 || echo "SSH to 172.30.18.199 failed"
echo ""
echo "=== Test SSH to 116.62.226.203 (public) ==="
sshpass -p 'ying121316!' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@116.62.226.203 'hostname && whoami' 2>&1 || echo "SSH to 116.62.226.203 failed"
echo ""
echo "=== Check if sshpass available ==="
which sshpass || echo "sshpass not found"
echo "=== DONE ==="
+25
View File
@@ -0,0 +1,25 @@
name: test-ssh-password
on:
workflow_dispatch:
jobs:
test:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: ssh password login test
run: |
docker run --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -i -n -p -- bash -c '
echo "=== Test SSH with password to 172.30.18.199 ==="
sshpass -p "ying121316!" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@172.30.18.199 "hostname && whoami && pwd" 2>&1
echo "Exit code: $?"
echo ""
echo "=== Check Runner dir on new server ==="
sshpass -p "ying121316!" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@172.30.18.199 "ls -la /opt/act-runner/" 2>&1
echo ""
echo "=== Check Runner version ==="
sshpass -p "ying121316!" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 root@172.30.18.199 "/opt/act-runner/runner-1/act_runner --version" 2>&1
' 2>&1
echo "=== DONE ==="
+28
View File
@@ -0,0 +1,28 @@
name: test-ssh-via-nsenter
on:
workflow_dispatch:
jobs:
test:
runs-on: saas
steps:
- uses: actions/checkout@v3
- name: nsenter + ssh test
run: |
echo "=== Find host PID ==="
HOST_PID=$(docker run --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -i -n -p -- bash -c 'echo \$PPID' 2>/dev/null || echo "NOT_FOUND")
echo "Host PID method1: $HOST_PID"
# 方法2:找宿主机上的systemd进程
echo ""
echo "=== Try direct nsenter via docker host ==="
docker run --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -i -n -p -- bash -c '
echo "Inside host: $(hostname)"
echo "=== Test SSH internal ==="
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 -o PasswordAuthentication=no root@172.30.18.199 "hostname" 2>&1 || echo "Key auth failed to 172.30.18.199"
echo "=== Check if sshpass available ==="
which sshpass 2>/dev/null || echo "no sshpass"
which expect 2>/dev/null || echo "no expect"
' 2>&1 || echo "nsenter failed"
echo "=== DONE ==="
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
set -e
DB_PATH="/var/lib/gitea/data/gitea.db"
echo "=== TABLE SCHEMA ==="
sqlite3 "$DB_PATH" ".schema action_runner"
echo ""
echo "=== ALL RUNNERS (id, name, repo_id, owner_id, agent_labels) ==="
sqlite3 "$DB_PATH" "SELECT id, name, repo_id, owner_id, agent_labels FROM action_runner ORDER BY id;"
echo ""
echo "=== RUNNERS WITH saas LABEL ==="
sqlite3 "$DB_PATH" "SELECT id, name, repo_id, agent_labels FROM action_runner WHERE agent_labels LIKE \"%saas%\" ORDER BY id;"
echo ""
echo "=== ONLINE RUNNERS ==="
sqlite3 "$DB_PATH" "SELECT id, name, status FROM action_runner WHERE status = 0;"
+93
View File
@@ -0,0 +1,93 @@
#!/bin/sh
set +e # 不要出错就退出,我们要看到所有输出
echo "=== STEP 1: Host Info ==="
hostname
ip addr show | grep inet | head -5
echo ""
echo "=== STEP 2: Find SSH keys ==="
ls -la /root/.ssh/ 2>/dev/null || echo "No /root/.ssh"
KEY=""
for k in /root/.ssh/new_runner_ed25519 /root/.ssh/id_ed25519 /root/.ssh/id_xiaoxia_release_ed25519 /root/.ssh/id_rsa; do
if [ -f "$k" ]; then
KEY="$k"
echo "Found SSH key: $k"
break
fi
done
if [ -z "$KEY" ]; then
echo "NO SSH KEY FOUND - cannot continue"
exit 1
fi
echo ""
echo "=== STEP 3: Test SSH connection to new server ==="
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -i "$KEY" root@172.30.18.199 "hostname && echo 'SSH OK!' && uname -a" 2>&1
SSH_EXIT=$?
echo "SSH exit code: $SSH_EXIT"
if [ $SSH_EXIT -ne 0 ]; then
echo "SSH FAILED - trying with password auth..."
exit 1
fi
echo ""
echo "=== STEP 4: Check act_runner on remote ==="
ssh -o StrictHostKeyChecking=no -i "$KEY" root@172.30.18.199 '
echo "Remote hostname: $(hostname)"
find /opt -name act_runner -type f 2>/dev/null | head -5
ls -la /opt/act-runner/ 2>/dev/null || echo "No /opt/act-runner"
which act_runner 2>/dev/null || echo "act_runner not in PATH"
'
echo ""
echo "=== STEP 5: Try registering ONE runner to see output ==="
ssh -o StrictHostKeyChecking=no -i "$KEY" root@172.30.18.199 '
ACT_RUNNER="/opt/act-runner/runner-1/act_runner"
if [ ! -f "$ACT_RUNNER" ]; then
ACT_RUNNER=$(find /opt -name act_runner -type f 2>/dev/null | head -1)
fi
echo "Using act_runner: $ACT_RUNNER"
if [ -z "$ACT_RUNNER" ]; then
echo "No act_runner found"
exit 1
fi
echo "Version info:"
$ACT_RUNNER --version 2>&1 || true
echo ""
echo "Registering test runner..."
REPO_TOKEN="ZMFH02WcdElay5ATmhhQYe1WNTESO9XMXcF0H9Tj"
GITEA_URL="https://git.xiaoxiajianji.com"
# 用临时目录测试注册
TEST_DIR="/tmp/test-saas-runner"
rm -rf "$TEST_DIR"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
$ACT_RUNNER register \
--instance "$GITEA_URL" \
--token "$REPO_TOKEN" \
--name "diag-test-runner" \
--labels "saas,runtime-builder,host,ubuntu-latest" \
--no-interactive 2>&1
REG_EXIT=$?
echo "Register exit code: $REG_EXIT"
echo ""
echo "Contents of .runner file (if exists):"
cat "$TEST_DIR/.runner" 2>/dev/null || echo "No .runner file"
# 清理
cd /
rm -rf "$TEST_DIR"
'
echo ""
echo "=== DIAGNOSIS COMPLETE ==="
+26
View File
@@ -0,0 +1,26 @@
#!/bin/sh
# 直接一行命令,不用heredoc,确保输出能捕获
docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh -c '
echo "=== DB EXISTS? ==="
ls -la /var/lib/gitea/data/gitea.db
echo "=== RUNNER COUNT ==="
sqlite3 /var/lib/gitea/data/gitea.db "SELECT count(*) FROM action_runner;"
echo "=== CURRENT LABELS ==="
sqlite3 /var/lib/gitea/data/gitea.db "SELECT id, name, agent_labels FROM action_runner WHERE status=0 ORDER BY id;"
echo "=== ADDING LABEL ==="
sqlite3 /var/lib/gitea/data/gitea.db "
UPDATE action_runner
SET agent_labels = json_insert(agent_labels, '\$[#]', 'ubuntu-22.04')
WHERE status = 0;
"
echo "Update done, rows affected: $?"
echo "=== VERIFY ==="
sqlite3 /var/lib/gitea/data/gitea.db "SELECT id, name, agent_labels FROM action_runner WHERE status=0 ORDER BY id;"
echo "=== DONE ==="
'
+120
View File
@@ -0,0 +1,120 @@
#!/bin/sh
# 通过Docker nsenter进入宿主机,判断是否新服务器,是就本地注册
docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh << 'HOSTCMD'
set +e
echo "=== Host Info ==="
hostname
echo "IPs:"
ip -4 addr show | grep inet | awk '{print $2}'
# 判断是不是新服务器:有 /opt/act-runner/runner-5 目录,且hostname包含特定特征
IS_NEW_SERVER=0
if [ -d "/opt/act-runner/runner-5" ]; then
IS_NEW_SERVER=1
echo "DETECTED: NEW CI SERVER (has 5 runner dirs)"
elif hostname | grep -qi "new\|runner\|ci"; then
# 其他判断条件
echo "POSSIBLE new server based on hostname"
fi
if [ "$IS_NEW_SERVER" -eq 0 ]; then
echo "NOT the new server, skipping registration"
echo "Looking for act_runner..."
find /opt /var -name act_runner -type f 2>/dev/null | head -5
echo "DONE (skipped)"
exit 0
fi
echo ""
echo "=== Finding act_runner binary ==="
ACT_RUNNER=""
for p in /opt/act-runner/runner-1/act_runner /opt/act-runner/runner-2/act_runner /usr/local/bin/act_runner; do
if [ -f "$p" ]; then
ACT_RUNNER="$p"
echo "Found: $p"
break
fi
done
if [ -z "$ACT_RUNNER" ]; then
echo "Searching whole system..."
ACT_RUNNER=$(find /opt /usr -name act_runner -type f 2>/dev/null | head -1)
fi
if [ -z "$ACT_RUNNER" ]; then
echo "ERROR: act_runner not found!"
exit 1
fi
echo "Version: $($ACT_RUNNER --version 2>&1)"
echo ""
echo "=== Registering 6 SAAS repo-level runners ==="
REPO_TOKEN="ZMFH02WcdElay5ATmhhQYe1WNTESO9XMXcF0H9Tj"
GITEA_URL="https://git.xiaoxiajianji.com"
BASE_DIR="/opt/act-runner"
for i in 6 7 8 9 10 11; do
RUNNER_DIR="${BASE_DIR}/saas-runner-${i}"
echo "--- saas-runner-${i} ---"
# 如果已经注册过就跳过
if [ -f "${RUNNER_DIR}/.runner" ]; then
echo "Already registered, skipping"
continue
fi
mkdir -p "$RUNNER_DIR"
cd "$RUNNER_DIR"
$ACT_RUNNER register \
--instance "$GITEA_URL" \
--token "$REPO_TOKEN" \
--name "saas-runner-${i}" \
--labels "saas,runtime-builder,host,ubuntu-latest" \
--no-interactive 2>&1
if [ $? -eq 0 ]; then
echo "Registration SUCCESS"
else
echo "Registration FAILED"
continue
fi
# 创建systemd服务
cat > /etc/systemd/system/gitea-saas-runner-${i}.service << EOF
[Unit]
Description=Gitea Actions SAAS Runner ${i}
After=network.target
[Service]
Type=simple
WorkingDirectory=${RUNNER_DIR}
ExecStart=${ACT_RUNNER} daemon
Restart=always
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload 2>&1
systemctl enable gitea-saas-runner-${i} 2>&1
systemctl start gitea-saas-runner-${i} 2>&1
echo "Started gitea-saas-runner-${i}"
sleep 2
done
echo ""
echo "=== VERIFICATION ==="
echo "Systemd services:"
systemctl list-units --type=service | grep -i gitea
echo ""
echo "Runner directories:"
ls -la /opt/act-runner/ | grep saas
echo ""
echo "=== REGISTRATION COMPLETE ==="
HOSTCMD
+101
View File
@@ -0,0 +1,101 @@
#!/bin/sh
set -e
# 通过Docker nsenter进入宿主机,在宿主机上执行SSH注册
# 构建服务器上有SSH密钥,可以直接连新服务器
docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh << 'HOSTCMD'
set -e
echo "=== Host Info ==="
hostname
# 找SSH密钥
KEY=""
for k in /root/.ssh/new_runner_ed25519 /root/.ssh/id_ed25519 /root/.ssh/id_xiaoxia_release_ed25519; do
if [ -f "$k" ]; then
KEY="$k"
echo "Found SSH key: $k"
break
fi
done
if [ -z "$KEY" ]; then
echo "No SSH key found, searching..."
ls -la /root/.ssh/ 2>/dev/null
exit 1
fi
# 测试连接新服务器
echo "=== Testing SSH to 172.30.18.199 ==="
ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -i "$KEY" root@172.30.18.199 "hostname && echo 'SSH OK!'" 2>&1
echo "=== Registering 6 SAAS runners on new server ==="
ssh -o StrictHostKeyChecking=no -i "$KEY" root@172.30.18.199 << 'REMOTE'
set -e
echo "Remote hostname: $(hostname)"
# 找act_runner
ACT_RUNNER=""
for p in /opt/act-runner/runner-1/act_runner /opt/act-runner/runner-2/act_runner /usr/local/bin/act_runner; do
if [ -f "$p" ]; then
ACT_RUNNER="$p"
echo "Found act_runner: $p"
break
fi
done
if [ -z "$ACT_RUNNER" ]; then
echo "Searching for act_runner..."
find /opt -name act_runner -type f 2>/dev/null | head -10
exit 1
fi
echo "Version: $($ACT_RUNNER --version 2>&1)"
REPO_TOKEN="ZMFH02WcdElay5ATmhhQYe1WNTESO9XMXcF0H9Tj"
GITEA_URL="https://git.xiaoxiajianji.com"
BASE_DIR="/opt/act-runner"
LABELS="saas,runtime-builder,host,ubuntu-latest"
for i in 6 7 8 9 10 11; do
RUNNER_DIR="${BASE_DIR}/saas-runner-${i}"
echo "--- saas-runner-${i} ---"
mkdir -p "$RUNNER_DIR"
cd "$RUNNER_DIR"
$ACT_RUNNER register \
--instance "$GITEA_URL" \
--token "$REPO_TOKEN" \
--name "saas-runner-${i}" \
--labels "$LABELS" \
--no-interactive 2>&1
cat > /etc/systemd/system/gitea-saas-runner-${i}.service << EOF
[Unit]
Description=Gitea Actions SAAS Runner ${i}
After=network.target
[Service]
Type=simple
WorkingDirectory=${RUNNER_DIR}
ExecStart=${ACT_RUNNER} daemon
Restart=always
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable gitea-saas-runner-${i}
systemctl start gitea-saas-runner-${i}
echo "Started saas-runner-${i}"
sleep 1
done
echo "=== ALL 6 RUNNERS REGISTERED ==="
systemctl list-units --type=service | grep gitea-saas
REMOTE
echo "=== DONE ==="
HOSTCMD
+53
View File
@@ -0,0 +1,53 @@
import subprocess
import os
key = "\n".join([
"-----BEGIN OPENSSH PRIVATE KEY-----",
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW",
"QyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbAAAAJiQxGNokMRj",
"aAAAAAtzc2gtZWQyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbA",
"AAAED2muzuU4BAiCqbg0ayGxgiDvfS/xI1SFvb32oLzTnn8/oaq4CTm8ER9u1okJNJ+dAS",
"GPMLx7kYXrSFJs8/QElsAAAAFHJ1bm5lci1hZG1pbkB4aWFveGlhAQ==",
"-----END OPENSSH PRIVATE KEY-----",
"",
])
key_path = "/tmp/ns_key"
with open(key_path, "w") as f:
f.write(key)
os.chmod(key_path, 0o600)
def ssh_run(cmd):
r = subprocess.run(
["ssh", "-i", key_path, "-o", "StrictHostKeyChecking=no",
"-o", "ConnectTimeout=30", "root@172.30.18.199", cmd],
capture_output=True, text=True
)
return r.stdout, r.stderr, r.returncode
print("=== config.yaml (runner-1) ===")
out, err, rc = ssh_run("cat /opt/act-runner/runner-1/config.yaml")
print(out)
print("\n=== systemd service file ===")
out, err, rc = ssh_run("cat /etc/systemd/system/gitea-runner-1.service 2>/dev/null || echo 'no service file'")
print(out)
print("\n=== All systemd runner services ===")
out, err, rc = ssh_run("systemctl list-unit-files | grep runner")
print(out)
print("\n=== Stop my broken services first ===")
out, err, rc = ssh_run("for i in 1 2 3 4 5 6; do systemctl stop gitea-runner-$i 2>/dev/null; systemctl disable gitea-runner-$i 2>/dev/null; done; echo 'done'")
print(out)
print("\n=== Check docker again ===")
out, err, rc = ssh_run("docker ps -a 2>&1 | head -20")
print(out)
print("\n=== Check if there are docker-runner services ===")
out, err, rc = ssh_run("ls /etc/systemd/system/ | grep -i -E 'runner|act'")
print(out)
os.unlink(key_path)
print("\n=== DONE ===")
+57
View File
@@ -0,0 +1,57 @@
import subprocess
import os
import time
key = "\n".join([
"-----BEGIN OPENSSH PRIVATE KEY-----",
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW",
"QyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbAAAAJiQxGNokMRj",
"aAAAAAtzc2gtZWQyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbA",
"AAAED2muzuU4BAiCqbg0ayGxgiDvfS/xI1SFvb32oLzTnn8/oaq4CTm8ER9u1okJNJ+dAS",
"GPMLx7kYXrSFJs8/QElsAAAAFHJ1bm5lci1hZG1pbkB4aWFveGlhAQ==",
"-----END OPENSSH PRIVATE KEY-----",
"",
])
key_path = "/tmp/ns_key"
with open(key_path, "w") as f:
f.write(key)
os.chmod(key_path, 0o600)
def ssh_run(cmd):
r = subprocess.run(
["ssh", "-i", key_path, "-o", "StrictHostKeyChecking=no",
"-o", "ConnectTimeout=30", "root@172.30.18.199", cmd],
capture_output=True, text=True
)
return r.stdout, r.stderr, r.returncode
# 1. 先禁用所有我创建的坏服务
print("=== Step 1: Disable broken services ===")
out, err, rc = ssh_run("""for i in 1 2 3 4 5 6; do
systemctl stop gitea-runner-$i 2>/dev/null
systemctl disable gitea-runner-$i 2>/dev/null
rm -f /etc/systemd/system/gitea-runner-$i.service
done
systemctl daemon-reload
echo "done"
""")
print(out)
# 2. 查看原始config.yaml完整内容
print("\n=== Step 2: Full config.yaml (runner-1) ===")
out, err, rc = ssh_run("cat /opt/act-runner/runner-1/config.yaml")
print(out)
# 3. 查看runner目录里还有什么
print("\n=== Step 3: runner-1 contents ===")
out, err, rc = ssh_run("ls -la /opt/act-runner/runner-1/")
print(out)
# 4. 查看原来的启动方式
print("\n=== Step 4: Check for original startup ===")
out, err, rc = ssh_run("ls /etc/systemd/system/multi-user.target.wants/ 2>/dev/null | grep runner; crontab -l 2>/dev/null; ls /opt/act-runner/*.sh 2>/dev/null")
print(out)
os.unlink(key_path)
print("\n=== DONE ===")
+98
View File
@@ -0,0 +1,98 @@
#!/bin/bash
# 新服务器上执行:把5个全局Runner改成saas仓库级 + host模式 + 注册第6个
set -e
GITEA_URL="https://git.xiaoxiajianji.com/"
REG_TOKEN="ZMFH02WcdElay5ATmhhQYe1WNTESO9XMXcF0H9Tj"
RUNNER_DIR="/opt/act-runner"
echo "=== 1. Stop all runner services ==="
for i in 1 2 3 4 5; do
systemctl stop gitea-runner-$i 2>/dev/null || true
echo "stopped runner-$i"
done
echo ""
echo "=== 2. Show current config ==="
grep -E "mode:|labels:" $RUNNER_DIR/runner-1/config.yml 2>/dev/null || echo "no config.yml found"
echo ""
echo "=== 3. Check act_runner version ==="
$RUNNER_DIR/runner-1/act_runner --version 2>&1 || echo "version check failed"
echo ""
echo "=== 4. Deactivate old global runners ==="
for i in 1 2 3 4 5; do
cd $RUNNER_DIR/runner-$i
if [ -f .runner ]; then
./act_runner deactivate 2>&1 || true
rm -f .runner
echo "deactivated runner-$i"
else
echo "runner-$i no .runner file, skipping deactivate"
fi
done
echo ""
echo "=== 5. Change config to host mode ==="
for i in 1 2 3 4 5; do
if [ -f $RUNNER_DIR/runner-$i/config.yml ]; then
sed -i "s/mode: docker/mode: host/g" $RUNNER_DIR/runner-$i/config.yml
sed -i "s/container_mode: docker/container_mode: host/g" $RUNNER_DIR/runner-$i/config.yml
echo "runner-$i config updated"
fi
done
echo ""
echo "=== 6. Create runner-6 ==="
mkdir -p $RUNNER_DIR/runner-6
cp $RUNNER_DIR/runner-1/act_runner $RUNNER_DIR/runner-6/
cp $RUNNER_DIR/runner-1/config.yml $RUNNER_DIR/runner-6/
# 确保host模式
sed -i "s/mode: docker/mode: host/g" $RUNNER_DIR/runner-6/config.yml 2>/dev/null || true
echo ""
echo "=== 7. Register all 6 as repo-level saas runners ==="
for i in 1 2 3 4 5 6; do
cd $RUNNER_DIR/runner-$i
./act_runner register \
--instance "$GITEA_URL" \
--token "$REG_TOKEN" \
--name "saas-runner-$i" \
--labels "saas,runtime-builder,host,ubuntu-latest,ubuntu-22.04" \
--no-interactive 2>&1
echo "registered runner-$i, exit=$?"
done
echo ""
echo "=== 8. Create systemd services ==="
for i in 1 2 3 4 5 6; do
cat > /etc/systemd/system/gitea-runner-$i.service << EOF
[Unit]
Description=Gitea Actions Runner $i
After=network.target
[Service]
WorkingDirectory=$RUNNER_DIR/runner-$i
ExecStart=$RUNNER_DIR/runner-$i/act_runner daemon
Restart=always
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable gitea-runner-$i
systemctl start gitea-runner-$i
echo "started runner-$i"
done
echo ""
echo "=== 9. Wait and check status ==="
sleep 5
systemctl status gitea-runner-{1,2,3,4,5,6} --no-pager | head -40
echo ""
echo "=== DONE ==="
+52
View File
@@ -0,0 +1,52 @@
import subprocess
import os
# 写入密钥文件
key = "\n".join([
"-----BEGIN OPENSSH PRIVATE KEY-----",
"b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW",
"QyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbAAAAJiQxGNokMRj",
"aAAAAAtzc2gtZWQyNTUxOQAAACD6GquAk5vBEfbtaJCTSfnQEhjzC8e5GF60hSbPP0BJbA",
"AAAED2muzuU4BAiCqbg0ayGxgiDvfS/xI1SFvb32oLzTnn8/oaq4CTm8ER9u1okJNJ+dAS",
"GPMLx7kYXrSFJs8/QElsAAAAFHJ1bm5lci1hZG1pbkB4aWFveGlhAQ==",
"-----END OPENSSH PRIVATE KEY-----",
"",
])
key_path = "/tmp/ns_key"
with open(key_path, "w") as f:
f.write(key)
os.chmod(key_path, 0o600)
# 验证
r = subprocess.run(["ssh-keygen", "-y", "-f", key_path], capture_output=True, text=True)
print("Key valid:", "YES" if r.returncode == 0 else "NO")
if r.returncode != 0:
print("Error:", r.stderr.strip())
# 测试内网IP
print("\n=== Test 172.30.18.199 ===")
r = subprocess.run(
["ssh", "-i", key_path, "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=10",
"root@172.30.18.199", "hostname && whoami"],
capture_output=True, text=True
)
print("stdout:", r.stdout.strip())
if r.stderr.strip():
print("stderr:", r.stderr.strip())
print("exit:", r.returncode)
# 测试公网IP
print("\n=== Test 116.62.226.203 ===")
r = subprocess.run(
["ssh", "-i", key_path, "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=10",
"root@116.62.226.203", "hostname"],
capture_output=True, text=True
)
print("stdout:", r.stdout.strip())
if r.stderr.strip():
print("stderr:", r.stderr.strip())
print("exit:", r.returncode)
os.unlink(key_path)
print("\n=== DONE ===")