--- name: cloud-weaver-monitor description: > Use this skill after a CloudWeaver v2 recipe has been deployed (via cloud-weaver-repo-setup + GitHub Actions pipeline) to confirm the application is actually up and to help diagnose it when it is not. It polls the app's health endpoint until HTTP 200 with retries and backoff, and on failure collects SSH diagnostics from the VM. --- # Monitor Confirm the deployed recipe is healthy. Called optionally after `cloud-weaver-repo-setup` completes — when the GHA pipeline succeeds but the user wants an explicit health confirmation, or when diagnosing a problem. In the v2 flow the pipeline itself waits for `kamal deploy` to finish, so in the happy path this skill is a belt-and-suspenders check, not a required step. --- ## 1. Determine the health URL and SSH key **Required inputs** (passed from `start-cloud` or `cloud-weaver-repo-setup`): | Variable | Example | |----------|---------| | `PUBLIC_IP` | `200.1.2.3` | | `REPO_NAME` | `meu-hermes` | Each recipe exposes a health endpoint: | Recipe | Health check URL | |--------|-----------------| | `hermes-agent` | `https://${PUBLIC_IP}.nip.io/health` | | `waha` | `https://${PUBLIC_IP}.nip.io/api/health` | | `hermes-host` | sem endpoint HTTP — checagem via SSH (passo 2b) | SSH key path (per-repo, generated by `cloud-weaver-repo-setup`): ```bash SSH_KEY="$HOME/.ssh/cw-${REPO_NAME}" ``` --- ## 2. Poll the health endpoint Run the poller (pure stdlib, no dependencies). It waits a grace period for containers to boot, then probes with exponential backoff until HTTP 200 or the timeout budget runs out: ```bash python3 /scripts/health-check.py \ --url "https://${PUBLIC_IP}.nip.io/health" \ --timeout 600 --initial-delay 30 ``` Give the user plain-language status updates while it runs (`Estou aguardando a aplicação subir…`). On success the script exits 0. Use `--output report.json` when the caller wants the attempt history. --- ### 2b. `hermes-host` — check via SSH (no HTTP endpoint) `hermes-host` does not expose a web service. The agent runs on the host, but its terminal actions are isolated in a Docker sandbox container. Instead of the HTTP poller: ```bash ssh -i "$HOME/.ssh/cw-${REPO_NAME}" -o StrictHostKeyChecking=accept-new \ root@"$PUBLIC_IP" \ "docker info >/dev/null && test \"\$(hermes config get terminal.backend)\" = docker \ && hermes --version \ && (XDG_RUNTIME_DIR=/run/user/\$(id -u) systemctl --user is-active --quiet hermes-gateway \ || pgrep -f 'hermes.*gateway' >/dev/null)" ``` Exit 0 means Docker is running, the terminal backend is `docker` (isolated), the agent is installed and the gateway is active. On failure go to section 4. --- ## 3. On success — proceed Report to the user that the app is healthy. Hand off to the final report. --- ## 4. On failure — diagnose via SSH If the health check times out or never returns 200, collect VM diagnostics: ```bash bash /scripts/diagnose.sh \ --ssh-key "$HOME/.ssh/cw-${REPO_NAME}" --ip "$PUBLIC_IP" ``` This gathers: `docker ps`, `/data` disk usage, memory, the Docker daemon log and uptime. Read the output and reason out loud: For `hermes-host` the docker checks in `diagnose.sh` apply to the Hermes-managed sandbox container, but the gateway itself is a systemd service — diagnose both: ```bash ssh -i "$HOME/.ssh/cw-${REPO_NAME}" -o StrictHostKeyChecking=accept-new \ root@"$PUBLIC_IP" \ "XDG_RUNTIME_DIR=/run/user/\$(id -u) systemctl --user status hermes-gateway --no-pager; \ XDG_RUNTIME_DIR=/run/user/\$(id -u) journalctl --user -u hermes-gateway -n 50 --no-pager \ && hermes config get terminal.backend && docker ps --filter label=hermes-agent=1" ``` - **Containers not running** → check Kamal service logs on the VM: ```bash ssh -i "$HOME/.ssh/cw-${REPO_NAME}" root@"$PUBLIC_IP" \ "docker ps -a && docker logs \$(docker ps -lq) --tail 50" ``` - **Container restarting** → view its logs for the exit reason. - **Disk/memory pressure** → the plan may be too small; suggest a larger VM plan. - **Docker daemon down** → `systemctl status docker` on the VM. Use the per-repo SSH key (`~/.ssh/cw-`, user `root`, `-o StrictHostKeyChecking=accept-new`) for any follow-up commands. Report findings to the user in plain PT-BR and recommend the next action. --- ## Rollback Automated rollback is not implemented. If diagnostics show the VM itself cannot be recovered, tell the user clearly — then offer to run `cloud-weaver-teardown` and start fresh. --- ## Bundled Resources - **`scripts/health-check.py`** — HTTP poller (stdlib, backoff, report JSON) - **`scripts/diagnose.sh`** — SSH diagnostics collector (`--dry-run` supported)