瀏覽代碼

Merge pull request #1630 from kaelanspatel/kaelan-prefix-bucket-backup

Add support for prefix parameter in bucket config
Kaelan Patel 3 年之前
父節點
當前提交
6847bc082b
共有 2 個文件被更改,包括 93 次插入0 次删除
  1. 5 0
      pkg/storage/bucketstorage.go
  2. 88 0
      pkg/storage/prefixedbucketstorage.go

+ 5 - 0
pkg/storage/bucketstorage.go

@@ -22,6 +22,7 @@ const (
 type StorageConfig struct {
 	Type   StorageProvider `yaml:"type"`
 	Config interface{}     `yaml:"config"`
+	Prefix string          `yaml:"prefix"`
 }
 
 // NewBucketStorage initializes and returns new Storage implementation leveraging the storage provider
@@ -54,6 +55,10 @@ func NewBucketStorage(config []byte) (Storage, error) {
 		return nil, errors.Wrap(err, fmt.Sprintf("create %s client", storageConfig.Type))
 	}
 
+	if storageConfig.Prefix != "" {
+		return NewPrefixedBucketStorage(storage, storageConfig.Prefix)
+	}
+
 	return storage, nil
 }
 

+ 88 - 0
pkg/storage/prefixedbucketstorage.go

@@ -0,0 +1,88 @@
+package storage
+
+// Partially forked from Thanos prefixed bucket for prefix handling
+// Licensed under the Apache License 2.0
+// https://github.com/thanos-io/objstore/blob/main/prefixed_bucket.go
+
+import (
+	"strings"
+
+	"github.com/pkg/errors"
+)
+
+type PrefixedBucketStorage struct {
+	storage Storage
+	prefix  string
+}
+
+func NewPrefixedBucketStorage(storage Storage, prefix string) (Storage, error) {
+	if validPrefix(prefix) {
+		return &PrefixedBucketStorage{
+			storage: storage,
+			prefix:  strings.Trim(prefix, DirDelim),
+		}, nil
+	}
+
+	return storage, errors.Errorf("failed to create prefixed storage: invalid prefix '%s'", prefix)
+}
+
+func validPrefix(prefix string) bool {
+	prefix = strings.Replace(prefix, "/", "", -1)
+	return len(prefix) > 0
+}
+
+func conditionalPrefix(prefix, name string) string {
+	if len(name) > 0 {
+		return withPrefix(prefix, name)
+	}
+
+	return name
+}
+
+func withPrefix(prefix, name string) string {
+	return prefix + DirDelim + name
+}
+
+func (pbs *PrefixedBucketStorage) StorageType() StorageType {
+	return pbs.storage.StorageType()
+}
+
+// FullPath returns the storage working path combined with the path provided.
+func (pbs *PrefixedBucketStorage) FullPath(name string) string {
+	return pbs.storage.FullPath(conditionalPrefix(pbs.prefix, name))
+}
+
+// Exists checks if the given object exists.
+func (pbs *PrefixedBucketStorage) Exists(name string) (bool, error) {
+	return pbs.storage.Exists(conditionalPrefix(pbs.prefix, name))
+}
+
+// List returns storage information for files on the provided path.
+func (pbs *PrefixedBucketStorage) List(path string) ([]*StorageInfo, error) {
+	return pbs.storage.List(conditionalPrefix(pbs.prefix, path))
+}
+
+// ListDirectories returns storage information for only directories on the provided path.
+func (pbs *PrefixedBucketStorage) ListDirectories(path string) ([]*StorageInfo, error) {
+	return pbs.storage.ListDirectories(conditionalPrefix(pbs.prefix, path))
+}
+
+// Read returns a reader for the given object name.
+func (pbs *PrefixedBucketStorage) Read(name string) ([]byte, error) {
+	return pbs.storage.Read(conditionalPrefix(pbs.prefix, name))
+}
+
+// Remove deletes the object with the given name.
+func (pbs *PrefixedBucketStorage) Remove(name string) error {
+	return pbs.storage.Remove(conditionalPrefix(pbs.prefix, name))
+}
+
+// Stat returns information about the specified object.
+func (pbs *PrefixedBucketStorage) Stat(name string) (*StorageInfo, error) {
+	return pbs.storage.Stat(conditionalPrefix(pbs.prefix, name))
+}
+
+// Write uploads the contents of the reader as an object into the bucket.
+func (pbs *PrefixedBucketStorage) Write(name string, data []byte) error {
+	return pbs.storage.Write(conditionalPrefix(pbs.prefix, name), data)
+}