mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-10-25 02:31:30 +00:00
zip.Listen picks its transport from the address scheme, and a bare ":8000" means ZAP. The dashboard and the kubelet both speak HTTP, so the readiness probe's "GET " arrived as a ZAP frame header — frame size 1195725856, which is the ASCII — and the pod never went Ready. The address now carries its scheme. Co-authored-by: Hanzo Dev <[email protected]>
77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
// fleet serves the read-only luxd fleet overview the lux.cloud dashboard polls.
|
|
//
|
|
// It runs inside the cluster that hosts the fleet, reads every luxd pod over
|
|
// that node's own /v1 HTTP RPC, and answers one document:
|
|
//
|
|
// GET /health liveness
|
|
// GET /v1/fleets/lux/overview the fleet, optionally ?networks=a,b
|
|
//
|
|
// The response is public chain state — node IDs, versions, heights, peer
|
|
// counts — so it carries no auth and no secrets: the lux.cloud landing page
|
|
// renders it for signed-out visitors.
|
|
package main
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
|
|
luxlog "github.com/luxfi/log"
|
|
"github.com/zap-proto/zip"
|
|
"github.com/zap-proto/zip/middleware"
|
|
|
|
"github.com/hanzoai/bootnode/fleet"
|
|
)
|
|
|
|
func main() {
|
|
log := luxlog.New("module", "fleet")
|
|
|
|
cluster, err := fleet.NewInCluster()
|
|
if err != nil {
|
|
log.Error("cluster unreachable", "err", err)
|
|
os.Exit(1)
|
|
}
|
|
app := newApp(log, &fleet.Collector{Cluster: cluster, Prober: fleet.NewRPC(), Markets: fleet.NewGraph()})
|
|
|
|
// The scheme picks the transport: a bare address would serve ZAP, and the
|
|
// dashboard and the kubelet both speak HTTP.
|
|
addr := os.Getenv("FLEET_ADDR")
|
|
if addr == "" {
|
|
addr = "http://:8000"
|
|
}
|
|
log.Info("lux fleet listening", "addr", addr)
|
|
if err := app.Listen(addr); err != nil {
|
|
log.Error("serve failed", "err", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// newApp is the whole HTTP surface: two routes, one of them a Group.
|
|
func newApp(log luxlog.Logger, c *fleet.Collector) *zip.App {
|
|
app := zip.New(zip.Config{Logger: log, AppName: "lux-fleet"})
|
|
app.Use(
|
|
middleware.Recover(),
|
|
middleware.RequestID(),
|
|
middleware.CORS(middleware.CORSConfig{AllowMethods: []string{"GET", "OPTIONS"}}),
|
|
)
|
|
|
|
app.Get("/health", func(ctx *zip.Ctx) error {
|
|
return ctx.JSON(200, map[string]any{"status": "ok", "k8s_enrichment": fleet.Available()})
|
|
})
|
|
|
|
app.Group("/v1/fleets/lux").Get("/overview", func(ctx *zip.Ctx) error {
|
|
return ctx.JSON(200, c.Overview(ctx.Context(), networks(ctx.Query("networks"))))
|
|
})
|
|
return app
|
|
}
|
|
|
|
// networks parses the comma-separated ?networks= filter; empty means all.
|
|
func networks(q string) []string {
|
|
var out []string
|
|
for _, n := range strings.Split(q, ",") {
|
|
if n = strings.TrimSpace(n); n != "" {
|
|
out = append(out, n)
|
|
}
|
|
}
|
|
return out
|
|
}
|