commit d1a427cea023b27ca80735c248a7635af8e3c16d Author: Johannes Date: Mon Jun 1 14:38:39 2026 -0400 docs: add root CLAUDE.md for hiveiq-ops Covers sub-project index, agent release workflow, What's New releases.json process, share.bcos.cloud API, and common operational mistakes. Content sourced from hiveops-src CLAUDE.md sections that belong to ops rather than application source. Co-Authored-By: Claude Sonnet 4.6 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..530f97a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,202 @@ +# CLAUDE.md — hiveiq-ops + +Operations repo for the HiveIQ/HiveOps platform. Split from `hiveops-src` (application source) to separate deployment configs, infrastructure, and documentation from service code. + +**Application source:** `/source/hiveops-src/` +**Ops source (this repo):** `/source/hiveiq-ops/` + +--- + +## Sub-Projects + +| Directory | Purpose | +|-----------|---------| +| `hiveiq-devops/` | Docker Compose + Kubernetes + Ansible deployment configs — see `hiveiq-devops/CLAUDE.md` | +| `hiveiq-openmetal/` | Production OpenMetal cloud infrastructure (VMs, DNS, CDN, bcos infra) — see `hiveiq-openmetal/CLAUDE.md` | +| `hiveiq-docs/` | MkDocs documentation site — `mkdocs.yml` (main) + `mkdocs-qsa.yml` (QSA audit) | + +**Start here for infra/VM reference:** `hiveiq-openmetal/CLAUDE.md` +**Start here for deployment configs:** `hiveiq-devops/CLAUDE.md` + +--- + +## Releasing a New Agent Version + +The agent build lives in `/source/hiveops-src/hiveops-agent/` but the release deploys to CDN (managed here in `hiveiq-openmetal`). + +```bash +# 1. Bump version in source repo +cd /source/hiveops-src/hiveops-agent +mvn versions:set -DnewVersion=X.Y.Z -DgenerateBackupPoms=false + +# 2. Build fat JAR +mvn clean package -DskipTests + +# 3. Build dist packages — run sequentially (build-dist.sh clears dist/ each run) +deployment/build-dist.sh --release --platform windows +scp -i ~/.ssh/id_ed25519_hiveiq deployment/dist/hiveops-agent-X.Y.Z-standard-windows.zip bcosadmin@173.231.195.252:~/hiveiq/hiveops-openmetal/hiveops/instances/browser/downloads/agent/ + +deployment/build-dist.sh --release --patch --platform windows +scp -i ~/.ssh/id_ed25519_hiveiq deployment/dist/hiveops-agent-X.Y.Z-patch-windows.zip bcosadmin@173.231.195.252:~/hiveiq/hiveops-openmetal/hiveops/instances/browser/downloads/agent/ + +deployment/build-dist.sh --release --platform linux +scp -i ~/.ssh/id_ed25519_hiveiq deployment/dist/hiveops-agent-X.Y.Z-standard-linux.tar.gz bcosadmin@173.231.195.252:~/hiveiq/hiveops-openmetal/hiveops/instances/browser/downloads/agent/ + +deployment/build-dist.sh --release --patch --platform linux +scp -i ~/.ssh/id_ed25519_hiveiq deployment/dist/hiveops-agent-X.Y.Z-patch-linux.tar.gz bcosadmin@173.231.195.252:~/hiveiq/hiveops-openmetal/hiveops/instances/browser/downloads/agent/ + +# 4. Update CDN manifest — pass all 5 args so patches appear in Fleet › Artifacts +ssh -i ~/.ssh/id_ed25519_hiveiq bcosadmin@173.231.195.252 +cd ~/hiveiq/hiveops-openmetal/hiveops/instances/browser +./scripts/release-agent.sh X.Y.Z \ + "hiveops-agent-X.Y.Z-standard-windows.zip" \ + "hiveops-agent-X.Y.Z-standard-linux.tar.gz" \ + "hiveops-agent-X.Y.Z-patch-windows.zip" \ + "hiveops-agent-X.Y.Z-patch-linux.tar.gz" + +# 5. Commit version bump + push in source repo +cd /source/hiveops-src/hiveops-agent +git add -A && git commit -m "chore(agent): bump version to X.Y.Z" +git push + +# 6. Update VERSIONS.md in hiveops-src +``` + +**Bearer token revocation rule:** before revoking any `agent.auth.token`, push a CONFIG_UPDATE fleet-wide and wait for all tasks to drain. Revoking while ATMs still hold the token kills module threads — recovery requires a manual JVM restart on every affected ATM. + +--- + +## Updating "What's New" Release Notes + +**Repo:** `/source/hiveops-src/hiveops-release/` (separate source repo, deploy via script) + +```bash +cd /source/hiveops-src/hiveops-release +# 1. Edit releases.json — prepend new entry to the relevant service array +# 2. Deploy +./deploy.sh +# 3. Verify +# https://cdn.bcos.cloud/whats-new?app= +``` + +### Service keys in releases.json + +| Key | Service | +|-----|---------| +| `browser` | HiveIQ Browser (Electron) | +| `incident` | Incident web app | +| `fleet` | Fleet web app (`fleet.bcos.cloud`) | +| `devices` | Devices web app | +| `transactions` | Transactions web app | +| `analytics` | Analytics web app | +| `agent` | HiveIQ Agent (ATM JAR) | +| `journal` | Journal microservice | +| `rules` | Journal parsing rules | +| `reports` | Reports microservice | + +Entry format: +```json +{ + "version": "v1.2.0", + "title": "Short descriptive title", + "date": "May 10, 2026", + "sections": [ + { + "type": "added", + "items": [ + { "title": "Feature name", "note": "One sentence describing what changed and why." } + ] + } + ] +} +``` +Section `type` values: `added`, `fixed`, `improved`, `changed`, `removed`. + +--- + +## share.bcos.cloud — Customer File Distribution + +Used to distribute patches that can't be auto-updated (e.g. ATEC Java 8 branch with `agent.update.enabled=false`). + +**VM:** `bcos-share` — `173.231.195.254` +**Login:** `hiveiq@bcos.cloud` + +Pingvin Share v1.13.0 reads the JWT from **cookies**, not the `Authorization` header. + +```bash +# 1. Sign in +curl -s -c /tmp/pingvin-cookies.txt -X POST https://share.bcos.cloud/api/auth/signIn \ + -H "Content-Type: application/json" \ + -d '{"email":"hiveiq@bcos.cloud","password":""}' + +# 2. Create share +curl -s -b /tmp/pingvin-cookies.txt -X POST https://share.bcos.cloud/api/shares \ + -H "Content-Type: application/json" \ + -d '{"id":"my-share-id","expiration":"never","recipients":[],"description":"..."}' + +# 3. Upload file (chunk params as query string, body is raw binary) +curl -s -b /tmp/pingvin-cookies.txt -X POST \ + "https://share.bcos.cloud/api/shares/my-share-id/files?chunkIndex=0&totalChunks=1&name=filename.zip" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@/path/to/file.zip" + +# 4. Complete +curl -s -b /tmp/pingvin-cookies.txt -X POST \ + https://share.bcos.cloud/api/shares/my-share-id/complete +``` + +Share URL: `https://share.bcos.cloud/s/{shareId}` + +--- + +## HiveIQ API — Service Account Login + +```bash +LOGIN=$(curl -s -X POST "https://api.bcos.cloud/auth/api/login" \ + -H "Content-Type: application/json" \ + -d '{"email":"hiveiq@bcos.cloud","password":"HiveIQ-Admin-2026!","rememberMe":false}') +JWT=$(echo "$LOGIN" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('token',''))") +``` + +- Response field is `token` (not `accessToken`), signed HS512 +- Route API calls through NGINX: `https://api.bcos.cloud//api/...` +- Login body uses `email` field (not `username`) + +--- + +## Common Operational Mistakes + +### PostgreSQL is on a SEPARATE VM +The `hiveiq-postgres` container runs on **`10.10.10.188`** (hiveiq-database VM), NOT on `173.231.195.250` (services VM). + +```bash +# CORRECT — ProxyJump to database VM +ssh -i ~/.ssh/id_ed25519_hiveiq -J bcosadmin@173.231.195.250 bcosadmin@10.10.10.188 \ + "docker exec hiveiq-postgres psql -U hiveiq -d hiveiq_journal -c 'SELECT ...'" + +# WRONG — postgres container is not on the services VM +ssh -i ~/.ssh/id_ed25519_hiveiq bcosadmin@173.231.195.250 \ + "docker exec hiveiq-postgres ..." +``` + +### NEVER use backslashes in fleet task payloads +All paths in `configPatch` (LOG_COLLECT_PATH, CONFIG_UPDATE, etc.) must use **forward slashes**. The agent normalizes separators on Windows. + +```json +{ "path": "C:/hiveops-agent/logs/hiveops-agent.log" } // CORRECT +{ "path": "C:\\hiveops-agent\\logs\\hiveops-agent.log" } // WRONG +``` + +### Generating a JWT without a real user account + +```python +import jwt, time +secret = '' +token = jwt.encode({ + 'sub': '1', 'email': 'admin@bcos.cloud', 'role': 'MSP_ADMIN', + 'iat': int(time.time()), 'exp': int(time.time()) + 3600 +}, secret.encode('utf-8'), algorithm='HS256') +print(token) +``` + +Do not base64-decode the secret — pass the raw string encoded as UTF-8.