store

package
v1.17.0 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Index

Constants

View Source
const KeySlotPrefix = "keys/"

KeySlotPrefix is the object key prefix for encryption key slot objects. These objects are stored unencrypted (they contain already-wrapped keys) so they can be read without the encryption key — avoiding a chicken-and-egg problem during key loading.

Variables

View Source
var ErrInvalidFrame = errors.New("store: invalid compression frame")

ErrInvalidFrame reports a framed object whose header or payload is not self-consistent. It is never downgraded to "return the bytes as they are": that is the sniffing behaviour this frame exists to remove.

View Source
var ErrNotFound = errors.New("object not found")

ErrNotFound is the sentinel error returned by Get when the requested key does not exist. Each backend translates its own not-found signal — a missing file, an S3 NoSuchKey/404, an SFTP no-such-file, a B2 404 — into this sentinel, wrapped with the key, so callers can use errors.Is(err, ErrNotFound) instead of treating every Get failure (network error, permission error, corrupt response, ...) as "the object isn't there".

View Source
var ErrPlaintextObject = errors.New("store: unencrypted object in an encrypted repository")

ErrPlaintextObject is returned when an object is not a ciphertext in an encrypted repository, outside what is plaintext by design.

View Source
var ErrQuotaExceeded = errors.New("storage quota exceeded during backup")

Functions

func GetConcurrencyHint added in v1.4.3

func GetConcurrencyHint(s ObjectStore, defaultConcurrency int) int

GetConcurrencyHint walks the store wrapper chain and returns the first ConcurrencyHint it finds, defaulting to defaultConcurrency if none exists.

Types

type B2Option added in v1.8.0

type B2Option func(*b2Options)

B2Option configures a B2 store.

func WithClient added in v1.8.0

func WithClient(client *b2.Client) B2Option

WithClient provides a pre-configured B2 client, skipping internal client creation. When set, WithCredentials is ignored.

func WithCredentials added in v1.8.0

func WithCredentials(keyID, appKey string) B2Option

WithCredentials sets the Backblaze application key ID and key used to authenticate. Ignored when WithClient is provided.

func WithPrefix added in v1.8.0

func WithPrefix(prefix string) B2Option

WithPrefix sets a key prefix prepended to every object key. Use this to isolate multiple repositories within a single bucket (e.g. "prod/" and "staging/").

type B2Store

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

B2Store implements ObjectStore for Backblaze B2.

func NewB2Store

func NewB2Store(bucketName string, opts ...B2Option) (*B2Store, error)

NewB2Store creates a B2Store for the given bucket. Either WithCredentials or WithClient must be provided.

func (*B2Store) Delete

func (s *B2Store) Delete(ctx context.Context, key string) error

func (*B2Store) DeletePrefix

func (s *B2Store) DeletePrefix(ctx context.Context, prefix string) error

DeletePrefix deletes all objects under the given prefix.

func (*B2Store) Exists

func (s *B2Store) Exists(ctx context.Context, key string) (bool, error)

func (*B2Store) Flush added in v1.4.3

func (s *B2Store) Flush(ctx context.Context) error

func (*B2Store) Get

func (s *B2Store) Get(ctx context.Context, key string) ([]byte, error)

func (*B2Store) GetRange added in v1.16.0

func (s *B2Store) GetRange(ctx context.Context, key string, offset, length int64) ([]byte, error)

GetRange implements RangeGetter using a B2 ranged download, so a caller reading a packfile footer transfers a few hundred bytes rather than the whole object.

func (*B2Store) List

func (s *B2Store) List(ctx context.Context, prefix string) ([]string, error)

func (*B2Store) NewWriter

func (s *B2Store) NewWriter(ctx context.Context, key string) io.WriteCloser

NewWriter returns a streaming writer to the given key in B2. The caller must Close the writer to finalize the upload.

func (*B2Store) Put

func (s *B2Store) Put(ctx context.Context, key string, data []byte) error

func (*B2Store) SignedURL

func (s *B2Store) SignedURL(ctx context.Context, key string, validFor time.Duration) (string, error)

SignedURL returns a time-limited download URL for the given key.

func (*B2Store) Size

func (s *B2Store) Size(ctx context.Context, key string) (int64, error)

func (*B2Store) TotalSize

func (s *B2Store) TotalSize(ctx context.Context) (int64, error)

type CompressedOption added in v1.16.0

type CompressedOption func(*CompressedStore)

CompressedOption configures a CompressedStore.

func WithFrameGate added in v1.16.0

func WithFrameGate(gate func() bool) CompressedOption

WithFrameGate frames writes whenever gate reports true, evaluated per write.

This is how framing tracks the repository format without a second source of truth: the caller owns one format value and points the gate at it, so raising the format turns framing on for every subsequent write at once. Enabling framing partway through a mutation is still the caller's responsibility to avoid — an object written unframed by this build is unframed permanently, since content-addressed objects are never rewritten once stored.

func WithFramedWrites added in v1.16.0

func WithFramedWrites(enabled bool) CompressedOption

WithFramedWrites is the static form of WithFrameGate, for callers whose framing decision does not change over the store's life (chiefly tests).

type CompressedStore added in v1.1.0

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

CompressedStore wraps an ObjectStore and transparently zstd-compresses on write and decompresses on read.

Whether a write is framed is not a mode this store is told to enter; it is derived, per write, from a gate the caller supplies (WithFrameGate). Framing belongs on only once the repository records a format whose readers understand the frame, and that format is raised during a mutation — so the gate lets the owner of the format flip one value and have every write follow, with no second copy of the decision to keep in sync. See core.FramedCompressionFormat.

Reads accept both framed and unframed objects regardless of the gate: unframed objects exist in every repository indefinitely, because upgrades are opportunistic and permanently partial (docs/compatibility.md).

func NewCompressedStore added in v1.1.0

func NewCompressedStore(inner ObjectStore, opts ...CompressedOption) *CompressedStore

func (*CompressedStore) Delete added in v1.1.0

func (s *CompressedStore) Delete(ctx context.Context, key string) error

func (*CompressedStore) Exists added in v1.1.0

func (s *CompressedStore) Exists(ctx context.Context, key string) (bool, error)

func (*CompressedStore) Flush added in v1.4.3

func (s *CompressedStore) Flush(ctx context.Context) error

func (*CompressedStore) Get added in v1.1.0

func (s *CompressedStore) Get(ctx context.Context, key string) ([]byte, error)

func (*CompressedStore) List added in v1.1.0

func (s *CompressedStore) List(ctx context.Context, prefix string) ([]string, error)

func (*CompressedStore) Put added in v1.1.0

func (s *CompressedStore) Put(ctx context.Context, key string, data []byte) error

func (*CompressedStore) Size added in v1.1.0

func (s *CompressedStore) Size(ctx context.Context, key string) (int64, error)

func (*CompressedStore) TotalSize added in v1.1.0

func (s *CompressedStore) TotalSize(ctx context.Context) (int64, error)

func (*CompressedStore) Unwrap added in v1.4.3

func (s *CompressedStore) Unwrap() ObjectStore

type ConcurrencyHinter added in v1.4.3

type ConcurrencyHinter interface {
	ConcurrencyHint() int
}

ConcurrencyHinter is an optional interface that ObjectStore implementations can implement to indicate the optimal number of concurrent operations. Remote stores (S3) benefit from high concurrency; local stores do not.

type DebugStore added in v1.2.0

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

DebugStore wraps an ObjectStore and logs every operation with timing information. Output goes to the provided writer, which should be a ui.SafeLogWriter so lines coexist with progress bars.

func NewDebugStore added in v1.2.0

func NewDebugStore(inner ObjectStore, w io.Writer) *DebugStore

func (*DebugStore) Delete added in v1.2.0

func (s *DebugStore) Delete(ctx context.Context, key string) error

func (*DebugStore) Exists added in v1.2.0

func (s *DebugStore) Exists(ctx context.Context, key string) (bool, error)

func (*DebugStore) Flush added in v1.4.3

func (s *DebugStore) Flush(ctx context.Context) error

func (*DebugStore) Get added in v1.2.0

func (s *DebugStore) Get(ctx context.Context, key string) ([]byte, error)

func (*DebugStore) GetRange added in v1.16.0

func (s *DebugStore) GetRange(ctx context.Context, key string, offset, length int64) ([]byte, error)

GetRange implements RangeGetter. DebugStore only logs, so it is safe to pass a ranged read straight through — and it has to, or wrapping a backend in --debug would silently turn every footer read into a full object transfer.

Declaring this method makes DebugStore satisfy RangeGetter unconditionally, including over an inner store that cannot range, so the fallback is explicit rather than inherited.

func (*DebugStore) List added in v1.2.0

func (s *DebugStore) List(ctx context.Context, prefix string) ([]string, error)

func (*DebugStore) Put added in v1.2.0

func (s *DebugStore) Put(ctx context.Context, key string, data []byte) error

func (*DebugStore) Size added in v1.2.0

func (s *DebugStore) Size(ctx context.Context, key string) (int64, error)

func (*DebugStore) TotalSize added in v1.2.0

func (s *DebugStore) TotalSize(ctx context.Context) (int64, error)

func (*DebugStore) Unwrap added in v1.4.3

func (s *DebugStore) Unwrap() ObjectStore

type EncryptedStore

type EncryptedStore struct {
	ObjectStore
	// contains filtered or unexported fields
}

EncryptedStore wraps an ObjectStore and transparently encrypts data on Put and decrypts on Get using AES-256-GCM.

Objects under "keys/" are exempt from encryption entirely — they hold the wrapped master key needed to derive the encryption key, so Put never encrypts them and Get never expects ciphertext there. "config", the repository marker read before any key is resolved, is a narrower exemption: Get returns it as-is when it is not a ciphertext (which is how it is always actually written, directly through the raw store), but Put still encrypts it like any other key, and Get still decrypts it if it ever does arrive as one.

A non-ciphertext object anywhere else is refused rather than returned. The passthrough that used to apply unconditionally here — legacy plaintext data returned as-is, documented as a gradual-migration affordance — is what let anyone with write access to the backing store have a client *holding the correct key* read attacker-written plaintext as repository content, with no key and no tampering with config or key slots required.

func NewEncryptedStore

func NewEncryptedStore(inner ObjectStore, key []byte) *EncryptedStore

NewEncryptedStore creates an EncryptedStore that encrypts all Put operations and decrypts Get operations. The key must be 32 bytes (AES-256).

func (*EncryptedStore) Get

func (s *EncryptedStore) Get(ctx context.Context, key string) ([]byte, error)

func (*EncryptedStore) Put

func (s *EncryptedStore) Put(ctx context.Context, key string, data []byte) error

func (*EncryptedStore) Unwrap added in v1.4.3

func (s *EncryptedStore) Unwrap() ObjectStore

type KeyCacheStore added in v1.1.0

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

KeyCacheStore wraps an ObjectStore and caches key existence from List calls, so that Exists returns immediately for known keys. Thread-safe.

func NewKeyCacheStore added in v1.1.0

func NewKeyCacheStore(inner ObjectStore) *KeyCacheStore

func (*KeyCacheStore) Delete added in v1.1.0

func (s *KeyCacheStore) Delete(ctx context.Context, key string) error

func (*KeyCacheStore) Exists added in v1.1.0

func (s *KeyCacheStore) Exists(ctx context.Context, key string) (bool, error)

func (*KeyCacheStore) Flush added in v1.4.3

func (s *KeyCacheStore) Flush(ctx context.Context) error

func (*KeyCacheStore) Get added in v1.1.0

func (s *KeyCacheStore) Get(ctx context.Context, key string) ([]byte, error)

func (*KeyCacheStore) List added in v1.1.0

func (s *KeyCacheStore) List(ctx context.Context, prefix string) ([]string, error)

func (*KeyCacheStore) PreloadKeys added in v1.1.0

func (s *KeyCacheStore) PreloadKeys(ctx context.Context, prefixes ...string) error

func (*KeyCacheStore) Put added in v1.1.0

func (s *KeyCacheStore) Put(ctx context.Context, key string, data []byte) error

func (*KeyCacheStore) Size added in v1.1.0

func (s *KeyCacheStore) Size(ctx context.Context, key string) (int64, error)

func (*KeyCacheStore) TotalSize added in v1.1.0

func (s *KeyCacheStore) TotalSize(ctx context.Context) (int64, error)

func (*KeyCacheStore) Unwrap added in v1.4.3

func (s *KeyCacheStore) Unwrap() ObjectStore

type LocalStore

type LocalStore struct {
	BasePath string
	// contains filtered or unexported fields
}

LocalStore implements ObjectStore for the local filesystem.

func NewLocalStore

func NewLocalStore(basePath string) (*LocalStore, error)

func (*LocalStore) Delete

func (s *LocalStore) Delete(_ context.Context, key string) error

func (*LocalStore) Exists

func (s *LocalStore) Exists(_ context.Context, key string) (bool, error)

func (*LocalStore) Flush added in v1.4.3

func (s *LocalStore) Flush(ctx context.Context) error

func (*LocalStore) Get

func (s *LocalStore) Get(_ context.Context, key string) ([]byte, error)

func (*LocalStore) GetRange added in v1.15.0

func (s *LocalStore) GetRange(_ context.Context, key string, offset, length int64) ([]byte, error)

GetRange implements RangeGetter, letting callers read a packfile footer without loading the whole object.

func (*LocalStore) List

func (s *LocalStore) List(_ context.Context, prefix string) ([]string, error)

List returns all keys matching the given prefix. When a prefix is provided the walk is scoped to just that subdirectory for efficiency.

func (*LocalStore) Put

func (s *LocalStore) Put(_ context.Context, key string, data []byte) error

func (*LocalStore) Size

func (s *LocalStore) Size(_ context.Context, key string) (int64, error)

func (*LocalStore) TotalSize

func (s *LocalStore) TotalSize(_ context.Context) (int64, error)

type MeteredStore

type MeteredStore struct {
	ObjectStore
	// contains filtered or unexported fields
}

MeteredStore wraps an ObjectStore and tracks bytes written/deleted.

func NewMeteredStore

func NewMeteredStore(s ObjectStore) *MeteredStore

func (*MeteredStore) BytesWritten

func (m *MeteredStore) BytesWritten() int64

func (*MeteredStore) Delete

func (m *MeteredStore) Delete(ctx context.Context, key string) error

func (*MeteredStore) DeleteReturnSize

func (m *MeteredStore) DeleteReturnSize(ctx context.Context, key string) (int64, error)

func (*MeteredStore) Put

func (m *MeteredStore) Put(ctx context.Context, key string, data []byte) error

func (*MeteredStore) Reset

func (m *MeteredStore) Reset()

func (*MeteredStore) Unwrap added in v1.4.3

func (m *MeteredStore) Unwrap() ObjectStore

type ObjectStore

type ObjectStore interface {
	// Put must not retain data beyond the call: read or copy it synchronously
	// before returning. Callers (chunking in particular) pool and reuse their
	// write buffers the instant Put returns, so an implementation that keeps
	// the slice — instead of the bytes — would see it mutated out from under
	// a previously "stored" value.
	Put(ctx context.Context, key string, data []byte) error
	Get(ctx context.Context, key string) ([]byte, error)
	Exists(ctx context.Context, key string) (bool, error)
	Delete(ctx context.Context, key string) error
	List(ctx context.Context, prefix string) ([]string, error)
	Size(ctx context.Context, key string) (int64, error)
	TotalSize(ctx context.Context) (int64, error)
	Flush(ctx context.Context) error
}

ObjectStore is the interface for content-addressable object storage. Keys are slash-separated paths like "chunk/<hash>" or "snapshot/<hash>".

type PackEntry added in v1.4.3

type PackEntry struct {
	PackRef string `json:"p"`
	Offset  int64  `json:"o"`
	Length  int64  `json:"l"`
}

PackEntry represents the location of a small object within a packfile.

type PackOption added in v1.16.0

type PackOption func(*PackStore)

PackOption configures a PackStore.

func WithPackIndexKey added in v1.16.0

func WithPackIndexKey(key []byte) PackOption

WithPackIndexKey seals the pack catalog and packfile footers with key.

PackStore sits below EncryptedStore in the store chain, so the objects it writes on its own behalf — index/packs and each pack's footer — never pass through the encryption layer. Without a key they are stored in plaintext, exposing every packed object's key, its exact ciphertext length, and which objects share a pack. Pack *contents* are unaffected either way: they are already ciphertext by the time PackStore sees them.

Pass a key derived with crypto.HKDFInfoPackIndexV1, not the master key. Repositories without encryption pass none and keep plaintext indexes.

type PackStore added in v1.4.3

type PackStore struct {
	ObjectStore
	// contains filtered or unexported fields
}

PackStore wraps an ObjectStore to aggregate small objects into larger "packfiles". It uses a stateless JSON catalog ("index/packs") to keep track of which pack contains which object.

func NewPackStore added in v1.4.3

func NewPackStore(inner ObjectStore, opts ...PackOption) (*PackStore, error)

NewPackStore initializes a new MicroPackStore over an existing ObjectStore.

func (*PackStore) CompactCatalog added in v1.16.0

func (s *PackStore) CompactCatalog(ctx context.Context) (int, error)

CompactCatalog folds every shard, and the legacy monolithic catalog, into a single shard and removes what it replaced.

Shards accumulate one per flush, so without compaction opening a repository costs a request per flush ever made. Callers must hold the repository's exclusive lock: this is the one operation that removes index material, and doing it alongside a concurrent writer could drop a shard written between the merge and the delete.

The consolidated shard is written before anything is deleted. A reader that lists midway sees both it and its inputs, which merge to the same result.

func (*PackStore) Delete added in v1.4.3

func (s *PackStore) Delete(ctx context.Context, key string) error

Delete removes an object. For packed objects, it just removes it from the catalog. The actual packfile is not currently garbage collected.

func (*PackStore) Exists added in v1.4.3

func (s *PackStore) Exists(ctx context.Context, key string) (bool, error)

Exists checks the un-flushed buffer, the catalog, or falls back to inner.

func (*PackStore) Flush added in v1.4.3

func (s *PackStore) Flush(ctx context.Context) error

Flush ensures any pending small objects are written to a packfile, and uploads the latest JSON catalog.

func (*PackStore) Get added in v1.4.3

func (s *PackStore) Get(ctx context.Context, key string) ([]byte, error)

Get retrieves an object from the active buffer, a cached pack, or downloads the pack.

func (*PackStore) List added in v1.4.3

func (s *PackStore) List(ctx context.Context, prefix string) ([]string, error)

List returns all keys matching the prefix, merging results from the inner store with the keys currently buffered or indexed in packfiles.

func (*PackStore) Put added in v1.4.3

func (s *PackStore) Put(ctx context.Context, key string, data []byte) error

Put stores data either in the active packbuffer or directly to the inner store.

func (*PackStore) RebuildCatalog added in v1.15.0

func (s *PackStore) RebuildCatalog(ctx context.Context) (recovered int, footerless int, err error)

RebuildCatalog reconstructs the pack catalog by reading every packfile's footer, and merges the result into the in-memory catalog.

This is what demotes index/packs from a single point of failure to a cache: entries recovered here are authoritative, because they come from inside the immutable, content-addressed packfile they describe. Packs written before footers existed contribute nothing and are reported as unrecoverable, since their offsets genuinely exist nowhere but the catalog.

Existing in-memory entries win over recovered ones. Both locate byte-identical content, so the merge is idempotent and order-independent.

func (*PackStore) Repack added in v1.4.4

func (s *PackStore) Repack(ctx context.Context, maxWastedRatio float64) (int64, int, error)

Repack analyzes the packfiles and repacks those that have too much wasted space. Wasted space occurs when objects within a packfile are logically deleted (removed from catalog). maxWastedRatio is the threshold (0.0 to 1.0) above which a pack is repacked. For example, 0.3 means a pack is repacked if it is more than 30% empty. Returns the number of bytes reclaimed, number of packs deleted, and error.

func (*PackStore) Size added in v1.4.3

func (s *PackStore) Size(ctx context.Context, key string) (int64, error)

func (*PackStore) TotalSize added in v1.4.3

func (s *PackStore) TotalSize(ctx context.Context) (int64, error)

type QuotaStore

type QuotaStore struct {
	ObjectStore
	// contains filtered or unexported fields
}

QuotaStore wraps an ObjectStore and cancels the backup context when cumulative bytes written exceed the remaining budget.

func NewQuotaStore

func NewQuotaStore(inner ObjectStore, budget int64, cancel context.CancelCauseFunc) *QuotaStore

func (*QuotaStore) Put

func (q *QuotaStore) Put(ctx context.Context, key string, data []byte) error

func (*QuotaStore) Unwrap added in v1.4.3

func (q *QuotaStore) Unwrap() ObjectStore

func (*QuotaStore) Written

func (q *QuotaStore) Written() int64

Written returns the total bytes successfully written through this store.

type RangeGetter added in v1.15.0

type RangeGetter interface {
	GetRange(ctx context.Context, key string, offset, length int64) ([]byte, error)
}

RangeGetter is an optional interface for backends that can read a byte range without transferring the whole object. It lets PackStore read a packfile's trailing footer without downloading the entire 8 MB pack.

Implementations return exactly length bytes starting at offset, or an error. Backends that cannot do this simply do not implement it; callers fall back to a full Get, which is correct everywhere and merely slower.

type S3Option added in v1.8.0

type S3Option func(*s3Options)

S3Option configures an S3 store.

func WithS3Client added in v1.8.0

func WithS3Client(client *s3.Client) S3Option

WithS3Client provides a pre-configured S3 client, skipping internal client creation. When set, credential, region, and endpoint options are ignored.

func WithS3Credentials added in v1.8.0

func WithS3Credentials(accessKey, secretKey string) S3Option

WithS3Credentials sets static AWS credentials. When omitted the SDK default credential chain is used (env vars, shared config, IAM role, etc.).

func WithS3Endpoint added in v1.8.0

func WithS3Endpoint(endpoint string) S3Option

WithS3Endpoint sets a custom S3-compatible endpoint URL (e.g. MinIO, Cloudflare R2). Path-style addressing is automatically enabled when an endpoint is set.

func WithS3Prefix added in v1.8.0

func WithS3Prefix(prefix string) S3Option

WithS3Prefix sets a key prefix prepended to every object key. Use this to isolate multiple repositories within a single bucket.

func WithS3Profile added in v1.11.0

func WithS3Profile(profile string) S3Option

WithS3Profile sets the AWS shared config profile name used by the SDK default credential chain (e.g. profile from ~/.aws/config).

func WithS3Region added in v1.8.0

func WithS3Region(region string) S3Option

WithS3Region sets the AWS region for the bucket (e.g. "us-east-1").

type S3Store added in v1.3.0

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

S3Store implements ObjectStore for Amazon S3 and compatible services.

func NewS3Store added in v1.3.0

func NewS3Store(ctx context.Context, bucketName string, opts ...S3Option) (*S3Store, error)

func (*S3Store) ConcurrencyHint added in v1.4.3

func (s *S3Store) ConcurrencyHint() int

ConcurrencyHint implements ConcurrencyHinter. S3 benefits from highly parallel uploads since each PUT is a separate HTTP round-trip.

func (*S3Store) Delete added in v1.3.0

func (s *S3Store) Delete(ctx context.Context, key string) error

func (*S3Store) Exists added in v1.3.0

func (s *S3Store) Exists(ctx context.Context, key string) (bool, error)

func (*S3Store) Flush added in v1.4.3

func (s *S3Store) Flush(ctx context.Context) error

func (*S3Store) Get added in v1.3.0

func (s *S3Store) Get(ctx context.Context, key string) ([]byte, error)

func (*S3Store) GetRange added in v1.16.0

func (s *S3Store) GetRange(ctx context.Context, key string, offset, length int64) ([]byte, error)

GetRange implements RangeGetter using an HTTP range request, so a caller reading a packfile footer transfers a few hundred bytes instead of the whole 8 MB object.

func (*S3Store) List added in v1.3.0

func (s *S3Store) List(ctx context.Context, prefix string) ([]string, error)

func (*S3Store) Put added in v1.3.0

func (s *S3Store) Put(ctx context.Context, key string, data []byte) error

func (*S3Store) Size added in v1.3.0

func (s *S3Store) Size(ctx context.Context, key string) (int64, error)

func (*S3Store) TotalSize added in v1.3.0

func (s *S3Store) TotalSize(ctx context.Context) (int64, error)

type SFTPStore added in v1.4.0

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

SFTPStore implements ObjectStore backed by an SFTP server.

func NewSFTPStore added in v1.4.0

func NewSFTPStore(host string, opts ...SFTPStoreOption) (*SFTPStore, error)

NewSFTPStore creates an SFTP-backed store for the given host. Either WithSFTPClient or authentication options must be provided. The base path directory is created if it does not exist.

func (*SFTPStore) Close added in v1.4.0

func (s *SFTPStore) Close() error

Close releases the underlying SFTP and SSH connections.

func (*SFTPStore) Delete added in v1.4.0

func (s *SFTPStore) Delete(_ context.Context, key string) error

func (*SFTPStore) Exists added in v1.4.0

func (s *SFTPStore) Exists(_ context.Context, key string) (bool, error)

func (*SFTPStore) Flush added in v1.4.3

func (s *SFTPStore) Flush(ctx context.Context) error

func (*SFTPStore) Get added in v1.4.0

func (s *SFTPStore) Get(_ context.Context, key string) ([]byte, error)

func (*SFTPStore) GetRange added in v1.16.0

func (s *SFTPStore) GetRange(_ context.Context, key string, offset, length int64) ([]byte, error)

GetRange implements RangeGetter by seeking, which sftp supports natively, so a caller reading a packfile footer does not transfer the whole object.

func (*SFTPStore) List added in v1.4.0

func (s *SFTPStore) List(_ context.Context, prefix string) ([]string, error)

func (*SFTPStore) Put added in v1.4.0

func (s *SFTPStore) Put(_ context.Context, key string, data []byte) error

func (*SFTPStore) Size added in v1.4.0

func (s *SFTPStore) Size(_ context.Context, key string) (int64, error)

func (*SFTPStore) TotalSize added in v1.4.0

func (s *SFTPStore) TotalSize(_ context.Context) (int64, error)

type SFTPStoreOption added in v1.8.0

type SFTPStoreOption func(*sftpStoreOptions)

SFTPStoreOption configures an SFTP store.

func WithSFTPBasePath added in v1.8.0

func WithSFTPBasePath(basePath string) SFTPStoreOption

WithSFTPBasePath sets the root directory on the SFTP server.

func WithSFTPClient added in v1.8.0

func WithSFTPClient(client *sftp.Client) SFTPStoreOption

WithSFTPClient provides a pre-configured SFTP client, skipping internal connection setup. When set, server and auth options are ignored.

func WithSFTPHostKeyCallback added in v1.14.0

func WithSFTPHostKeyCallback(cb ssh.HostKeyCallback) SFTPStoreOption

WithSFTPHostKeyCallback sets the host key verification callback.

func WithSFTPKey added in v1.8.0

func WithSFTPKey(keyPath string) SFTPStoreOption

WithSFTPKey sets the path to a PEM-encoded private key for authentication.

func WithSFTPKnownHosts added in v1.14.0

func WithSFTPKnownHosts(path string) SFTPStoreOption

WithSFTPKnownHosts sets the path to the known_hosts file.

func WithSFTPPassword added in v1.8.0

func WithSFTPPassword(password string) SFTPStoreOption

WithSFTPPassword sets password authentication.

func WithSFTPPort added in v1.8.0

func WithSFTPPort(port string) SFTPStoreOption

WithSFTPPort sets the SSH port. Defaults to "22" when empty.

func WithSFTPUser added in v1.8.0

func WithSFTPUser(user string) SFTPStoreOption

WithSFTPUser sets the SSH user for authentication.

type Unwrapper added in v1.4.3

type Unwrapper interface {
	Unwrap() ObjectStore
}

Unwrapper is an optional interface for wrapper stores (CompressedStore, EncryptedStore, etc.) to expose their inner store for introspection.

Directories

Path Synopsis
Package storetest provides test doubles for store.ObjectStore.
Package storetest provides test doubles for store.ObjectStore.

Jump to

Keyboard shortcuts

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