blobmirror

package
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: Apache-2.0 Imports: 31 Imported by: 0

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

View Source
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

func LifecycleRule

func LifecycleRule(rebaseline, retention time.Duration) (prefix string, days int)

LifecycleRule is the operator's expiry of the target's blob/ prefix: ⌈(rebaseline + retention) / 24h⌉ days, so no object expires before the last generation of its epoch is retention old.

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

type Entry struct {
	Generation, Epoch uint64
	Complete          bool
	At                time.Time
}

Entry is one generation a listing shows; At is its manifest's ModTime, zero while incomplete.

func List

func List(ctx context.Context, src blob.Bucket) ([]Entry, error)

List lists the generations under blob/ once, by generation; no read.

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.

func New

func New(cfg Config) (Mirror, error)

New checks cfg: an empty Dir, no Target, or a time not positive, or a rebaseline or retention below the interval, is fault.Invalid. An empty FrozenDir is <Dir>-frozen.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL