mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-09-30 20:46:32 +00:00
The lux.cloud dashboard was blank because the collector could not reach a
single validator. Two independent breaks, either one fatal:
1. It called /ext. luxd 1.36 serves /v1 only — /ext/info is 404 — and the
collector's _rpc() maps any non-200 to None, so every field came back
null with no error anywhere.
2. It dialled 15 hardcoded public LoadBalancer IPs. There are now zero
LoadBalancer Services in lux-mainnet/testnet/devnet; those IPs do not
answer at all (connect timeout, not 404).
Both are the same root defect: the observer was outside the thing it observes
and had to be told where to look. So the observer moves in. Running in lux-k8s,
a validator's address is its pod IP, read from the pod list on every
collection — there is nothing left to configure and nothing left to go stale.
Chain facts come from the node itself over /v1: info.getNodeVersion,
getNodeID, getNodeIP, peers, isBootstrapped per chain, eth_blockNumber at
/v1/bc/C/rpc (the bc/ segment is load-bearing; /v1/C/rpc is not a route) and
platform.getHeight at /v1/bc/P, which quotes its integer.
That also collapses the MODE A / MODE B split: there is one path, not two.
Two corrections to what the old collector reported:
version is now what the fleet RUNS, not what the CR declares. The mainnet
LuxNetwork CR asks for ghcr.io/luxfi/node:v1.34.0, a tag that does not
exist; the nodes are on luxd/1.36.2. The dashboard must show the running
truth, so observation wins and image keeps the declared value.
external_ip becomes ip, matching console/lib/fleet.ts, and carries the
address the node advertises for itself (info.getNodeIP) rather than an
address someone wrote down.
Degraded is reported as degraded. A node that does not answer keeps every
field null and counts against nodes_rpc_ok; it is never smoothed over.
Placement: this stays in hanzoai/bootnode rather than folding into
hanzoai/cloud. cloud is not deployed on lux-k8s, and standing the whole
monolith up inside the chain cluster to run a read-only collector is a far
larger change than the collector itself. The surface is registered with zip's
Group; the route set is unchanged.
Deploy: Deployment/Service/RBAC in lux-k8s (lux-fleet.yaml, read-only —
list/get on pods and luxnetworks, no pods/proxy, no exec). The public URL
resolves to bootnode-k8s, so that cluster forwards just /v1/fleets/lux across
(lux-fleet-bridge.yaml); no other path on the host is touched.
Tests: a luxd stub that 404s anything outside /v1 and quotes platform height;
assertions that every probe path is under /v1, that no wire key is ever
omitted (an absent key reads as undefined and blanks a cell), that a down node
stays null, and that /v1/fleets/lux/zzzz is 404 next to a 200 on /overview.
Co-authored-by: Hanzo Dev <[email protected]>
64 lines
2.3 KiB
YAML
64 lines
2.3 KiB
YAML
# Hanzo CI/CD — one declarative build + test config.
|
|
#
|
|
# Read by platform.hanzo.ai, the sole orchestrator for this repo. On every
|
|
# push / PR the platform GitHub App delivers the event to platform, which reads
|
|
# THIS file and builds each image on the shared in-cluster `hanzo-build-*`
|
|
# arcbuild pool (bootnode has no self-hosted runners of its own — the reason the
|
|
# old GitHub-Actions `.github/workflows/cicd.yml` dead-ended and was removed).
|
|
# Registry credentials live in the cluster (kaniko-ghcr), never in GitHub.
|
|
#
|
|
# Images publish to ghcr.io/bootnode/bootnode as `<sha>-amd64-<tag-suffix>`.
|
|
# Rollout is GitOps, not platform: luxfi/universe pins the freshly-built tag and
|
|
# Argo applies it. The `deploy:` block below is therefore advisory (platform
|
|
# treats the Deployment-style `services:` form as build-only).
|
|
|
|
images:
|
|
- name: api
|
|
context: ./api
|
|
dockerfile: ./api/Dockerfile
|
|
repo: ghcr.io/bootnode/bootnode
|
|
tag-suffix: api
|
|
- name: web
|
|
context: ./console
|
|
dockerfile: ./console/Dockerfile
|
|
repo: ghcr.io/bootnode/bootnode
|
|
tag-suffix: web
|
|
# The Lux fleet API: pure Go, built from the repo-root module. Hanzo repos
|
|
# publish to ghcr.io/hanzoai — the two entries above are the legacy refs the
|
|
# running bootnode Deployments still pull.
|
|
- name: fleet
|
|
context: .
|
|
dockerfile: ./Dockerfile.fleet
|
|
repo: ghcr.io/hanzoai/bootnode
|
|
tag-suffix: fleet
|
|
|
|
# Commands run on the arc runner after the image builds. Non-zero fails the run.
|
|
test:
|
|
- name: api
|
|
run: >-
|
|
docker compose -f compose.yml up -d postgres redis >/dev/null 2>&1;
|
|
cd api &&
|
|
DATABASE_URL=postgresql+asyncpg://bootnode:bootnode@localhost:5432/bootnode
|
|
JWT_SECRET=ci API_KEY_SALT=ci
|
|
uv run pytest -q --tb=short
|
|
|
|
# Roll the freshly-built images onto the cluster. Only on the listed branches /
|
|
# on v* tags. The operator (or kubectl, via the KMS kubeconfig) patches each
|
|
# Service to the new image. Omit this block for build-only repos.
|
|
deploy:
|
|
cluster: bootnode-k8s
|
|
namespace: bootnode
|
|
on:
|
|
- main
|
|
services:
|
|
- name: web3-platform-api
|
|
image: api
|
|
- name: web3-platform-web-bootnode
|
|
image: web
|
|
|
|
# KMS source for /deploy secrets (GHCR_TOKEN, KUBECONFIG). workspace + endpoint
|
|
# are supplied as repo vars so this file carries no secrets.
|
|
kms:
|
|
path: /deploy
|
|
environment: prod
|