Help us shape the future of Go! Take the 2026 Go Developer Survey

backup

package
v0.18.5 Latest Latest
Warning

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

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

Documentation

Overview

Package backup makes and lists data-directory backups: a consistent copy of the database (VACUUM INTO) and a tar.gz of data trees and local recovery configuration, both under <data>/backups/<UTC timestamp>. `gorun backup` and the admin's System → Backups share it.

Index

Constants

View Source
const ManifestVersion = 1
View Source
const (

	// MaxEncryptedFile is DARE's cryptographic plaintext bound, less our authenticated marker.
	// Uploads use bounded buffers; provider object-size limits still apply.
	MaxEncryptedFile int64 = (1 << 48) - int64(len(contentMarker))
)

Variables

View Source
var Dirs = []string{"media", "overrides", "extensions", "form-uploads"}

Dirs are the data-directory trees archived next to the database copy.

View Source
var ErrPartialRestore = errors.New("backup: an interrupted restore left a partial directory")

ErrPartialRestore reports that an interrupted restore left its staging directory (see PartialPath); remove it before restoring again.

Functions

func CheckManifestHMAC added in v0.18.0

func CheckManifestHMAC(m *Manifest, key []byte) (ok bool, err error)

CheckManifestHMAC reports whether m was signed with key. Unsigned (legacy) manifests return false, nil — callers decide whether to warn.

func Decrypt

func Decrypt(src io.Reader, key []byte, name string) ([]byte, error)

Decrypt is the bounded in-memory convenience API. Large recovery/readback uses DecryptTo.

func DecryptTo added in v0.18.3

func DecryptTo(dst io.Writer, src io.Reader, key []byte, name string) (int64, error)

DecryptTo reads v2 streams and legacy v1 files. Only authenticated chunks are written, but callers must consume EOF and reject all output if any error occurs. v1 decoding retains its original bounded whole-file authentication.

func Dir

func Dir(dataDir string) string

Dir is the backups directory of dataDir.

func Encrypt

func Encrypt(src io.Reader, key []byte, name string) ([]byte, error)

Encrypt is the bounded in-memory convenience API. Uploads must use EncryptTo.

func EncryptTo added in v0.18.3

func EncryptTo(dst io.Writer, src io.Reader, key []byte, name string) (int64, error)

EncryptTo writes a v2 DARE20 stream with a fresh file key bound to name. Memory usage is independent of the input size. Only ciphertext is written.

func EncryptedSize added in v0.18.3

func EncryptedSize(size int64) (int64, error)

EncryptedSize returns the v2 ciphertext size, including the authenticated envelope.

func File

func File(dataDir, name string) (string, error)

File returns the path of the backup file name (<stamp>.db or <stamp>.tar.gz); any other name, or a missing file, is fs.ErrNotExist.

func ManifestFile added in v0.2.0

func ManifestFile(dataDir, stamp string) (string, error)

ManifestFile returns the path of <stamp>.manifest.json under the backups directory when it exists as a regular file.

func PartialPath added in v0.2.0

func PartialPath(destination string) string

PartialPath is the staging directory Restore fills before it renames it to destination: a hidden sibling, so an interrupted restore never looks complete.

func Prune added in v0.2.0

func Prune(dataDir string, keep int) (removed int, err error)

Prune deletes the oldest complete local backup pairs under dataDir so that at most keep complete pairs remain (newest first). A complete pair has both .db and .tar.gz. Incomplete stamps are left alone. keep < 1 is a no-op. Each pruned stamp removes .db, .tar.gz, .manifest.json and .remote.json when present. Create is unchanged: callers opt into Prune after Create.

func PruneVerified added in v0.4.0

func PruneVerified(dataDir string, keep int) (removed int, err error)

PruneVerified counts only pairs that pass a fresh integrity/archive inspection. Incomplete, legacy, and corrupt copies never displace a known-good copy and are left for the operator to inspect rather than silently deleted.

func PruneVerifiedKeeping added in v0.15.0

func PruneVerifiedKeeping(dataDir string, keep int, stamp string) (int, error)

PruneVerifiedKeeping reserves one retention slot for the just-created pair, even when the host clock moved backwards since an earlier run.

func PruneVerifiedKeepingWith added in v0.18.0

func PruneVerifiedKeepingWith(dataDir string, keep int, stamp string, key []byte) (int, error)

PruneVerifiedKeepingWith is PruneVerifiedKeeping with a site secret for HMAC.

func PruneVerifiedWith added in v0.18.0

func PruneVerifiedWith(dataDir string, keep int, key []byte) (removed int, err error)

PruneVerifiedWith is PruneVerified, verifying keyed manifest HMACs with key.

func RemovePartial added in v0.2.0

func RemovePartial(destination string) error

RemovePartial deletes the leftover staging directory for destination (see PartialPath). It only removes that exact sibling name under the destination's parent via os.OpenRoot — never a path outside restores/.

func RestoreDestination added in v0.2.0

func RestoreDestination(dataDir, stamp string) (string, error)

RestoreDestination is the confined path for an admin restore of stamp: <dataDir>/restores/<stamp>. The directory must not exist before Restore.

func Restored added in v0.2.0

func Restored(dataDir, stamp string) (string, bool)

Restored reports whether a previous restore for stamp is present under <dataDir>/restores/<stamp> (directory with gorun.db).

func StoreUploadReceipt

func StoreUploadReceipt(res Result, receipt UploadReceipt) error

func StoreUploadReceiptWithKey added in v0.18.3

func StoreUploadReceiptWithKey(res Result, receipt UploadReceipt, key []byte) error

StoreUploadReceiptWithKey authenticates the manifest identity, destination, remote object keys and readback result with the existing site secret.

func ValidStamp added in v0.2.0

func ValidStamp(s string) bool

ValidStamp reports whether s is a backup timestamp name.

Types

type Entry

type Entry struct {
	Stamp       string
	Time        time.Time
	DBSize      int64 // -1 when the .db is missing
	FilesSize   int64 // -1 when the .tar.gz is missing
	LocalState  string
	HasManifest bool
	Remote      UploadReceipt
}

Entry is one backup in the backups directory (either file may be missing).

func List

func List(dataDir string) ([]Entry, error)

List returns the backups of dataDir, newest first.

func ListWithKey added in v0.18.3

func ListWithKey(dataDir string, key []byte) ([]Entry, error)

ListWithKey verifies historical readback receipts with the site secret. Presence-only local metadata remains distinct from an integrity inspection.

type ExternalRequirement

type ExternalRequirement struct {
	Kind      string `json:"kind"`
	Reference string `json:"reference"`
	State     string `json:"state"`
}

type FileDigest

type FileDigest struct {
	Name   string `json:"name"`
	Size   int64  `json:"size"`
	SHA256 string `json:"sha256"`
}

type Inspection

type Inspection struct {
	Stamp                string                `json:"stamp"`
	CheckedAt            string                `json:"checked_at"`
	LocalComplete        bool                  `json:"local_complete"`
	IntegrityOK          bool                  `json:"integrity_ok"`
	ForeignKeyViolations int                   `json:"foreign_key_violations"`
	ArchiveFiles         int                   `json:"archive_files"`
	RecoveryKeyArchived  bool                  `json:"recovery_key_archived"`
	Consistency          string                `json:"consistency"`
	Readiness            string                `json:"readiness"`
	Errors               []string              `json:"errors"`
	Warnings             []string              `json:"warnings"`
	CutoverChecklist     []string              `json:"cutover_checklist"`
	ExternalRequirements []ExternalRequirement `json:"external_requirements"`
	Remote               UploadReceipt         `json:"remote"`
}

func Inspect

func Inspect(manifestPath string) (*Inspection, error)

Inspect never creates a DB, secret or receipt, and makes no network requests. Readiness tiers:

  • blocked: local pair cannot be restored (errors)
  • review_required: local pair usable, but site-specific warnings need attention before cutover
  • local_ok: local checksums/integrity passed; cutover_checklist still lists secrets/themes/writes/remote

func InspectWith added in v0.18.0

func InspectWith(manifestPath string, key []byte) (*Inspection, error)

InspectWith is Inspect, verifying a keyed manifest HMAC when key is the 32-byte site secret. When a key is supplied, an HMAC is required (omitting or stripping it is treated as tampering). Without a key, legacy unsigned manifests are still accepted on digest checks alone.

func Restore

func Restore(manifestPath, destination string) (report *Inspection, resultErr error)

Restore writes only into a new directory. It never merges into an existing installation; the caller must review external requirements before booting it. Everything is written into PartialPath(destination) first and renamed to destination only after the database and archive checksums verify, so destination exists only for a complete restore.

func RestoreWith added in v0.18.0

func RestoreWith(manifestPath, destination string, key []byte) (report *Inspection, resultErr error)

RestoreWith is Restore, verifying a keyed manifest HMAC when key is set.

type Manifest

type Manifest struct {
	FormatVersion      int        `json:"format_version"`
	Stamp              string     `json:"stamp"`
	CreatedAt          string     `json:"created_at"`
	Database           FileDigest `json:"database"`
	Archive            FileDigest `json:"archive"`
	Consistency        string     `json:"consistency"`
	RecoveryFiles      []string   `json:"recovery_files"`
	Limitations        []string   `json:"limitations"`
	EncryptedFileLimit int64      `json:"encrypted_file_limit"`
	// HMAC is hex(HMAC-SHA256(site secret, domain || canonical digests)).
	// Empty on legacy manifests written before keyed integrity.
	HMAC string `json:"hmac,omitempty"`
}

func ReadManifest

func ReadManifest(path string) (*Manifest, error)

type Options

type Options struct {
	// IncludeSecrets archives secret.key and gorun.toml in plain text
	// (`gorun backup --include-secrets`). Keep such archives offline and
	// encrypted; the admin never sets it.
	IncludeSecrets bool
	// SecretKey (32 bytes) HMACs the manifest so a writable backups
	// directory alone cannot forge digests. Prefer the site secret.
	SecretKey []byte
}

Options adjust Create.

type Result

type Result struct {
	Stamp, DB, Files string
	Manifest         string
	Count            int // archived files
}

Result names the files one backup wrote.

func Create

func Create(dataDir, dbPath string, now time.Time) (Result, error)

Create backs up the database at dbPath and the data trees of dataDir, named after now, without the recovery secrets (see Options).

func CreateWith

func CreateWith(dataDir, dbPath string, now time.Time, opts Options) (Result, error)

CreateWith is Create with options.

type UploadFile

type UploadFile struct {
	Name      string `json:"name"`
	State     string `json:"state"`
	ObjectKey string `json:"object_key,omitempty"`
	Code      string `json:"code,omitempty"`
	CheckedAt string `json:"checked_at"`
}

type UploadReceipt

type UploadReceipt struct {
	State            string       `json:"state"`
	Files            []UploadFile `json:"files"`
	ReadBackVerified bool         `json:"read_back_verified"`
	Stamp            string       `json:"stamp,omitempty"`
	DestinationID    string       `json:"destination_id,omitempty"`
	ManifestHMAC     string       `json:"manifest_hmac,omitempty"`
	HMAC             string       `json:"hmac,omitempty"`
	DatabaseSHA256   string       `json:"database_sha256,omitempty"`
	ArchiveSHA256    string       `json:"archive_sha256,omitempty"`
}

UploadReceipt records acknowledgments; keyed receipts may additionally attest to authenticated readback at upload time, not continued remote availability.

Jump to

Keyboard shortcuts

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