restic

package
v0.4.80 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: Apache-2.0 Imports: 15 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")
	// 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. It is inside /var/lib/casaos/backups, which the box's own backup already holds.

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) 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) 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 a destination keeps its backups with 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) 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
}

Router answers a backup's seven calls with restic where the destination keeps its backups with restic, and with rclone everywhere else.

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) 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) Purge

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

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)

Jump to

Keyboard shortcuts

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