add clawgo-node-child skill for child node deployment and sync

This commit is contained in:
DBT
2026-02-25 11:39:44 +00:00
parent 5ea3586431
commit 1a3e6240f7
2 changed files with 129 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
---
name: clawgo-node-child
description: Deploy and register a clawgo child node to a parent clawgo gateway without ad-hoc Python agents. Use when setting up sub-nodes, syncing provider settings from parent to child, enabling reverse tunnel fallback, and validating parent-dispatched nodes actions (describe/run/invoke/agent_task).
---
# Clawgo Node Child
Use built-in clawgo services only. Do not create `node_agent.py`.
## Execute
1. Run `scripts/deploy_child.sh` on the operator host with env vars:
- `PARENT_HOST` `PARENT_PASS`
- `CHILD_HOST` `CHILD_PASS`
- Optional: `PARENT_GATEWAY_PORT` (default `18790`), `RELAY_PORT` (default `17789`), `CHILD_PORT` (default `7789`), `NODE_ID` (default `node-child`)
2. Script will:
- Copy `/usr/local/bin/clawgo` from parent to child
- Sync `providers` + `agents.defaults` into child `/root/.clawgo/provider-sync.json`
- Create child gateway config `/root/.clawgo/config.child.json`
- Install/start child service `clawgo-child-gateway.service`
- Install/start reverse tunnel service `clawgo-child-revtunnel.service`
- Register child node to parent `/nodes/register`
- Install child heartbeat cron (`/nodes/heartbeat` every minute)
3. Validate from parent:
- Health: `curl http://127.0.0.1:${RELAY_PORT}/health`
- Task dispatch: `clawgo agent` + `nodes action=agent_task node=<NODE_ID> mode=relay ...`
## Notes
- Prefer direct endpoint if reachable; keep reverse tunnel as fallback.
- If parent and CLI visibility differ, ensure node state persistence is enabled (`memory/nodes-state.json`).
- If child service fails, check:
- `journalctl -u clawgo-child-gateway.service -n 100 --no-pager`
- `journalctl -u clawgo-child-revtunnel.service -n 100 --no-pager`

View File

@@ -0,0 +1,95 @@
#!/usr/bin/env bash
set -euo pipefail
: "${PARENT_HOST:?need PARENT_HOST}"
: "${PARENT_PASS:?need PARENT_PASS}"
: "${CHILD_HOST:?need CHILD_HOST}"
: "${CHILD_PASS:?need CHILD_PASS}"
PARENT_GATEWAY_PORT="${PARENT_GATEWAY_PORT:-18790}"
RELAY_PORT="${RELAY_PORT:-17789}"
CHILD_PORT="${CHILD_PORT:-7789}"
NODE_ID="${NODE_ID:-node-child}"
SSHP_PARENT=(sshpass -p "$PARENT_PASS" ssh -o StrictHostKeyChecking=no "root@${PARENT_HOST}")
SSHP_CHILD=(sshpass -p "$CHILD_PASS" ssh -o StrictHostKeyChecking=no "root@${CHILD_HOST}")
# 1) Copy clawgo binary parent -> local -> child
sshpass -p "$PARENT_PASS" scp -o StrictHostKeyChecking=no "root@${PARENT_HOST}:/usr/local/bin/clawgo" /tmp/clawgo_child
sshpass -p "$CHILD_PASS" scp -o StrictHostKeyChecking=no /tmp/clawgo_child "root@${CHILD_HOST}:/usr/local/bin/clawgo"
"${SSHP_CHILD[@]}" "chmod +x /usr/local/bin/clawgo"
# 2) Sync providers + agents.defaults from parent
"${SSHP_PARENT[@]}" "python3 - <<'PY'
import json
c=json.load(open('/root/.clawgo/config.json'))
p={'providers':c.get('providers',{}),'agents_defaults':c.get('agents',{}).get('defaults',{})}
print(json.dumps(p,ensure_ascii=False))
PY" > /tmp/provider-sync.json
cat /tmp/provider-sync.json | "${SSHP_CHILD[@]}" "mkdir -p /root/.clawgo && cat > /root/.clawgo/provider-sync.json"
# 3) Build child config (no ad-hoc python server)
"${SSHP_CHILD[@]}" "python3 - <<'PY'
import json
src='/root/.clawgo/provider-sync.json'
out='/root/.clawgo/config.child.json'
d=json.load(open(src))
cfg={
'gateway': {'host':'0.0.0.0','port': ${CHILD_PORT}},
'providers': d.get('providers',{}),
'agents': {'defaults': d.get('agents_defaults',{})},
'channels': {},
'tools': {'shell': {'enabled': True}},
'logging': {'level':'info'}
}
json.dump(cfg, open(out,'w'), ensure_ascii=False, indent=2)
print(out)
PY"
# 4) Install child gateway service
"${SSHP_CHILD[@]}" "cat > /etc/systemd/system/clawgo-child-gateway.service <<EOF
[Unit]
Description=Clawgo Child Gateway
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/clawgo gateway run --config /root/.clawgo/config.child.json
Restart=always
RestartSec=2
User=root
WorkingDirectory=/root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now clawgo-child-gateway.service"
# 5) Install reverse tunnel service (child -> parent)
"${SSHP_CHILD[@]}" "yum install -y sshpass >/dev/null 2>&1 || true"
"${SSHP_CHILD[@]}" "cat > /etc/systemd/system/clawgo-child-revtunnel.service <<EOF
[Unit]
Description=Clawgo Child Reverse Tunnel
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/sshpass -p ${PARENT_PASS} /usr/bin/ssh -o StrictHostKeyChecking=no -o ServerAliveInterval=20 -o ServerAliveCountMax=3 -N -R ${RELAY_PORT}:127.0.0.1:${CHILD_PORT} root@${PARENT_HOST}
Restart=always
RestartSec=3
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now clawgo-child-revtunnel.service"
# 6) Register + heartbeat
"${SSHP_CHILD[@]}" "curl -s -X POST http://${PARENT_HOST}:${PARENT_GATEWAY_PORT}/nodes/register -H 'Content-Type: application/json' -d '{\"id\":\"${NODE_ID}\",\"name\":\"${NODE_ID}\",\"os\":\"linux\",\"arch\":\"amd64\",\"version\":\"clawgo-child\",\"endpoint\":\"http://127.0.0.1:${RELAY_PORT}\",\"capabilities\":{\"run\":true,\"invoke\":true,\"model\":true},\"actions\":[\"run\",\"invoke\",\"agent_task\"],\"models\":[\"local-sim\"]}'"
"${SSHP_CHILD[@]}" "(crontab -l 2>/dev/null; echo '*/1 * * * * curl -s -X POST http://${PARENT_HOST}:${PARENT_GATEWAY_PORT}/nodes/heartbeat -H \"Content-Type: application/json\" -d \"{\\\"id\\\":\\\"${NODE_ID}\\\"}\" >/dev/null 2>&1') | crontab -"
echo "DONE: ${NODE_ID} deployed"