aboutsummaryrefslogtreecommitdiff
path: root/weed/remote_storage/remote_storage.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/remote_storage/remote_storage.go')
-rw-r--r--weed/remote_storage/remote_storage.go93
1 files changed, 88 insertions, 5 deletions
diff --git a/weed/remote_storage/remote_storage.go b/weed/remote_storage/remote_storage.go
index c9bef8c9b..d8d1e1f5c 100644
--- a/weed/remote_storage/remote_storage.go
+++ b/weed/remote_storage/remote_storage.go
@@ -4,12 +4,26 @@ import (
"fmt"
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
"github.com/chrislusf/seaweedfs/weed/pb/remote_pb"
+ "github.com/golang/protobuf/proto"
"io"
+ "sort"
"strings"
"sync"
+ "time"
)
-func ParseLocation(remote string) (loc *remote_pb.RemoteStorageLocation) {
+func ParseLocationName(remote string) (locationName string) {
+ if strings.HasSuffix(string(remote), "/") {
+ remote = remote[:len(remote)-1]
+ }
+ parts := strings.SplitN(string(remote), "/", 2)
+ if len(parts) >= 1 {
+ return parts[0]
+ }
+ return
+}
+
+func parseBucketLocation(remote string) (loc *remote_pb.RemoteStorageLocation) {
loc = &remote_pb.RemoteStorageLocation{}
if strings.HasSuffix(string(remote), "/") {
remote = remote[:len(remote)-1]
@@ -28,31 +42,97 @@ func ParseLocation(remote string) (loc *remote_pb.RemoteStorageLocation) {
return
}
+func parseNoBucketLocation(remote string) (loc *remote_pb.RemoteStorageLocation) {
+ loc = &remote_pb.RemoteStorageLocation{}
+ if strings.HasSuffix(string(remote), "/") {
+ remote = remote[:len(remote)-1]
+ }
+ parts := strings.SplitN(string(remote), "/", 2)
+ if len(parts) >= 1 {
+ loc.Name = parts[0]
+ }
+ loc.Path = string(remote[len(loc.Name):])
+ if loc.Path == "" {
+ loc.Path = "/"
+ }
+ return
+}
+
func FormatLocation(loc *remote_pb.RemoteStorageLocation) string {
+ if loc.Bucket == "" {
+ return fmt.Sprintf("%s%s", loc.Name, loc.Path)
+ }
return fmt.Sprintf("%s/%s%s", loc.Name, loc.Bucket, loc.Path)
}
type VisitFunc func(dir string, name string, isDirectory bool, remoteEntry *filer_pb.RemoteEntry) error
+type Bucket struct {
+ Name string
+ CreatedAt time.Time
+}
+
type RemoteStorageClient interface {
Traverse(loc *remote_pb.RemoteStorageLocation, visitFn VisitFunc) error
ReadFile(loc *remote_pb.RemoteStorageLocation, offset int64, size int64) (data []byte, err error)
WriteDirectory(loc *remote_pb.RemoteStorageLocation, entry *filer_pb.Entry) (err error)
+ RemoveDirectory(loc *remote_pb.RemoteStorageLocation) (err error)
WriteFile(loc *remote_pb.RemoteStorageLocation, entry *filer_pb.Entry, reader io.Reader) (remoteEntry *filer_pb.RemoteEntry, err error)
UpdateFileMetadata(loc *remote_pb.RemoteStorageLocation, oldEntry *filer_pb.Entry, newEntry *filer_pb.Entry) (err error)
DeleteFile(loc *remote_pb.RemoteStorageLocation) (err error)
+ ListBuckets() ([]*Bucket, error)
+ CreateBucket(name string) (err error)
+ DeleteBucket(name string) (err error)
}
type RemoteStorageClientMaker interface {
Make(remoteConf *remote_pb.RemoteConf) (RemoteStorageClient, error)
+ HasBucket() bool
+}
+
+type CachedRemoteStorageClient struct {
+ *remote_pb.RemoteConf
+ RemoteStorageClient
}
var (
RemoteStorageClientMakers = make(map[string]RemoteStorageClientMaker)
- remoteStorageClients = make(map[string]RemoteStorageClient)
+ remoteStorageClients = make(map[string]CachedRemoteStorageClient)
remoteStorageClientsLock sync.Mutex
)
+func GetAllRemoteStorageNames() string {
+ var storageNames []string
+ for k := range RemoteStorageClientMakers {
+ storageNames = append(storageNames, k)
+ }
+ sort.Strings(storageNames)
+ return strings.Join(storageNames, "|")
+}
+
+func GetRemoteStorageNamesHasBucket() string {
+ var storageNames []string
+ for k, m := range RemoteStorageClientMakers {
+ if m.HasBucket() {
+ storageNames = append(storageNames, k)
+ }
+ }
+ sort.Strings(storageNames)
+ return strings.Join(storageNames, "|")
+}
+
+func ParseRemoteLocation(remoteConfType string, remote string) (remoteStorageLocation *remote_pb.RemoteStorageLocation, err error) {
+ maker, found := RemoteStorageClientMakers[remoteConfType]
+ if !found {
+ return nil, fmt.Errorf("remote storage type %s not found", remoteConfType)
+ }
+
+ if !maker.HasBucket() {
+ return parseNoBucketLocation(remote), nil
+ }
+ return parseBucketLocation(remote), nil
+}
+
func makeRemoteStorageClient(remoteConf *remote_pb.RemoteConf) (RemoteStorageClient, error) {
maker, found := RemoteStorageClientMakers[remoteConf.Type]
if !found {
@@ -66,8 +146,8 @@ func GetRemoteStorage(remoteConf *remote_pb.RemoteConf) (RemoteStorageClient, er
defer remoteStorageClientsLock.Unlock()
existingRemoteStorageClient, found := remoteStorageClients[remoteConf.Name]
- if found {
- return existingRemoteStorageClient, nil
+ if found && proto.Equal(existingRemoteStorageClient.RemoteConf, remoteConf) {
+ return existingRemoteStorageClient.RemoteStorageClient, nil
}
newRemoteStorageClient, err := makeRemoteStorageClient(remoteConf)
@@ -75,7 +155,10 @@ func GetRemoteStorage(remoteConf *remote_pb.RemoteConf) (RemoteStorageClient, er
return nil, fmt.Errorf("make remote storage client %s: %v", remoteConf.Name, err)
}
- remoteStorageClients[remoteConf.Name] = newRemoteStorageClient
+ remoteStorageClients[remoteConf.Name] = CachedRemoteStorageClient{
+ RemoteConf: remoteConf,
+ RemoteStorageClient: newRemoteStorageClient,
+ }
return newRemoteStorageClient, nil
}