This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/server/storage/storage.go
Jeffrey Smith 694779fac6
All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-frontend (push) Has been skipped
CI/CD / test-runners (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-go-pg (push) Successful in 2m45s
CI/CD / test-sqlite (push) Successful in 2m52s
CI/CD / build-and-deploy (push) Successful in 1m20s
Feat v0.8.0 files module (#67)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
2026-04-03 00:18:05 +00:00

85 lines
2.9 KiB
Go

package storage
import (
"context"
"errors"
"io"
)
// ── Errors ─────────────────────────────────
var (
// ErrNotFound is returned when a requested object does not exist.
ErrNotFound = errors.New("storage: object not found")
// ErrNotConfigured is returned when storage operations are attempted
// but no backend has been configured or the backend is unhealthy.
ErrNotConfigured = errors.New("storage: backend not configured")
)
// ── ObjectStore Interface ──────────────────
// ObjectStore is the abstraction for blob storage.
// Implementations: PVC (filesystem), S3 (minio-go v7).
//
// Keys are slash-delimited paths relative to the storage root:
//
// ext/{package_id}/{file_id}_{filename}
//
// Implementations must create intermediate directories as needed.
type ObjectStore interface {
// Put writes data to the given key.
// Creates parent directories as needed. Overwrites if exists.
Put(ctx context.Context, key string, r io.Reader, size int64, contentType string) error
// Get returns a reader for the given key.
// Returns the reader, size in bytes, content type, and error.
// Caller must close the returned reader.
// Returns ErrNotFound if key does not exist.
Get(ctx context.Context, key string) (io.ReadCloser, int64, string, error)
// Delete removes the object at key.
// No error if the key does not exist (idempotent).
Delete(ctx context.Context, key string) error
// DeletePrefix removes all objects under the given prefix.
// Used for bulk cleanup (e.g. extension uninstall).
// Example: DeletePrefix(ctx, "ext/{package_id}/")
DeletePrefix(ctx context.Context, prefix string) error
// Exists checks if an object exists at key without reading it.
Exists(ctx context.Context, key string) (bool, error)
// Healthy returns nil if the backend is operational (writable).
Healthy(ctx context.Context) error
// Stats returns aggregate storage statistics.
Stats(ctx context.Context) (*StorageStats, error)
// List returns objects under the given prefix, up to limit entries.
// Returns an empty slice (not error) if no objects match.
List(ctx context.Context, prefix string, limit int) ([]ObjectEntry, error)
// Backend returns the backend type identifier ("pvc", "s3").
Backend() string
}
// ObjectEntry represents a single object returned by List.
type ObjectEntry struct {
Key string `json:"key"`
Size int64 `json:"size"`
ContentType string `json:"content_type"`
}
// StorageStats holds aggregate storage metrics.
type StorageStats struct {
Backend string `json:"backend"`
Path string `json:"path,omitempty"` // PVC only
Endpoint string `json:"endpoint,omitempty"` // S3 only
Bucket string `json:"bucket,omitempty"` // S3 only
Healthy bool `json:"healthy"`
Configured bool `json:"configured"`
TotalFiles int64 `json:"total_files"`
TotalBytes int64 `json:"total_bytes"`
}