Post-repair hardware validation pipeline for Proxmox cluster hosts. Go orchestrator + in-image agent + mkosi live image + bundled dnsmasq PXE + SQLite + HTMX/SSE UI + notify registry + janitor + full docs.
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"vetting/internal/model"
|
||||
"vetting/internal/store"
|
||||
"vetting/internal/web/templates"
|
||||
)
|
||||
|
||||
// TileEnricher builds a fully-populated TileData for a host. It looks
|
||||
// up the latest run's spec-diff count and hold-key artifact path so the
|
||||
// tile can render the "n critical diffs" badge and the ssh invocation
|
||||
// without the template package needing DB access.
|
||||
//
|
||||
// Used by both the Dashboard handler (initial render) and the SSE tile-
|
||||
// refresh path (agent_handlers.Hold, orchestrator runner) so every
|
||||
// place that renders a tile shows the same data.
|
||||
type TileEnricher struct {
|
||||
Runs *store.Runs
|
||||
Artifacts *store.Artifacts
|
||||
SpecDiffs *store.SpecDiffs
|
||||
}
|
||||
|
||||
// Build returns a TileData for (host, latest). Fails soft: DB errors
|
||||
// fall back to a tile without the extra fields rather than breaking
|
||||
// the whole dashboard.
|
||||
func (e *TileEnricher) Build(ctx context.Context, host model.Host, latest *model.Run) templates.TileData {
|
||||
t := templates.TileData{Host: host, Latest: latest}
|
||||
if latest == nil {
|
||||
return t
|
||||
}
|
||||
if e.SpecDiffs != nil {
|
||||
if diffs, err := e.SpecDiffs.ListForRun(ctx, latest.ID); err == nil {
|
||||
for _, d := range diffs {
|
||||
if d.Severity == "critical" && !d.Ignored {
|
||||
t.SpecDiffCritical++
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("tile: list spec_diffs run %d: %v", latest.ID, err)
|
||||
}
|
||||
}
|
||||
if e.Artifacts != nil {
|
||||
if arts, err := e.Artifacts.ListForRun(ctx, latest.ID); err == nil {
|
||||
for _, a := range arts {
|
||||
if a.Kind == "hold_key" {
|
||||
t.HoldKeyPath = a.Path
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("tile: list artifacts run %d: %v", latest.ID, err)
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// BuildByHost looks up the latest run itself — convenient for SSE tile
|
||||
// publishers that only know the host ID.
|
||||
func (e *TileEnricher) BuildByHost(ctx context.Context, host model.Host) templates.TileData {
|
||||
var latest *model.Run
|
||||
if e.Runs != nil {
|
||||
if r, err := e.Runs.LatestForHost(ctx, host.ID); err == nil {
|
||||
latest = r
|
||||
}
|
||||
}
|
||||
return e.Build(ctx, host, latest)
|
||||
}
|
||||
Reference in New Issue
Block a user