Documentation
¶
Overview ¶
Package local is a pure-Go backend over a directory: the zero-account, zero-dependency vault. It stores exactly the bytes and layout a remote does (header, transitions, namespace objects), so a local vault copied to a remote is byte-identical and the same trust machinery runs unchanged.
Where rclone's header swap is a windowed best effort, this backend's is a true compare-and-swap: an advisory OS file lock (auto-released by the kernel if the process dies, so a crash can never wedge later writers) covers the read-compare-write, and same-machine writers are the only writers a local vault has. The lock is cooperative and same-machine only: a vault directory under Dropbox/syncthing/NFS gets no cross-machine exclusion: concurrent multi-machine use is what remotes are for.
Index ¶
- type Storage
- func (s *Storage) BackupHeader(ctx context.Context) error
- func (s *Storage) Delete(ctx context.Context, key string) error
- func (s *Storage) Get(ctx context.Context, key string) ([]byte, error)
- func (s *Storage) GetHeader(ctx context.Context) ([]byte, error)
- func (s *Storage) List(ctx context.Context, prefix string) ([]string, error)
- func (s *Storage) Preflight(ctx context.Context) error
- func (s *Storage) Probe(ctx context.Context) error
- func (s *Storage) Put(ctx context.Context, key string, data []byte) error
- func (s *Storage) PutHeader(ctx context.Context, raw []byte) error
- func (s *Storage) RestoreHeaderBackup(ctx context.Context) error
- func (s *Storage) SwapHeader(ctx context.Context, base, updated []byte) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Storage ¶
type Storage struct {
Path string
}
Storage is a vault in a local directory. The zero value is not usable; Path must be set (made absolute by the caller).
func (*Storage) BackupHeader ¶
BackupHeader copies the current header to its ".prev" sibling so a bad overwrite is recoverable. Like every backend it keeps its own backup. The safe-write protocol calls it ONLY when a header exists, so a missing header here is a race, not the virgin case, and is returned as an error: the write fails closed rather than overwrite without a recoverable copy.
func (*Storage) List ¶
List returns base-relative keys of every object under prefix, recursively, sorted. Header artifacts and abandoned temp files are not objects and are never listed.
func (*Storage) Preflight ¶
Preflight creates the vault directory if needed, the local counterpart of "is the remote reachable".
func (*Storage) Probe ¶
Probe round-trips a marker file so an unwritable or full disk fails here, with context, not at the first real `set`.
func (*Storage) Put ¶
Put stores data at key. The write is a temp file in the same directory renamed into place, so a reader never sees a partial object, and both file and directory are synced so a committed write survives power loss.
func (*Storage) PutHeader ¶
PutHeader writes the header object unconditionally (recovery paths only; mutations go through SwapHeader). Atomic like every other write.
func (*Storage) RestoreHeaderBackup ¶
RestoreHeaderBackup copies the ".prev" backup back over the header, ErrNotFound when there is none.
func (*Storage) SwapHeader ¶
SwapHeader is a true compare-and-swap: an exclusive OS file lock covers the read, the compare, and the write, so concurrent same-machine writers serialize completely: exactly one of any set of racing swaps against the same base succeeds.