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
- Variables
- func Available() bool
- type Engine
- func (e *Engine) Check(ctx context.Context, destination string) error
- func (e *Engine) CopyBack(ctx context.Context, destinationName, remotePath, sub, hostPath string) error
- func (e *Engine) CopyDirectory(ctx context.Context, source, destinationName, destinationPath string) error
- func (e *Engine) CopyFile(ctx context.Context, source, destinationName, destinationPath string) error
- func (e *Engine) Disable(destination string) error
- func (e *Engine) Enable(ctx context.Context, destination, password string) (string, error)
- func (e *Engine) Enabled(destination string) bool
- func (e *Engine) Fetch(ctx context.Context, destinationName, remotePath string) ([]byte, error)
- func (e *Engine) Held(destination string) bool
- func (e *Engine) List(ctx context.Context, destinationName, remotePath, sub string) ([]rclone.File, error)
- func (e *Engine) Purge(ctx context.Context, destinationName, remotePath string) error
- func (e *Engine) RestoreDirectory(ctx context.Context, destinationName, remotePath, hostPath string) error
- func (e *Engine) RestoreFile(ctx context.Context, destinationName, remotePath, hostPath string) error
- func (e *Engine) Runs(destinationName, appPath string) ([]string, error)
- type ExitError
- type Router
- func (r *Router) CopyBack(ctx context.Context, destinationName, remotePath, sub, hostPath string) error
- func (r *Router) CopyDirectory(ctx context.Context, source, destinationName, destinationPath string) error
- func (r *Router) CopyFile(ctx context.Context, source, destinationName, destinationPath string) error
- func (r *Router) Fetch(ctx context.Context, destinationName, remotePath string) ([]byte, error)
- func (r *Router) List(ctx context.Context, destinationName, remotePath, sub string) ([]rclone.File, error)
- func (r *Router) Purge(ctx context.Context, destinationName, remotePath string) error
- func (r *Router) RestoreDirectory(ctx context.Context, destinationName, remotePath, hostPath string) error
- func (r *Router) RestoreFile(ctx context.Context, destinationName, remotePath, hostPath string) error
- func (r *Router) Runs(destinationName, appPath string) ([]string, error)
Constants ¶
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 ¶
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") )
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.
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 ¶
Types ¶
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine keeps backups in restic repositories.
func (*Engine) Check ¶ added in v0.4.82
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
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 ¶
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) Held ¶ added in v0.4.83
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) Purge ¶
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.
type Router ¶
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 (*Router) CopyDirectory ¶
func (*Router) Purge ¶
Purge deletes one run, from the repository if it is there and otherwise as the stamped copy it is.