mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-21 03:36:35 +00:00
refactor: stop probing predastore for a raft role
The daemon dialled a /status endpoint on each meta node to report which held raft leadership. That endpoint lived in predastore's s3db package; after the transport collapse the meta nodes speak rpc over QUIC and the in-process pipe and expose no HTTP surface, so the probe dialled a dead port. NodeStatusResponse.PredastoreRole is retained and left empty. Every consumer already guards on the empty string, so the CLI and the UI simply omit the badge, and restoring the probe later needs no contract change.
This commit is contained in:
committed by
Bryn Mailer
parent
96dc1af568
commit
94db344556
@@ -347,9 +347,8 @@ func (d *Daemon) handleNodeStatus(msg *nats.Msg) {
|
||||
// OVN roles are probed only on DB quorum members; compute-only nodes skip
|
||||
// the shell-out entirely.
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
wg.Add(1)
|
||||
go func() { defer wg.Done(); resp.NATSRole = d.queryNATSRole() }()
|
||||
go func() { defer wg.Done(); resp.PredastoreRole = d.queryPredastoreRole() }()
|
||||
if d.isOVNDBQuorumMember() {
|
||||
wg.Add(2)
|
||||
go func() { defer wg.Done(); resp.OVNNBRole = host.OVNDBRole(host.OVNNBTarget, host.OVNNBSchema) }()
|
||||
@@ -364,8 +363,7 @@ const (
|
||||
roleLeader = "leader"
|
||||
roleFollower = "follower"
|
||||
|
||||
natsMonitorPort = 8222
|
||||
predastoreDBPort = 6660
|
||||
natsMonitorPort = 8222
|
||||
)
|
||||
|
||||
// queryNATSRole queries the local NATS monitoring endpoint to determine this
|
||||
@@ -378,16 +376,6 @@ func (d *Daemon) queryNATSRole() string {
|
||||
return fetchNATSRole(url, roleHTTPClient)
|
||||
}
|
||||
|
||||
// queryPredastoreRole queries the local Predastore DB status endpoint to
|
||||
// determine this node's Raft role. Returns "leader", "follower", or "".
|
||||
func (d *Daemon) queryPredastoreRole() string {
|
||||
if !d.config.HasService("predastore") {
|
||||
return ""
|
||||
}
|
||||
url := "https://" + net.JoinHostPort(d.daemonIP(), strconv.Itoa(predastoreDBPort)) + "/status"
|
||||
return fetchPredastoreRole(url, roleTLSHTTPClient)
|
||||
}
|
||||
|
||||
// isOVNDBQuorumMember reports whether this node hosts the clustered OVN NB/SB
|
||||
// databases. Compute-only nodes short-circuit OVN role probes to "" without
|
||||
// shelling out to ovn-appctl.
|
||||
@@ -401,10 +389,6 @@ func (d *Daemon) isOVNDBQuorumMember() bool {
|
||||
|
||||
var roleHTTPClient = &http.Client{Timeout: 500 * time.Millisecond}
|
||||
|
||||
var roleTLSHTTPClient = &http.Client{
|
||||
Timeout: 500 * time.Millisecond,
|
||||
}
|
||||
|
||||
// fetchNATSRole queries a NATS /varz endpoint and returns "leader", "follower", or "".
|
||||
func fetchNATSRole(url string, client *http.Client) string {
|
||||
resp, err := client.Get(url) //nolint:noctx // internal monitoring call
|
||||
@@ -525,29 +509,6 @@ func resolveVMGPU(att gpu.GPUAttachment, byMdev, byPCI map[string]gpu.PoolEntry)
|
||||
return nil
|
||||
}
|
||||
|
||||
// fetchPredastoreRole queries a Predastore /status endpoint and returns "leader", "follower", or "".
|
||||
func fetchPredastoreRole(url string, client *http.Client) string {
|
||||
resp, err := client.Get(url) //nolint:noctx // internal monitoring call
|
||||
if err != nil {
|
||||
slog.Debug("Failed to query Predastore status", "err", err)
|
||||
return ""
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var status struct {
|
||||
IsLeader bool `json:"is_leader"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&status); err != nil {
|
||||
slog.Debug("Failed to decode Predastore status", "err", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
if status.IsLeader {
|
||||
return roleLeader
|
||||
}
|
||||
return roleFollower
|
||||
}
|
||||
|
||||
// handleNodeVMs responds with the list of VMs running on this node.
|
||||
// Used by the CLI: spx get vms.
|
||||
func (d *Daemon) handleNodeVMs(msg *nats.Msg) {
|
||||
|
||||
@@ -76,38 +76,3 @@ func TestFetchNATSRole_BadJSON(t *testing.T) {
|
||||
role := fetchNATSRole(srv.URL, srv.Client())
|
||||
assert.Empty(t, role)
|
||||
}
|
||||
|
||||
func TestFetchPredastoreRole_Leader(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"node_id":"1","state":"Leader","is_leader":true}`))
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
role := fetchPredastoreRole(srv.URL, srv.Client())
|
||||
assert.Equal(t, "leader", role)
|
||||
}
|
||||
|
||||
func TestFetchPredastoreRole_Follower(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`{"node_id":"2","state":"Follower","is_leader":false}`))
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
role := fetchPredastoreRole(srv.URL, srv.Client())
|
||||
assert.Equal(t, "follower", role)
|
||||
}
|
||||
|
||||
func TestFetchPredastoreRole_Unreachable(t *testing.T) {
|
||||
role := fetchPredastoreRole("https://127.0.0.1:1/status", &http.Client{})
|
||||
assert.Empty(t, role)
|
||||
}
|
||||
|
||||
func TestFetchPredastoreRole_BadJSON(t *testing.T) {
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(`not json`))
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
role := fetchPredastoreRole(srv.URL, srv.Client())
|
||||
assert.Empty(t, role)
|
||||
}
|
||||
|
||||
@@ -62,8 +62,11 @@ type NodeStatusResponse struct {
|
||||
InstanceTypes []InstanceTypeCap `json:"instance_types"`
|
||||
|
||||
// Leader roles for clustered services (empty string = service not running or not clustered)
|
||||
NATSRole string `json:"nats_role,omitempty"` // "leader" or "follower"
|
||||
PredastoreRole string `json:"predastore_role,omitempty"` // "leader" or "follower"
|
||||
NATSRole string `json:"nats_role,omitempty"` // "leader" or "follower"
|
||||
|
||||
// Never populated: predastore's meta nodes expose no status surface. Kept so
|
||||
// the JSON contract and the UI are unchanged when the probe is restored.
|
||||
PredastoreRole string `json:"predastore_role,omitempty"`
|
||||
|
||||
// OVN DB Raft roles ("leader"/"follower"/""); empty when the node is not an
|
||||
// OVN DB cluster member or OVN is standalone.
|
||||
|
||||
Reference in New Issue
Block a user