feat: per-site SHIFT path with video search, fix agent token injection, accept cpu_temp
- deploy_agent.sh: agent v3.3-shift — use dashboard-configured SHIFT path for file fetch/search (SR/SHIFT sites have no TAKELEAP folder), date fast-path; fix installer discarding the injected agent token (sentinel was being rewritten by the server's placeholder replace, agents ended up tokenless) - central_api_prototype.py: replace only the token assignment when serving the installer; add cpu_temp to TelemetryPayload (agents already send it, it was silently dropped); new endpoints set-shift-path, request-search, search-results; heartbeat response now carries shift_path + pending search - commands.json: restore last_reboot/dummy, add update_diag diagnostic - CLAUDE.md: document deployment layout, procedures, and gotchas
This commit is contained in:
124
CLAUDE.md
Normal file
124
CLAUDE.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# SeekRight Pulse RMM — Production Deployment Map
|
||||
|
||||
This VM (`vm3-mint`, LAN `192.168.1.201`, Tailscale `100.79.183.41`) is the
|
||||
**production server** for the SeekRight Pulse RMM system. Field agents and the
|
||||
public dashboard both talk to services running here.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Internet
|
||||
│
|
||||
▼
|
||||
Synology reverse proxy (takeleapindia.synology.me / 106.51.70.111)
|
||||
├── https://rmm.seekright.com → this VM : vite port (currently 4173)
|
||||
└── https://rmm-backend.seekright.com → this VM : 8000
|
||||
│
|
||||
Field agents (X-Agent-Token) ───────────────────┤
|
||||
▼
|
||||
FastAPI backend (uvicorn :8000, 4 workers)
|
||||
│
|
||||
MongoDB localhost:27017, db `rmm_db`
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### Backend — `/opt/rmm-backend`
|
||||
- FastAPI app `central_api_prototype.py`, run by **systemd `rmm-backend.service`**
|
||||
(User=root): `venv/bin/uvicorn central_api_prototype:app --host 0.0.0.0 --port 8000 --workers 4`
|
||||
- Env: systemd `EnvironmentFile=/opt/rmm-backend/.env` injects vars **at service
|
||||
start**. The `APP_ENV` / `.env.production` / `.env.development` logic in the
|
||||
code is mostly vestigial here: values from `.env` are already in the process
|
||||
environment and `load_dotenv` never overrides them. **Editing `.env` requires
|
||||
a service restart to take effect.**
|
||||
- Data: MongoDB `rmm_db` (`clients`, `logs`, `config` collections). Alerts go to
|
||||
Rocket.Chat via `ROCKETCHAT_WEBHOOK_URL`.
|
||||
- `commands.json` = whitelist of commands agents may run. Read from disk **per
|
||||
request** (no restart needed). Also editable live from the dashboard config
|
||||
editor (`/api` load/save endpoints) — meaning production edits land in the
|
||||
working tree and will conflict with `git pull` (see gotchas).
|
||||
- Agent auth: agents send `X-Agent-Token` (value `AGENT_TOKEN` in `.env`). Mode
|
||||
lives in Mongo `config._id=agent_auth`: `grace` (default — tokenless legacy
|
||||
agents still accepted) or `strict` (reject without token). Flip with
|
||||
`set_strict.py` only after every field agent has been updated
|
||||
(`deploy_agent.sh` / the `update_agent` command).
|
||||
- Dashboard login: `POST /api/login`, credentials `DASHBOARD_USERNAME` /
|
||||
`DASHBOARD_PASSWORD` from `.env`, JWT signed with `JWT_SECRET_KEY`.
|
||||
|
||||
### Frontend — `/opt/rmm-ui`
|
||||
- React + Vite, run by **systemd `rmm-frontend.service`** (User=root):
|
||||
`npm run dev -- --mode production` (a vite **dev server**, not a static build).
|
||||
- Port is set in `vite.config.js` (`server.port`, currently **4173** — must
|
||||
match the Synology reverse-proxy upstream);
|
||||
`allowedHosts: ["rmm.seekright.com"]` must include the public hostname or
|
||||
vite rejects proxied requests.
|
||||
- Vite watches files: pulled code changes hot-reload automatically, and a
|
||||
`vite.config.js` change makes vite restart itself — BUT an in-process
|
||||
restart keeps whatever port vite already bound (including an auto-bumped
|
||||
one like 4174 after a port collision). To change ports for real:
|
||||
`sudo systemctl restart rmm-frontend.service`.
|
||||
- API base URL comes from `/opt/rmm-ui/.env.production`
|
||||
(`VITE_API_BASE_URL=https://rmm-backend.seekright.com`).
|
||||
|
||||
### Reverse proxy — Synology (NOT on this VM)
|
||||
- No nginx/apache runs on this VM. TLS + routing for both public hostnames is
|
||||
done on the Synology at `takeleapindia.synology.me` (106.51.70.111).
|
||||
- **If the vite port changes in `vite.config.js`, the Synology reverse-proxy
|
||||
upstream port must be updated to match** — otherwise the site 502s.
|
||||
This exact thing happened 2026-07-16 (commit `dc604a4` moved 4173 → 6173).
|
||||
|
||||
### Field agents (remote machines)
|
||||
- Run `/opt/seekright-agent/client_agent_prototype.py` on each monitored node;
|
||||
poll `GET /api/get-command` and push `POST /api/telemetry`.
|
||||
- Installed/updated via `deploy_agent.sh` (served by the backend; in strict
|
||||
mode downloading it requires a valid agent token).
|
||||
|
||||
## How to deploy
|
||||
|
||||
Backend:
|
||||
```bash
|
||||
cd /opt/rmm-backend
|
||||
git status # working tree should be clean — see gotchas
|
||||
git pull
|
||||
sudo systemctl restart rmm-backend.service
|
||||
systemctl status rmm-backend.service --no-pager -n 20 # check for crash loop
|
||||
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8000/docs # expect 200
|
||||
```
|
||||
|
||||
Frontend:
|
||||
```bash
|
||||
cd /opt/rmm-ui
|
||||
git pull # vite hot-reloads; restarts itself on config change
|
||||
# only if deps changed: npm install && sudo systemctl restart rmm-frontend.service
|
||||
curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: rmm.seekright.com' http://localhost:4173/
|
||||
curl -sk -o /dev/null -w '%{http_code}\n' https://rmm.seekright.com/ # via Synology
|
||||
```
|
||||
|
||||
## Gotchas / history
|
||||
|
||||
- **Don't hand-edit tracked files on this server** (`commands.json`, `.env`
|
||||
are tracked in git). Local edits block `git pull`. Commit changes to the repo
|
||||
instead. Dashboard edits to `commands.json` also dirty the tree — push them
|
||||
upstream after changing them.
|
||||
- 2026-07-16: pull of `dc604a4` changed the vite port 4173 → 6173 and broke
|
||||
https://rmm.seekright.com (Synology still forwarded to 4173). Resolved by
|
||||
reverting `vite.config.js` to port 4173 in the working tree. That revert is
|
||||
a LOCAL change to a tracked file — commit and push it (or the next pull
|
||||
will conflict and re-break the site by pulling 6173 back in).
|
||||
- The backend service must be restarted after every backend pull — uvicorn has
|
||||
no auto-reload in the unit. A long-running process can silently serve
|
||||
weeks-old code (happened Jul 6 → Jul 16).
|
||||
- Adding a telemetry field takes THREE places: agent payload (in
|
||||
`deploy_agent.sh`), `TelemetryPayload` in `central_api_prototype.py`, and the
|
||||
UI. Pydantic silently DROPS any field missing from `TelemetryPayload` —
|
||||
agents sent `cpu_temp` for a while with the backend discarding it and no
|
||||
error anywhere (found 2026-07-16).
|
||||
- Ports on this VM: 8000 backend, 6173 rmm-ui vite, 5173 auditor-portal vite
|
||||
(localhost only), 7514 + others auditor portal, 4430–4433 MeshCentral,
|
||||
Grafana also runs here. Check `ss -tlnp` before assigning a new port.
|
||||
|
||||
## Other services on this VM (not part of RMM deploys)
|
||||
|
||||
- `meshcentral.service` — MeshCentral remote management (node, ports 4430–4433)
|
||||
- `grafana` — monitoring dashboards
|
||||
- `/opt/auditor-portal` — separate project (its own vite/node dev servers)
|
||||
Reference in New Issue
Block a user