restore

package
v1.76.1 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package restore writes a backup (backup.Reader, verified whole when it was opened) into an installation of layout v5, and shows beforehand what that would do.

Preview and Apply

Preview reads the destination and reports, per module and section, what would be created, overwritten or left alone. It writes nothing. The Report carries names and versions only; a value, a secret or a blob body is read to be compared and never leaves the package.

Apply runs on an archive backup.Open verified before the first write (a tampered or truncated archive is refused with nothing written), plans, refuses a destination that holds a different value unless Options.Overwrite is set, writes, and reads everything back: any record that differs makes the call fail with ErrVerify. The destination is not wiped; records the archive does not hold are left as they are.

What is restored

  • State records with port.State.Put, carrying the lifetime that is left: a record's absolute expiry in the archive is turned into a remaining lifetime now, and an expired record is skipped.
  • Index sets with port.Index.Add; on overwrite the members the archive does not hold are removed.
  • Secrets as documents, created with an empty revision, or written over the current revision on overwrite.
  • Blobs, each a file of the archive, checked against its hash.

Leases, notifications, gates, caches, dedupe records and the maintenance record are never restored: the modules regenerate them, and the maintenance record belongs to the restore run that calls this package. An archive that holds one anyway has it counted as regenerated.

Order

Modules are written in port.Modules order with oidc last, and inside oidc the secrets and blobs and the records first and the signing key ring (its records and its index sets) at the very end, so that a restore that stops half way never leaves a ring whose sessions and tokens are missing.

Resuming

Apply is idempotent: a record already equal to the archive's is not written again, so a run that was stopped (context cancelled, a write that failed) is continued by calling Apply again.

Index

Constants

View Source
const (
	TypeState  = "state"
	TypeIndex  = "index"
	TypeSecret = "secret"
	TypeBlob   = "blob"
)

Record types of an Item.

Variables

View Source
var (
	// ErrNotEmpty is a destination that holds a different value for a record
	// of the archive, and no overwrite was asked for. Nothing was written.
	ErrNotEmpty = errors.New("restore: the destination holds different data (use overwrite)")
	// ErrVerify is a restore whose read-back differs from the archive.
	ErrVerify = errors.New("restore: the destination differs from the archive after the restore")
	// ErrArchive is a record the archive should not hold: another module's
	// key, a name outside the module's blob prefixes, an unknown namespace.
	ErrArchive = errors.New("restore: the archive holds a record that does not belong")
)

Errors a caller can match with errors.Is.

Functions

This section is empty.

Types

type Action

type Action string

Action is what a restore does (or did) with one record.

const (
	// Create: the destination holds nothing under the name.
	Create Action = "create"
	// Overwrite: the destination holds a different value.
	Overwrite Action = "overwrite"
	// Same: the destination already holds the archive's value.
	Same Action = "same"
	// Expired: the record had expired by now and is skipped.
	Expired Action = "expired"
	// Regenerated: a lease, cache or the like, which the module rebuilds.
	Regenerated Action = "regenerated"
)

The actions.

type Item

type Item struct {
	Type   string `json:"type"`
	Name   string `json:"name"`
	Action Action `json:"action"`
	// Version is the destination's current revision, for [Overwrite].
	Version string `json:"version,omitempty"`
}

Item is one record that is not Same: its name and, for an overwrite, the version the destination holds now. It never carries a value.

type Options

type Options struct {
	// Overwrite lets Apply replace a different value in the destination.
	Overwrite bool
	// Now is the clock the remaining lifetimes are computed with.
	Now func() time.Time
	// MaxItems bounds the names listed per section of the report; the default
	// is 100. The counts are always exact.
	MaxItems int
}

Options are the optional parts of a run.

type Report

type Report struct {
	Installation string          `json:"installation"`
	ID           string          `json:"id"`
	Layout       backup.Layout   `json:"layout"`
	Created      string          `json:"created"`
	Sections     []SectionReport `json:"sections"`
}

Report is the outcome of Preview or Apply.

func Apply

func Apply(ctx context.Context, r *backup.Reader, t Target, opt Options) (*Report, error)

Apply restores the archive, which backup.Open verified whole before anything is written; a different value in the destination refuses the restore unless Options.Overwrite; afterwards every record is read back. The report is the plan that was carried out: Create and Overwrite count the writes.

func Preview

func Preview(ctx context.Context, r *backup.Reader, t Target, opt Options) (*Report, error)

Preview reports what Apply would do with an archive backup.Open verified. It writes nothing.

func (*Report) Totals

func (r *Report) Totals() SectionReport

Totals sums the counts of every section.

type SectionReport

type SectionReport struct {
	Module      port.Module    `json:"module"`
	Section     backup.Section `json:"section"`
	Create      int            `json:"create"`
	Overwrite   int            `json:"overwrite"`
	Same        int            `json:"same"`
	Expired     int            `json:"expired"`
	Regenerated int            `json:"regenerated"`
	// Items lists the records that are not Same, up to [Options.MaxItems];
	// Truncated says the list is shorter than the counts.
	Items     []Item `json:"items,omitempty"`
	Truncated bool   `json:"truncated,omitempty"`
}

SectionReport is one module's section.

type Table

type Table interface {
	port.State
	port.Index
}

Table is the State and the Index of one module's table.

type Target

type Target struct {
	// Table returns the table of a module.
	Table func(port.Module) Table
	// Secrets are the installation's secrets on layout v5.
	Secrets *secretstore.StoresV5
	// Blob holds the modules' blobs.
	Blob port.Blob
}

Target is the installation a backup is restored into.

Jump to

Keyboard shortcuts

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