46 lines
1.8 KiB
Go
46 lines
1.8 KiB
Go
package backupgood
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// **Each item's last good night** (novox/hq ADR 0571 clause 3, ADR 0564 §6; the lead, 2026-10-29): the node-backup holder
|
|
// restic keeps, from its tools bundle through the runtime on the night's file event (its night's process runs as the
|
|
// operator's account and holds no bus account, ADR 0436 §1-2), its own state `good`, one key `<node>.<module>.<item>` for every item a module
|
|
// declares that a backup path covers, written when it changes: the item, the path whose snapshot keeps it and the newest
|
|
// good night of its module (zero before the first). The self-check's probe of a stale backup reads it there. The package is restic's own, published by its series (ADR 0634 §4); the readers import it.
|
|
const (
|
|
ResticModule = "restic"
|
|
GoodState = "good"
|
|
GoodBucket = ResticModule + "_" + GoodState
|
|
GoodRead = ResticModule + "." + GoodState
|
|
GoodVersion = 1
|
|
)
|
|
|
|
// GoodRow is one key of restic's `good`.
|
|
type GoodRow struct {
|
|
V int `json:"v"`
|
|
Node string `json:"node"`
|
|
Module string `json:"module"`
|
|
Item string `json:"item"`
|
|
CoveredBy string `json:"covered_by"`
|
|
LastGood time.Time `json:"last_good,omitzero"`
|
|
}
|
|
|
|
// GoodKey is a row's key: `<node>.<module>.<item>`, as a disk-load reading's.
|
|
func GoodKey(node, module, item string) string { return node + "." + module + "." + item }
|
|
|
|
// DecodeGoodRow reads a row; it refuses another version.
|
|
func DecodeGoodRow(raw []byte) (GoodRow, error) {
|
|
var g GoodRow
|
|
if err := json.Unmarshal(raw, &g); err != nil {
|
|
return GoodRow{}, fmt.Errorf("backupgood: a last good night is not readable: %w", err)
|
|
}
|
|
if g.V != GoodVersion {
|
|
return GoodRow{}, fmt.Errorf("backupgood: a last good night of version %d, and this reads %d", g.V, GoodVersion)
|
|
}
|
|
return g, nil
|
|
}
|