79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
package storage
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
)
|
|
|
|
// Init creates an ObjectStore based on the configuration.
|
|
//
|
|
// Auto-detection when backend is empty:
|
|
// - If storagePath is writable → PVC (implicit)
|
|
// - If storagePath is missing/unwritable → nil (storage disabled)
|
|
//
|
|
// Explicit backends:
|
|
// - "pvc" → PVC, fail if path is not writable
|
|
// - "s3" → S3-compatible (MinIO, Ceph RGW, AWS), fail if not reachable
|
|
func Init(backend, storagePath string, s3Cfg *S3Config) (ObjectStore, error) {
|
|
switch backend {
|
|
case "pvc":
|
|
// Explicit PVC — fail if not writable
|
|
s, err := NewPVC(storagePath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("storage: PVC backend at %q: %w", storagePath, err)
|
|
}
|
|
log.Printf(" 📁 Storage: PVC at %s", storagePath)
|
|
return s, nil
|
|
|
|
case "s3":
|
|
if s3Cfg == nil {
|
|
return nil, fmt.Errorf("storage: S3 backend requires S3_BUCKET and credentials")
|
|
}
|
|
s, err := NewS3(*s3Cfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("storage: S3 backend: %w", err)
|
|
}
|
|
endpoint := s3Cfg.Endpoint
|
|
if endpoint == "" {
|
|
endpoint = "AWS"
|
|
}
|
|
log.Printf(" 📁 Storage: S3 at %s/%s (prefix=%q)", endpoint, s3Cfg.Bucket, s3Cfg.Prefix)
|
|
return s, nil
|
|
|
|
case "":
|
|
// Auto-detect: try PVC if path exists or is creatable
|
|
s, err := NewPVC(storagePath)
|
|
if err != nil {
|
|
// Path not writable — storage disabled, not an error
|
|
log.Printf(" 📁 Storage: disabled (path %s not writable)", storagePath)
|
|
return nil, nil
|
|
}
|
|
log.Printf(" 📁 Storage: PVC at %s (auto-detected)", storagePath)
|
|
return s, nil
|
|
|
|
default:
|
|
return nil, fmt.Errorf("storage: unknown backend %q (expected pvc or s3)", backend)
|
|
}
|
|
}
|
|
|
|
// IsPathWritable checks if a directory path exists and is writable.
|
|
// Used by auto-detection. Does not create the directory.
|
|
func IsPathWritable(path string) bool {
|
|
info, err := os.Stat(path)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
if !info.IsDir() {
|
|
return false
|
|
}
|
|
|
|
// Try writing a probe file
|
|
probe := path + "/.writable-probe"
|
|
if err := os.WriteFile(probe, []byte("ok"), 0o644); err != nil {
|
|
return false
|
|
}
|
|
os.Remove(probe)
|
|
return true
|
|
}
|