Files
hiveiq-ops/CLAUDE.md
T
2026-06-09 13:46:22 -04:00

7.5 KiB
Raw Blame History

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 (bcos.cloud) — see hiveiq-openmetal/CLAUDE.md
hiveiq-openmetal-dev/ Dev OpenMetal environment (bcos.dev) — docker-compose, nginx, .env.example
hiveiq-docs/ MkDocs documentation site — mkdocs.yml (main) + mkdocs-qsa.yml (QSA audit)

Production infra (bcos.cloud): hiveiq-openmetal/CLAUDE.md Dev environment (bcos.dev): hiveiq-openmetal-dev/DEV-ENVIRONMENT-SETUP.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/ — production only).

# 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)

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=<key>

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:

{
  "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-share173.231.195.254 Login: hiveiq@bcos.cloud

Pingvin Share v1.13.0 reads the JWT from cookies, not the Authorization header.

# 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":"<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

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/<service>/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).

# 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.

{ "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

import jwt, time
secret = '<JWT_SECRET value from .env>'
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.