%s
`, errHTML, hostname, mac, opts.String(), notes))
}
func hostDetailPage(h *model.Host, ops []model.Operation, activity []model.ActivityEntry) string {
stateClass := stateColor(h.State)
led := ledClass(h.State)
canRebuild := h.State == model.StateRegistered || h.State == model.StateReady || h.State == model.StateFailed
var actions strings.Builder
if canRebuild {
actions.WriteString(fmt.Sprintf(``, h.ID))
}
actions.WriteString(fmt.Sprintf(``, h.ID))
var opsHTML strings.Builder
for _, op := range ops {
duration := ""
if op.CompletedAt != nil {
duration = op.CompletedAt.Sub(op.StartedAt).Truncate(1e9).String()
}
errCell := ""
if op.ErrorMessage != "" {
errCell = html.EscapeString(op.ErrorMessage)
}
opsHTML.WriteString(fmt.Sprintf(`
%s
%s
%s
%s
%s
`,
op.Kind, op.State, op.StartedAt.Format("2006-01-02 15:04"), duration, errCell))
}
ip := h.IPAddress
if ip == "" {
ip = "—"
}
var stuckWarning string
if h.State == model.StatePXEReady && time.Since(h.UpdatedAt) > 10*time.Minute {
mins := int(time.Since(h.UpdatedAt).Minutes())
stuckWarning = fmt.Sprintf(`
Host has been in PXE_READY for %d minutes with no iPXE request. This usually means the host failed to PXE boot — check secure boot settings, network connectivity, and BIOS boot order.
`, mins)
}
var activityHTML strings.Builder
for _, e := range activity {
activityHTML.WriteString(fmt.Sprintf(
`