mirror of
https://github.com/gopasspw/gopass.git
synced 2025-12-08 19:24:54 +00:00
* [chore] Add PID to the debug logs This helps differentiate between gopass foreground and background (e.g. agent) processes. Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org> * [chore] Adjust logging severities and improve pretty printing Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org> --------- Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
126 lines
3.5 KiB
Go
126 lines
3.5 KiB
Go
package backend
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/blang/semver/v4"
|
|
"github.com/gopasspw/gopass/pkg/debug"
|
|
)
|
|
|
|
// ErrNotSupported is returned by backends for unsupported calls.
|
|
var ErrNotSupported = fmt.Errorf("not supported")
|
|
|
|
// StorageBackend is a type of storage backend.
|
|
type StorageBackend int
|
|
|
|
const (
|
|
// FS is a filesystem-backed storage.
|
|
FS StorageBackend = iota
|
|
// GitFS is a filesystem-backed storage with Git.
|
|
GitFS
|
|
// FossilFS is a filesystem-backed storage with Fossil.
|
|
FossilFS
|
|
// JJ is a filesystem-backed storage with Jujutsu.
|
|
JJFS
|
|
// CryptFS is a filename encrypting storage.
|
|
CryptFS
|
|
)
|
|
|
|
func (s StorageBackend) String() string {
|
|
if be, err := StorageRegistry.BackendName(s); err == nil {
|
|
return be
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// Storage is an storage backend.
|
|
type Storage interface {
|
|
fmt.Stringer
|
|
rcs
|
|
Get(ctx context.Context, name string) ([]byte, error)
|
|
Set(ctx context.Context, name string, value []byte) error
|
|
Delete(ctx context.Context, name string) error
|
|
Exists(ctx context.Context, name string) bool
|
|
Move(ctx context.Context, from, to string, del bool) error
|
|
List(ctx context.Context, prefix string) ([]string, error)
|
|
IsDir(ctx context.Context, name string) bool
|
|
Prune(ctx context.Context, prefix string) error
|
|
Link(ctx context.Context, from, to string) error
|
|
|
|
Name() string
|
|
Path() string
|
|
Version(context.Context) semver.Version
|
|
Fsck(context.Context) error
|
|
}
|
|
|
|
// DetectStorage tries to detect the storage backend being used.
|
|
func DetectStorage(ctx context.Context, path string) (Storage, error) {
|
|
// The call to HasStorageBackend is important since GetStorageBackend will always return FS
|
|
// if nothing is found in the context.
|
|
if be, err := StorageRegistry.Get(GetStorageBackend(ctx)); HasStorageBackend(ctx) && err == nil {
|
|
debug.V(1).Log("Trying requested storage backend %q for %q", be, path)
|
|
st, err := be.New(ctx, path)
|
|
if err == nil {
|
|
debug.Log("Successfully loaded requested storage backend %q for %q", be, path)
|
|
|
|
return st, nil
|
|
}
|
|
debug.Log("Failed to use requested storage backend %q for %s: %q", be, path, err)
|
|
|
|
// fallback to FS
|
|
be, err := StorageRegistry.Get(FS)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
debug.Log("Using fallback %q for %q", be, path)
|
|
|
|
return be.Init(ctx, path)
|
|
}
|
|
|
|
// Nothing requested in the context. Try to detect the backend.
|
|
for _, be := range StorageRegistry.Prioritized() {
|
|
debug.V(1).Log("Trying storage backend %q for %q", be, path)
|
|
if err := be.Handles(ctx, path); err != nil {
|
|
debug.Log("failed to use %s for %s: %s", be, path, err)
|
|
|
|
continue
|
|
}
|
|
debug.Log("Detected storage backend %q for %q", be, path)
|
|
|
|
return be.New(ctx, path)
|
|
}
|
|
|
|
// fallback to FS
|
|
be, err := StorageRegistry.Get(FS)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
debug.Log("Using default fallback %q for %q", be, path)
|
|
|
|
return be.Init(ctx, path)
|
|
}
|
|
|
|
// NewStorage initializes an existing storage backend.
|
|
func NewStorage(ctx context.Context, id StorageBackend, path string) (Storage, error) {
|
|
if be, err := StorageRegistry.Get(id); err == nil {
|
|
debug.Log("Using storage backend %q for %q", be, path)
|
|
|
|
return be.New(ctx, path)
|
|
}
|
|
|
|
return nil, fmt.Errorf("unknown backend %q: %w", path, ErrNotFound)
|
|
}
|
|
|
|
// InitStorage initilizes a new storage location.
|
|
func InitStorage(ctx context.Context, id StorageBackend, path string) (Storage, error) {
|
|
if be, err := StorageRegistry.Get(id); err == nil {
|
|
debug.Log("Using %s for %s", be, path)
|
|
|
|
return be.Init(ctx, path)
|
|
}
|
|
|
|
return nil, fmt.Errorf("unknown backend %q: %w", path, ErrNotFound)
|
|
}
|