cloud

package
v0.0.0-...-bd25097 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: AGPL-3.0 Imports: 30 Imported by: 0

Documentation

Overview

Package cloud keeps an encrypted copy of a backup in an S3-compatible bucket the owner controls (D70): AWS S3, Cloudflare R2, Backblaze B2, Wasabi, MinIO. The client is a small Signature V4 implementation on the standard library (path-style URLs, one PUT per object), so no SDK is pulled in.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotConfigured = errors.New("cloud: backup is not configured")
	ErrBusy          = errors.New("cloud: a backup is already running")
)

ErrNotConfigured means a setting the run needs is empty; ErrBusy means a run is already going.

View Source
var ErrOpen = errors.New("cloud: archive does not open with this key, or it is damaged")

ErrOpen means the archive does not open with this key or is damaged; no plaintext was trusted.

Functions

func Configured

func Configured(c store.CloudConfig) bool

Configured reports whether every value a run needs is present.

func Due

func Due(lastStarted string, lastStatus string, intervalHours int, now time.Time) bool

Due reports whether a run should start now: none yet, the last one older than the interval, or the last one failed more than retryAfter ago.

func Fetch

func Fetch(ctx context.Context, cl *Client, object string, key []byte, dest string) (string, error)

Fetch downloads object, opens it with key and unpacks it under dest; it returns the snapshot folder.

func KeyHint

func KeyHint(hexKey string) string

KeyHint is a short, safe label for a key: its first and last four characters.

func NewRecoveryKey

func NewRecoveryKey() (string, error)

NewRecoveryKey returns a fresh key as 64 hex characters.

func ObjectPrefix

func ObjectPrefix(c store.CloudConfig) string

ObjectPrefix is where this install's archives live in the bucket.

func Open

func Open(r io.Reader, key []byte) (io.Reader, error)

Open returns a reader of the plaintext; it fails with ErrOpen on a wrong key, an edited chunk or a missing end. Every byte it returns has been authenticated.

func Pack

func Pack(w io.Writer, dir string) error

Pack writes dir (a backup snapshot) as tar.gz into w: regular files and folders only, paths relative.

func ParseRecoveryKey

func ParseRecoveryKey(s string) ([]byte, error)

ParseRecoveryKey accepts the key with or without spaces/dashes between groups.

func Prune

func Prune(ctx context.Context, cl *Client, prefix string, keep int) (int, error)

Prune deletes the oldest archives under prefix beyond keep (keys carry a UTC timestamp, so they sort).

func Seal

func Seal(w io.Writer, key []byte) (io.WriteCloser, error)

Seal returns a writer that encrypts into w; Close writes the final chunk and must be called.

func Unpack

func Unpack(r io.Reader, dest string) (string, error)

Unpack extracts a tar.gz made by Pack into dest and returns the snapshot folder it contained. Anything that could write outside dest (absolute or ../ paths, links, devices) is refused.

Types

type Client

type Client struct {
	Endpoint  string // https://<account>.r2.cloudflarestorage.com, https://s3.us-west-004.backblazeb2.com, …
	Region    string // "auto" for R2; the bucket's region elsewhere
	Bucket    string
	AccessKey string
	SecretKey string
	HTTP      *http.Client
	// contains filtered or unexported fields
}

Client talks to one bucket.

func (*Client) Delete

func (c *Client) Delete(ctx context.Context, key string) error

Delete removes key.

func (*Client) Get

func (c *Client) Get(ctx context.Context, key string, w io.Writer) error

Get streams key into w.

func (*Client) List

func (c *Client) List(ctx context.Context, prefix string) ([]Object, error)

List returns every key under prefix (ListObjectsV2, all pages), oldest first by key.

func (*Client) Put

func (c *Client) Put(ctx context.Context, key, path string) error

Put uploads the file at path as key.

type ErrStatus

type ErrStatus struct {
	Code int
	Body string
}

ErrStatus is a non-2xx answer; Body holds the start of the error document.

func (ErrStatus) Error

func (e ErrStatus) Error() string

type Job

type Job struct {
	Store      *store.Store
	Disk       repos.Disk
	GitBinary  string
	ConfigPath string     // copied into each snapshot
	LFSRoot    string     // data/lfs: LFS objects go into each snapshot too (D82)
	WorkDir    string     // temp space on the data disk
	Secret     secret.Key // auth.secret_key: unseals the bucket secret and the recovery key
	HTTP       *http.Client
	// contains filtered or unexported fields
}

Job runs cloud backups for one install. One run at a time per Job.

func (*Job) Client

func (j *Job) Client(c store.CloudConfig) (*Client, error)

Client builds the S3 client from the stored configuration.

func (*Job) Run

func (j *Job) Run(ctx context.Context, trigger string) (out Outcome, err error)

Run takes a snapshot, uploads it encrypted, downloads it back and proves it opens and matches, then prunes old archives beyond Keep. The run is recorded in cloud_backup_runs either way.

func (*Job) Running

func (j *Job) Running() bool

Running reports whether a run is in progress.

func (*Job) Schedule

func (j *Job) Schedule(ctx context.Context, tick time.Duration, log *slog.Logger)

Schedule checks every tick whether a run is due and runs it in the background loop of `serve`.

type Object

type Object struct {
	Key      string
	Size     int64
	Modified time.Time
}

Object is one listed key.

type Outcome

type Outcome struct {
	Object string
	Bytes  int64
	Repos  int
	Pruned int
}

Outcome is what a successful run produced.

Jump to

Keyboard shortcuts

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