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.

137 lines
3.9 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. package backend
  2. import (
  3. "io"
  4. "os"
  5. "strings"
  6. "time"
  7. "github.com/chrislusf/seaweedfs/weed/glog"
  8. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  9. "github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
  10. "github.com/spf13/viper"
  11. )
  12. type BackendStorageFile interface {
  13. io.ReaderAt
  14. io.WriterAt
  15. Truncate(off int64) error
  16. io.Closer
  17. GetStat() (datSize int64, modTime time.Time, err error)
  18. Name() string
  19. }
  20. type BackendStorage interface {
  21. ToProperties() map[string]string
  22. NewStorageFile(key string, tierInfo *volume_server_pb.VolumeInfo) BackendStorageFile
  23. CopyFile(f *os.File, attributes map[string]string, fn func(progressed int64, percentage float32) error) (key string, size int64, err error)
  24. DownloadFile(fileName string, key string, fn func(progressed int64, percentage float32) error) (size int64, err error)
  25. DeleteFile(key string) (err error)
  26. }
  27. type StringProperties interface {
  28. GetString(key string) string
  29. }
  30. type StorageType string
  31. type BackendStorageFactory interface {
  32. StorageType() StorageType
  33. BuildStorage(configuration StringProperties, id string) (BackendStorage, error)
  34. }
  35. var (
  36. BackendStorageFactories = make(map[StorageType]BackendStorageFactory)
  37. BackendStorages = make(map[string]BackendStorage)
  38. )
  39. // used by master to load remote storage configurations
  40. func LoadConfiguration(config *viper.Viper) {
  41. StorageBackendPrefix := "storage.backend"
  42. backendSub := config.Sub(StorageBackendPrefix)
  43. for backendTypeName := range config.GetStringMap(StorageBackendPrefix) {
  44. backendStorageFactory, found := BackendStorageFactories[StorageType(backendTypeName)]
  45. if !found {
  46. glog.Fatalf("backend storage type %s not found", backendTypeName)
  47. }
  48. backendTypeSub := backendSub.Sub(backendTypeName)
  49. for backendStorageId := range backendSub.GetStringMap(backendTypeName) {
  50. if !backendTypeSub.GetBool(backendStorageId + ".enabled") {
  51. continue
  52. }
  53. backendStorage, buildErr := backendStorageFactory.BuildStorage(backendTypeSub.Sub(backendStorageId), backendStorageId)
  54. if buildErr != nil {
  55. glog.Fatalf("fail to create backend storage %s.%s", backendTypeName, backendStorageId)
  56. }
  57. BackendStorages[backendTypeName+"."+backendStorageId] = backendStorage
  58. if backendStorageId == "default" {
  59. BackendStorages[backendTypeName] = backendStorage
  60. }
  61. }
  62. }
  63. }
  64. // used by volume server to receive remote storage configurations from master
  65. func LoadFromPbStorageBackends(storageBackends []*master_pb.StorageBackend) {
  66. for _, storageBackend := range storageBackends {
  67. backendStorageFactory, found := BackendStorageFactories[StorageType(storageBackend.Type)]
  68. if !found {
  69. glog.Warningf("storage type %s not found", storageBackend.Type)
  70. continue
  71. }
  72. backendStorage, buildErr := backendStorageFactory.BuildStorage(newProperties(storageBackend.Properties), storageBackend.Id)
  73. if buildErr != nil {
  74. glog.Fatalf("fail to create backend storage %s.%s", storageBackend.Type, storageBackend.Id)
  75. }
  76. BackendStorages[storageBackend.Type+"."+storageBackend.Id] = backendStorage
  77. if storageBackend.Id == "default" {
  78. BackendStorages[storageBackend.Type] = backendStorage
  79. }
  80. }
  81. }
  82. type Properties struct {
  83. m map[string]string
  84. }
  85. func newProperties(m map[string]string) *Properties {
  86. return &Properties{m: m}
  87. }
  88. func (p *Properties) GetString(key string) string {
  89. if v, found := p.m[key]; found {
  90. return v
  91. }
  92. return ""
  93. }
  94. func ToPbStorageBackends() (backends []*master_pb.StorageBackend) {
  95. for sName, s := range BackendStorages {
  96. sType, sId := BackendNameToTypeId(sName)
  97. if sType == "" {
  98. continue
  99. }
  100. backends = append(backends, &master_pb.StorageBackend{
  101. Type: sType,
  102. Id: sId,
  103. Properties: s.ToProperties(),
  104. })
  105. }
  106. return
  107. }
  108. func BackendNameToTypeId(backendName string) (backendType, backendId string) {
  109. parts := strings.Split(backendName, ".")
  110. if len(parts) == 1 {
  111. return backendName, "default"
  112. }
  113. if len(parts) != 2 {
  114. return
  115. }
  116. backendType, backendId = parts[0], parts[1]
  117. return
  118. }