restore

package
v0.1.0 Latest Latest
Warning

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

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

Documentation

Overview

Package restore implements restore Path B: a user restoring their own Space from a snapshot, back into OpenCloud (decisions.md, "Restore paths").

[S3 target] -> [kopia read/decrypt] -> [CS3 upload]

It is the mirror image of internal/backup, and shares its rules:

  • Authorization is the caller's, not the worker's: the API only ever hands this package a Space the caller is a *member* of. There is no admin path into a user's Space (decisions.md #2, #15) — being an admin grants nothing here.
  • v1 restores a whole snapshot into a fresh "Restore/<timestamp>/" folder. Live data is never overwritten and never deleted (decisions.md #3).
  • Nothing is staged on disk: entries stream from kopia straight into CS3, the same stance the backup path takes.
  • The plaintext Data Key and the target's credentials exist only in memory for the duration of a run.

Index

Constants

View Source
const DefaultRunTimeout = 6 * time.Hour

DefaultRunTimeout bounds a background restore. Like a backup run it is generous: a full Space may be large and being killed halfway is worse than being slow.

View Source
const RestoreFolder = "Restore"

RestoreFolder is the top-level folder every restore lands in. A restore never touches live data, so everything is written below RestoreFolder/<timestamp>/.

Variables

View Source
var (
	// ErrSpaceNotFound means the worker credential cannot see the Space.
	ErrSpaceNotFound = errors.New("restore: space not found")
	// ErrNotConfigured means the Space has no backup configuration or no keys.
	ErrNotConfigured = errors.New("restore: backup is not configured for this space")
	// ErrTargetUnavailable means the target is missing or unreadable.
	ErrTargetUnavailable = errors.New("restore: backup target is unavailable")
	// ErrSnapshotNotFound means the requested snapshot is not in the repository.
	ErrSnapshotNotFound = errors.New("restore: no such snapshot")
	// ErrRunInProgress means another run holds the Space's lock.
	ErrRunInProgress = errors.New("restore: a run is already in progress for this space")
	// ErrRunFailed means the restore itself failed.
	ErrRunFailed = errors.New("restore: restore run failed")
)

Sentinel errors the API maps onto status codes. Their messages are user-safe: they never name internal services, endpoints, or key material.

Functions

func RestoreFolderName

func RestoreFolderName(at time.Time) string

RestoreFolderName builds the space-relative folder a restore writes into: "Restore/<RFC3339 timestamp>". The timestamp is filename-safe on every platform the Space may later be synced to, so colons are replaced.

Types

type Clock

type Clock interface {
	Now() time.Time
}

Clock supplies the current time.

type Deps

type Deps struct {
	Spaces  cs3.SpaceReader
	Writer  cs3.SpaceWriter
	Configs spacecfg.Store
	Targets targets.Store
	Sealer  targets.CredSealer
	Keys    keys.Store
	Unwrap  keys.Wrapper
	Engine  snapshot.Engine
	Jobs    jobs.Store
	Locks   jobs.Locker
	// Logger receives operational detail: identifiers and counts, never key
	// material and never a user's file names.
	Logger *slog.Logger
	// Clock is injected for deterministic tests and names the restore folder.
	Clock Clock
	// RunTimeout bounds a background run started by StartRestore.
	RunTimeout time.Duration
	// Outcome tunes how a run's terminal outcome is written. The zero value is
	// the production setting; tests shorten the retry backoff.
	Outcome jobs.RecordOptions
	// Background owns the restores StartRestore puts in the background, so
	// that shutdown cancels and waits for them. Optional: when nil the Runner
	// keeps its own, which nothing stops — fine for tests, wrong for the service.
	Background *jobs.Background
}

Deps are the Runner's injected collaborators; every one is an interface so a restore can be exercised without OpenCloud, S3, or real keys.

type Result

type Result struct {
	JobID      string
	SpaceID    string
	SnapshotID snapshot.SnapshotID
	// Folder is the space-relative folder the snapshot was restored into.
	Folder     string
	FileCount  int64
	TotalBytes int64
	StartedAt  time.Time
	FinishedAt time.Time
}

Result summarises a completed restore. It carries no key material.

type Runner

type Runner struct {
	// contains filtered or unexported fields
}

Runner executes restore runs.

func NewRunner

func NewRunner(d Deps) (*Runner, error)

NewRunner validates dependencies and constructs a Runner.

func (*Runner) ListSnapshots

func (r *Runner) ListSnapshots(ctx context.Context, spaceID string) ([]snapshot.Info, error)

ListSnapshots returns the snapshots available for a Space, newest first. It is what the restore picker reads; the caller must already have verified the requester's membership.

func (*Runner) RunRestore

func (r *Runner) RunRestore(ctx context.Context, spaceID string, id snapshot.SnapshotID) (Result, error)

RunRestore performs one restore and waits for it to finish.

func (*Runner) StartRestore

func (r *Runner) StartRestore(ctx context.Context, spaceID string, id snapshot.SnapshotID) (string, error)

StartRestore accepts a restore and runs it in the background, returning the job id to poll. Everything that can fail fast — the Space, the lock — is resolved before returning.

Jump to

Keyboard shortcuts

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