You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.7 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package filer
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/chrislusf/seaweedfs/weed/remote_storage"
  6. _ "github.com/chrislusf/seaweedfs/weed/remote_storage/s3"
  7. "github.com/chrislusf/seaweedfs/weed/util"
  8. "github.com/golang/protobuf/proto"
  9. "math"
  10. "strings"
  11. "github.com/chrislusf/seaweedfs/weed/glog"
  12. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  13. "github.com/viant/ptrie"
  14. )
  15. const REMOTE_STORAGE_CONF_SUFFIX = ".conf"
  16. const REMOTE_STORAGE_MOUNT_FILE = "mount.mapping"
  17. type FilerRemoteStorage struct {
  18. rules ptrie.Trie
  19. storageNameToConf map[string]*filer_pb.RemoteConf
  20. }
  21. func NewFilerRemoteStorage() (rs *FilerRemoteStorage) {
  22. rs = &FilerRemoteStorage{
  23. rules: ptrie.New(),
  24. storageNameToConf: make(map[string]*filer_pb.RemoteConf),
  25. }
  26. return rs
  27. }
  28. func (rs *FilerRemoteStorage) loadRemoteStorageConfigurations(filer *Filer) (err error) {
  29. // execute this on filer
  30. entries, _, err := filer.ListDirectoryEntries(context.Background(), DirectoryEtcRemote, "", false, math.MaxInt64, "", "", "")
  31. if err != nil {
  32. if err == filer_pb.ErrNotFound {
  33. return nil
  34. }
  35. glog.Errorf("read remote storage %s: %v", DirectoryEtcRemote, err)
  36. return
  37. }
  38. for _, entry := range entries {
  39. if entry.Name() == REMOTE_STORAGE_MOUNT_FILE {
  40. rs.loadRemoteStorageMountMapping(entry.Content)
  41. }
  42. if !strings.HasSuffix(entry.Name(), REMOTE_STORAGE_CONF_SUFFIX) {
  43. return nil
  44. }
  45. conf := &filer_pb.RemoteConf{}
  46. if err := proto.Unmarshal(entry.Content, conf); err != nil {
  47. return fmt.Errorf("unmarshal %s/%s: %v", DirectoryEtcRemote, entry.Name(), err)
  48. }
  49. rs.storageNameToConf[conf.Name] = conf
  50. }
  51. return nil
  52. }
  53. func (rs *FilerRemoteStorage) loadRemoteStorageMountMapping(data []byte) (err error) {
  54. mappings := &filer_pb.RemoteStorageMappingList{}
  55. if err := proto.Unmarshal(data, mappings); err != nil {
  56. return fmt.Errorf("unmarshal %s/%s: %v", DirectoryEtcRemote, REMOTE_STORAGE_MOUNT_FILE, err)
  57. }
  58. for _, mapping := range mappings.Mappings {
  59. rs.mapDirectoryToRemoteStorage(util.FullPath(mapping.Dir), mapping.RemoteStorageName)
  60. }
  61. return nil
  62. }
  63. func (rs *FilerRemoteStorage) mapDirectoryToRemoteStorage(dir util.FullPath, remoteStorageName string) {
  64. rs.rules.Put([]byte(dir+"/"), remoteStorageName)
  65. }
  66. func (rs *FilerRemoteStorage) FindRemoteStorageClient(p util.FullPath) (client remote_storage.RemoteStorageClient, found bool) {
  67. var storageName string
  68. rs.rules.MatchPrefix([]byte(p), func(key []byte, value interface{}) bool {
  69. storageName = value.(string)
  70. return true
  71. })
  72. if storageName == "" {
  73. return
  74. }
  75. remoteConf, ok := rs.storageNameToConf[storageName]
  76. if !ok {
  77. return
  78. }
  79. var err error
  80. if client, err = remote_storage.GetRemoteStorage(remoteConf); err == nil {
  81. found = true
  82. return
  83. }
  84. return
  85. }