Documentation
¶
Overview ¶
Package blobmirror mirrors the local blob store to the platform backup target (ADR-0208 Decision 4): each run freezes the store into a hard-link image, uploads the objects whose id the current epoch lacks, then an index and a manifest, written last; nothing on the target is ever read, overwritten or deleted. Restore puts a generation back.
Index ¶
Constants ¶
const Format = 1
Format is the mirror manifest's format. Object.Gen is the n of objects/<id>/<n>/; Object.SHA256 is the hex SHA-256 of its stored bytes, all parts in order.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Config ¶
type Config struct {
Dir, FrozenDir string
Target blob.Bucket
Ready func(context.Context) (conditional bool, err error)
Seal backup.Seal
Recipients []string
Interval, Rebaseline, Retention, RetryInterval time.Duration
Logger *slog.Logger
Hold interface{ Held() bool }
Record func(start time.Time, err error)
}
Config builds a Mirror. Target is backup.target; Ready is its Ready then Conditional (ADR-0203), nil ⇒ always ready and conditional; Seal and Recipients are ADR-0204's. RetryInterval follows a failed run as ADR-0205 Decision 2's does. Hold is ADR-0206's gate, nil ⇒ never held; Record is ADR-0205's Recorder("blob"), nil ⇒ log only.
type Entry ¶
Entry is one generation a listing shows; At is its manifest's ModTime, zero while incomplete.
type Manifest ¶
type Manifest struct {
Format int `json:"format"`
Generation uint64 `json:"generation"`
Epoch uint64 `json:"epoch"`
At v1alpha1.Timestamp `json:"at"`
Funcd string `json:"funcd"`
Objects int `json:"objects"`
Index backup.StoreFile `json:"index"`
Recipients []string `json:"recipients,omitempty"`
}
Manifest is a generation's manifest.yaml, created last. Recipients are the sorted fingerprints the objects and the index are sealed to, in every object id; none ⇒ unsealed.
func Restore ¶
func Restore(ctx context.Context, src blob.Bucket, generation uint64, dst blob.Bucket, open backup.Opener) (_ Manifest, err error)
Restore puts generation n of src into the empty dst (ADR-0208 Decision 6): it calls open once with the manifest's recipients and reads the index through it; an object is read through it too, or as is when the manifest names no recipient (user bytes, never sniffed). A missing part or sha256- key is fault.NotFound and a non-empty dst fault.Conflict, both before any write; an object whose stored bytes miss their SHA-256 is fault.Invalid. An error after a write deletes what it wrote.
type Mirror ¶
type Mirror interface {
// Run writes one generation.
Run(ctx context.Context) (Manifest, error)
// Loop runs when due until ctx ends: due an Interval after the newest complete generation, after a failure at
// most RetryInterval later. Each outcome goes to Record, a Ready refusal too, a cancel never. While held it
// neither runs nor records and checks again after Interval.
Loop(ctx context.Context)
}
Mirror runs the local store's mirror.
type Object ¶
type Object struct {
Key string `json:"key"`
ID string `json:"id"`
SHA256 string `json:"sha256"`
ContentType string `json:"contentType,omitempty"`
Gen uint64 `json:"gen"`
Parts int `json:"parts"`
Size int64 `json:"size"`
Metadata map[string]string `json:"metadata,omitempty"`
}
Object is one index line: a store object and its upload.