backupfile

package
v0.41.0 Latest Latest
Warning

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

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

Documentation

Overview

Package backupfile reads and writes the folder a backup is kept in:

manifest.json      what the backup holds, written last
<kind>.jsonl       the records of one kind, a JSON line each
content/aa/bb/<sha>  file content, by its checksum

A record file begins with a header line. With a key the records follow in encrypted blocks of about a thousand lines, so a backup of any size is read and written a block at a time. Content is stored as it is, once however many files share it, so repeating a backup into the same folder copies only what is new.

Index

Constants

View Source
const (
	// Version is the folder format.
	Version = 1
)

Variables

View Source
var ErrWrongKey = errors.New("cannot decrypt the backup: wrong key, or the file is damaged")

ErrWrongKey is returned when a block does not decrypt.

Functions

func ClearUnfinished

func ClearUnfinished(dir string) error

ClearUnfinished removes the mark once the backup is complete.

func ContentPath

func ContentPath(dir, sha string) string

ContentPath is where the content with a checksum is kept.

func DownloadContent

func DownloadContent(dir, sha string, fetch Fetch) (int64, error)

DownloadContent copies the content with a checksum into the backup, carrying on from a partial copy if there is one, and checking the whole against the checksum before keeping it. A failure leaves the partial copy for the next attempt; content that fails its checksum is discarded. It returns the bytes copied in this call.

func HasContent

func HasContent(dir, sha string) bool

HasContent reports whether the backup holds the content with a checksum.

func HasContentOfSize

func HasContentOfSize(dir, sha string, size int64) bool

HasContentOfSize is HasContent that also checks the size, so content a crash left empty or cut short is copied again rather than trusted. Content is not synced file by file, which would make a backup of many small files crawl.

func IsBackupDir

func IsBackupDir(dir string) bool

IsBackupDir reports whether dir holds a backup, finished or not.

func MarkUnfinished

func MarkUnfinished(dir string) error

MarkUnfinished records that a backup into dir has begun.

func OpenContent

func OpenContent(dir, sha string) (*os.File, error)

OpenContent opens the content with a checksum.

func PartialPath

func PartialPath(dir, sha string) string

PartialPath is where content with a checksum is kept while it is being copied. A copy that fails leaves it, so the next attempt, in this run or the next, carries on from there.

func Prune

func Prune(dir string, keep func(sha string) bool) (removed int, freed int64, err error)

Prune removes content that no file refers to: keep reports whether a checksum is still wanted. It also clears partial copies. It returns how many files it removed and the bytes they held.

func RecordPath

func RecordPath(dir, kind string) string

RecordPath is the file the records of a kind are kept in.

func WriteContent

func WriteContent(dir, sha string, r io.Reader) (int64, error)

WriteContent stores content read from r under its checksum, refusing content that does not match it. It returns the bytes written.

func WriteManifest

func WriteManifest(dir string, m *Manifest) error

WriteManifest writes the manifest into dir.

Types

type Fetch

type Fetch func(offset int64) (rc io.ReadCloser, resumed bool, err error)

Fetch opens content from byte offset. It returns the stream and whether the stream starts at offset: false means it starts at the beginning, because the server sent everything again.

type Manifest

type Manifest struct {
	Version   int            `json:"version" msgpack:"version"`
	Created   time.Time      `json:"created" msgpack:"created"`
	Server    string         `json:"server" msgpack:"server"` // the knot version that made it
	Encrypted bool           `json:"encrypted" msgpack:"encrypted"`
	Counts    map[string]int `json:"counts" msgpack:"counts"`
	Content   bool           `json:"content" msgpack:"content"` // file content was copied
}

Manifest says what a backup holds. It is written when the backup is complete, so a folder without one is unfinished.

func ReadManifest

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

ReadManifest reads the manifest of the backup in dir.

type Reader

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

Reader reads the records of one kind.

func Open

func Open(dir, kind, key string) (*Reader, error)

Open opens the record file of a kind in dir; key is needed if it is encrypted. A kind the backup has no file for returns os.ErrNotExist.

func (*Reader) Close

func (r *Reader) Close()

func (*Reader) Each

func (r *Reader) Each(fn func(line []byte) error) error

Each calls fn with every record, in order, stopping at the first error.

type Writer

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

Writer writes the records of one kind.

func Create

func Create(dir, kind, key string) (*Writer, error)

Create starts the record file of a kind in dir. With a key the records are encrypted.

func (*Writer) Add

func (w *Writer) Add(line []byte) error

Add writes a record, a JSON value with no newline in it.

func (*Writer) Close

func (w *Writer) Close() error

Close finishes the file, making it durable.

func (*Writer) Count

func (w *Writer) Count() int

Count is how many records have been added.

Jump to

Keyboard shortcuts

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