Files
selfpost/internal/health/health.go
T
mix 8ce050ef7f release: 0.1.0: Phases 0-11: panel, Postfix/DKIM, milter, backup, Docker image
Initial feature-complete implementation of the v1.0 specification (phases 0-11 of `docs/implementation-plan.md`).
Added:
  - Panel (Go, single static binary) with SQLite persistence, one-time
  - Domain management with per-domain DKIM (RSA-2048, generated in pure Go) and
  - Application (sender identity) management: SASL credentials via `sasldb2`,
  - Full Postfix relay config generated from env at container start: SMTPS 465,
  - Journal milter (pure Go, `go-milter`) recording every send to `send_log`;
  … (6 more in CHANGELOG)

Full detail: CHANGELOG.md (0.1.0).
2026-09-22 15:24:51 +03:00

54 lines
1.8 KiB
Go

// Package health reports the running container's own operating state for the
// panel's status screen: the supervised processes, the TLS certificate Postfix
// serves, and the milter sockets delivery depends on.
//
// Every check is read-only and reports a problem as a Status value rather than
// an error return, so one broken component degrades a single line of the status
// page instead of blanking the whole thing. The package also owns the Status
// vocabulary shared with internal/dnscheck, so the panel renders every check —
// local or DNS — through one set of badges.
package health
// Status is the outcome of a single check, in the order the status page treats
// them: unknown < ok < warn < error, worst wins for a group.
type Status string
const (
// StatusUnknown means the check could not be performed at all (a missing
// setting, an unreachable resolver) — not evidence of a problem.
StatusUnknown Status = "unknown"
// StatusOK means the checked component is in its expected state.
StatusOK Status = "ok"
// StatusWarn means something is off but mail still flows.
StatusWarn Status = "warn"
// StatusError means mail delivery is (or soon will be) affected.
StatusError Status = "error"
)
// severity orders statuses so a group can report its worst member.
func (s Status) severity() int {
switch s {
case StatusError:
return 3
case StatusWarn:
return 2
case StatusOK:
return 1
default:
return 0
}
}
// Worst returns the most severe of the given statuses, or StatusUnknown when
// there are none. It is how the status page rolls a list of checks up into one
// headline.
func Worst(statuses ...Status) Status {
worst := StatusUnknown
for _, s := range statuses {
if s.severity() > worst.severity() {
worst = s
}
}
return worst
}