Host detail v2: full pipeline + per-stage logs + WoL diagnostics
CI / Lint + build + test (push) Has been cancelled
CI / Lint + build + test (push) Has been cancelled
Pipeline now always renders all 13 nodes (3 pre-stage + 9 stage +
Completed), synthesising ghosts from run state when stage rows
aren't seeded yet. Makes a WaitingWoL host show the full timeline
ahead of it instead of just 4 dots.
Agent tags each log line with its stage; logs.Hub fans out to both
log-{runID} and log-{runID}-{stage} SSE events so the detail page
can show per-stage tabs with a pure-CSS radio-sibling switch. Flat
run log prepends [stage] so grep still works.
Dispatcher writes picked/sent-WoL/heartbeat lines into the per-run
log — the operator opens the detail page, sees WaitingWoL stuck,
and reads exactly what the dispatcher did and why nothing's
progressing, instead of having to tail journalctl on the LXC.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -181,6 +181,11 @@ func (a *Agent) Claim(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
log.Printf("agent claimed: run=%d agent_ip=%s", runID, agentIP)
|
||||
if a.Logs != nil {
|
||||
if w, err := a.Logs.WriterFor(runID); err == nil {
|
||||
w.Append(logs.Line{Level: "info", Text: fmt.Sprintf("agent claimed from %s — entering Inventory", agentIP)})
|
||||
}
|
||||
}
|
||||
|
||||
// Stage-driven agent needs a bit of per-run config: the device
|
||||
// allowlist (serial + expected size) for Storage, and the iperf3
|
||||
@@ -331,6 +336,7 @@ type LogBatch struct {
|
||||
type LogLine struct {
|
||||
TS string `json:"ts,omitempty"` // RFC3339Nano; server clock used if empty
|
||||
Level string `json:"level,omitempty"` // info|warn|error|debug
|
||||
Stage string `json:"stage,omitempty"` // optional stage tag for per-stage log fan-out
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
@@ -356,7 +362,7 @@ func (a *Agent) Log(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
for _, l := range batch.Lines {
|
||||
ts, _ := time.Parse(time.RFC3339Nano, l.TS)
|
||||
writer.Append(logs.Line{TS: ts, Level: l.Level, Text: l.Text})
|
||||
writer.Append(logs.Line{TS: ts, Level: l.Level, Stage: l.Stage, Text: l.Text})
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"ok": true, "written": len(batch.Lines)})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user