Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7.5 KiB
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-share — 173.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(notaccessToken), signed HS512 - Route API calls through NGINX:
https://api.bcos.cloud/<service>/api/... - Login body uses
emailfield (notusername)
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.