restic

package
v0.4.97 Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package restic is the other way to keep a backup: in a restic repository on a destination, instead of one stamped copy per run.

A destination that has been switched to restic keeps the same names as the rest of the feature -- an app, a stamp, an operation's path under the run -- and this package answers the same seven calls the rclone client answers (copy a folder, copy a file, restore a folder, restore a file, read a file, list, purge). That is the whole integration: the planning, the hold-still, the manifest, the retention and the restore stay what they were, and only where the bytes go changes.

What the names map to. Every copy is one restic snapshot, tagged with the app, the stamp and the path it was asked to land at; a run is the snapshots that share a stamp, and the manifest, written last, is the run's last snapshot. Deleting a run forgets those snapshots and prunes. What restic adds over a stamped copy is that a run costs what changed since the last one, not another full copy, and that ownership and permissions survive the trip.

restic reaches the destination through the rclone remote it already is (`rclone:casaos-backup-<name>:...`), so credentials, S3, SFTP and the rest are not configured a second time.

Index

Constants

View Source
const RepositoryFolder = "casaos-restic"

RepositoryFolder is the folder a destination keeps its repository in. Next to the stamped copies, not in place of them: a destination switched to restic keeps whatever it held.

Variables

View Source
var (
	// ErrNotInstalled is the restic binary missing from this box.
	ErrNotInstalled = errors.New("restic is not installed on this box")
	// ErrAlreadyEnabled is a destination that is a restic repository already.
	ErrAlreadyEnabled = errors.New("this destination already keeps its backups with restic")
	// ErrKeyKept is a password given for a destination whose key this box still has.
	ErrKeyKept = errors.New("this box still has the key of this destination's repository; take it up again without a password")
	// ErrNotKept is a destination with no restic repository to go back from.
	ErrNotKept = errors.New("this destination does not keep its backups with restic")
	// ErrWrongPassword is a repository that is there and does not open with the
	// password it was given.
	ErrWrongPassword = errors.New("a restic repository is already there and this password does not open it")
	// ErrNothingHeld is a restore of something the repository does not hold.
	ErrNothingHeld = errors.New("the repository holds nothing at that path")
)
View Source
var CacheDir = "/var/cache/casaos/restic"

CacheDir is where restic keeps what it learns about a repository between runs. Given explicitly because the service has neither $HOME nor $XDG_CACHE_HOME, and without a place for it restic refuses to back anything up.

View Source
var KeyDir = "/var/lib/casaos/backups/restic"

KeyDir is where the repositories' passwords are kept, one file per destination. The box's own backup does not hold them: it may itself be kept in the repository a key opens, and a key that lies inside what it opens opens nothing on a new box.

A destination switched back to rclone keeps its key and gains a marker next to it, `<name>.key.off`: the repository is still read, only no longer written to.

Functions

func Available

func Available() bool

Available says whether the restic binary is on this box.

Types

type Engine

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

Engine keeps backups in restic repositories.

func New

func New() *Engine

New returns the engine that drives the restic binary on this box.

func (*Engine) Check added in v0.4.82

func (e *Engine) Check(ctx context.Context, destination string) error

Check asks restic whether the repository is sound: its index and snapshots read, and every pack file the index names is there with the size it should have.

shortcut: it does not read the data inside the packs, which downloads the whole repository (and at a cloud provider, bills it); a bit that rots inside a pack that is the right size passes. Add `--read-data-subset` if that is ever felt.

func (*Engine) CopyBack added in v0.4.83

func (e *Engine) CopyBack(ctx context.Context, destinationName, remotePath, sub, hostPath string) error

CopyBack puts `sub` of the snapshot taken for remotePath on hostPath, with its owners and modes, over what is there and deleting nothing.

func (*Engine) CopyDirectory

func (e *Engine) CopyDirectory(ctx context.Context, source, destinationName, destinationPath string) error

CopyDirectory backs a folder up as one snapshot.

func (*Engine) CopyFile

func (e *Engine) CopyFile(ctx context.Context, source, destinationName, destinationPath string) error

CopyFile backs one file up as one snapshot.

func (*Engine) Disable added in v0.4.83

func (e *Engine) Disable(destination string) error

Disable sends the next backups of a destination back to rclone. Nothing is deleted: the key stays, the repository stays, and Enable takes it up again.

func (*Engine) Enable

func (e *Engine) Enable(ctx context.Context, destination, password string) (string, error)

Enable makes a destination a restic repository and returns the password that opens it. An empty password makes a new one; a given one is for a repository that is already there -- a destination added again on another box, which is how a backup is restored somewhere else.

The password is returned here and kept nowhere a person can read it again except the box's own files: a repository whose password is lost is a pile of bytes, so the one time it is shown is the time to write it down.

func (*Engine) Enabled

func (e *Engine) Enabled(destination string) bool

Enabled says whether the backups to come at a destination go into restic.

func (*Engine) Fetch

func (e *Engine) Fetch(ctx context.Context, destinationName, remotePath string) ([]byte, error)

Fetch reads one file held in the repository.

func (*Engine) Held added in v0.4.83

func (e *Engine) Held(destination string) bool

Held says whether this box has the key of a restic repository at a destination: what the repository holds can be listed and restored, whichever engine the next backups go to.

func (*Engine) List added in v0.4.83

func (e *Engine) List(ctx context.Context, destinationName, remotePath, sub string) ([]rclone.File, error)

List lists one level of `sub` inside the snapshot taken for remotePath.

func (*Engine) Password added in v0.4.87

func (e *Engine) Password(destination string) (string, error)

Password is the key this box keeps for a destination's repository, read back so its owner can keep a copy away from this box: the box's own backup leaves it out.

func (*Engine) Purge

func (e *Engine) Purge(ctx context.Context, destinationName, remotePath string) error

Purge forgets one run -- every snapshot that shares its app and stamp -- and frees what nothing else uses.

func (*Engine) RestoreDirectory

func (e *Engine) RestoreDirectory(ctx context.Context, destinationName, remotePath, hostPath string) error

RestoreDirectory makes hostPath hold what the snapshot held, and nothing else.

The folder the snapshot was taken of is read from the snapshot itself, never from a manifest: restic keeps the full path it saw, and `snapshot:folder` names that folder as the root to restore from.

func (*Engine) RestoreFile

func (e *Engine) RestoreFile(ctx context.Context, destinationName, remotePath, hostPath string) error

RestoreFile puts one file from the repository at hostPath.

func (*Engine) Runs

func (e *Engine) Runs(destinationName, appPath string) ([]string, error)

Runs lists the apps a repository holds backups of, or an app's runs by stamp.

type ExitError

type ExitError struct {
	Code    int
	Message string
}

ExitError is restic failing: its exit code, and the last of what it said.

func (*ExitError) Error

func (e *ExitError) Error() string

type Router

type Router struct {
	*rclone.Client
	Restic *Engine
	// contains filtered or unexported fields
}

Router answers a backup's nine calls. The copies go where the destination keeps its backups now -- restic where it is switched to it, rclone everywhere else. What is read goes to both while the box holds the key of a repository there: the stamped copies a destination held before it was switched, and the repository it keeps after it was switched back, stay listed, restorable and subject to the schedule's retention, which counts them as the one set of runs they are.

It carries the rclone client along, so the calls that are not about the bytes of a backup -- listing destinations, checking one, creating one -- reach rclone unchanged.

func NewRouter

func NewRouter() *Router

NewRouter is the engine every backup call goes through.

func (*Router) CopyBack added in v0.4.83

func (r *Router) CopyBack(ctx context.Context, destinationName, remotePath, sub, hostPath string) error

func (*Router) CopyDirectory

func (r *Router) CopyDirectory(ctx context.Context, source, destinationName, destinationPath string) error

func (*Router) CopyFile

func (r *Router) CopyFile(ctx context.Context, source, destinationName, destinationPath string) error

func (*Router) Fetch

func (r *Router) Fetch(ctx context.Context, destinationName, remotePath string) ([]byte, error)

func (*Router) List added in v0.4.83

func (r *Router) List(ctx context.Context, destinationName, remotePath, sub string) ([]rclone.File, error)

func (*Router) Purge

func (r *Router) Purge(ctx context.Context, destinationName, remotePath string) error

Purge deletes one run, from the repository if it is there and otherwise as the stamped copy it is.

func (*Router) RestoreDirectory

func (r *Router) RestoreDirectory(ctx context.Context, destinationName, remotePath, hostPath string) error

func (*Router) RestoreFile

func (r *Router) RestoreFile(ctx context.Context, destinationName, remotePath, hostPath string) error

func (*Router) Runs

func (r *Router) Runs(destinationName, appPath string) ([]string, error)

Runs lists the apps a destination holds backups of, or an app's runs by stamp: those of the repository and the stamped copies together.

Jump to

Keyboard shortcuts

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