Files
br ca6cdcca63 software steht so weit.
jetzt build + docker build und testen
2026-10-02 13:25:34 +02:00

62 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package store
import (
"context"
"strings"
"time"
"unicode"
"unicode/utf8"
)
// Maintenance ist eine angemeldete Wartung eines Knotens.
type Maintenance struct {
Since time.Time
Until time.Time // Nullwert = unbefristet
Reason string // intern (Log, Monitoring) – nie öffentlich
PublicReason string // optional, ersetzt den Standardtext der Wartungsseite
}
// Active meldet, ob die Wartung zum Zeitpunkt now gilt (nil = keine).
func (m *Maintenance) Active(now time.Time) bool {
return m != nil && (m.Until.IsZero() || now.Before(m.Until))
}
const (
maxPublicReason = 300
maxReason = 500
)
// validText: einzeilig, ohne Steuerzeichen, höchstens max Zeichen.
func validText(s string, max int) bool {
return utf8.RuneCountInString(s) <= max && !strings.ContainsFunc(s, unicode.IsControl)
}
// SetNodeMaintenance meldet eine Wartung an (Since = jetzt). m.Until muss
// in der Zukunft liegen oder Nullwert (unbefristet) sein.
func (s *Store) SetNodeMaintenance(ctx context.Context, nodeID string, m Maintenance) error {
now := s.now()
switch {
case !m.Until.IsZero() && !m.Until.After(now):
return invalid("Wartungsende liegt nicht in der Zukunft")
case !validText(m.PublicReason, maxPublicReason):
return invalid("öffentlicher Grund: einzeilig, höchstens %d Zeichen", maxPublicReason)
case !validText(m.Reason, maxReason):
return invalid("Grund: einzeilig, höchstens %d Zeichen", maxReason)
}
var until any
if !m.Until.IsZero() {
until = formatTime(m.Until)
}
res, err := s.db.ExecContext(ctx, `UPDATE nodes SET maintenance_since = ?, maintenance_until = ?,
maintenance_reason = ?, maintenance_public_reason = ? WHERE id = ?`,
formatTime(now), until, m.Reason, m.PublicReason, nodeID)
return requireAffected(res, err, "Knoten "+nodeID)
}
// ClearNodeMaintenance beendet die Wartung eines Knotens.
func (s *Store) ClearNodeMaintenance(ctx context.Context, nodeID string) error {
res, err := s.db.ExecContext(ctx, `UPDATE nodes SET maintenance_since = NULL, maintenance_until = NULL,
maintenance_reason = '', maintenance_public_reason = '' WHERE id = ?`, nodeID)
return requireAffected(res, err, "Knoten "+nodeID)
}