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.

133 lines
3.6 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.VolumeTierInfo) BackendStorageFile
  23. CopyFile(f *os.File, fn func(progressed int64, percentage float32) error) (key string, size int64, err error)
  24. }
  25. type StringProperties interface {
  26. GetString(key string) string
  27. }
  28. type StorageType string
  29. type BackendStorageFactory interface {
  30. StorageType() StorageType
  31. BuildStorage(configuration StringProperties, id string) (BackendStorage, error)
  32. }
  33. var (
  34. BackendStorageFactories = make(map[StorageType]BackendStorageFactory)
  35. BackendStorages = make(map[string]BackendStorage)
  36. )
  37. func LoadConfiguration(config *viper.Viper) {
  38. StorageBackendPrefix := "storage.backend"
  39. backendSub := config.Sub(StorageBackendPrefix)
  40. for backendTypeName := range config.GetStringMap(StorageBackendPrefix) {
  41. backendStorageFactory, found := BackendStorageFactories[StorageType(backendTypeName)]
  42. if !found {
  43. glog.Fatalf("backend storage type %s not found", backendTypeName)
  44. }
  45. backendTypeSub := backendSub.Sub(backendTypeName)
  46. for backendStorageId := range backendSub.GetStringMap(backendTypeName) {
  47. if !backendTypeSub.GetBool(backendStorageId + ".enabled") {
  48. continue
  49. }
  50. backendStorage, buildErr := backendStorageFactory.BuildStorage(backendTypeSub.Sub(backendStorageId), backendStorageId)
  51. if buildErr != nil {
  52. glog.Fatalf("fail to create backend storage %s.%s", backendTypeName, backendStorageId)
  53. }
  54. BackendStorages[backendTypeName+"."+backendStorageId] = backendStorage
  55. if backendStorageId == "default" {
  56. BackendStorages[backendTypeName] = backendStorage
  57. }
  58. }
  59. }
  60. }
  61. func LoadFromPbStorageBackends(storageBackends []*master_pb.StorageBackend) {
  62. for _, storageBackend := range storageBackends {
  63. backendStorageFactory, found := BackendStorageFactories[StorageType(storageBackend.Type)]
  64. if !found {
  65. glog.Warningf("storage type %s not found", storageBackend.Type)
  66. continue
  67. }
  68. backendStorage, buildErr := backendStorageFactory.BuildStorage(newProperties(storageBackend.Properties), storageBackend.Id)
  69. if buildErr != nil {
  70. glog.Fatalf("fail to create backend storage %s.%s", storageBackend.Type, storageBackend.Id)
  71. }
  72. BackendStorages[storageBackend.Type+"."+storageBackend.Id] = backendStorage
  73. if storageBackend.Id == "default" {
  74. BackendStorages[storageBackend.Type] = backendStorage
  75. }
  76. }
  77. }
  78. type Properties struct {
  79. m map[string]string
  80. }
  81. func newProperties(m map[string]string) *Properties {
  82. return &Properties{m: m}
  83. }
  84. func (p *Properties) GetString(key string) string {
  85. if v, found := p.m[key]; found {
  86. return v
  87. }
  88. return ""
  89. }
  90. func ToPbStorageBackends() (backends []*master_pb.StorageBackend) {
  91. for sName, s := range BackendStorages {
  92. sType, sId := BackendNameToTypeId(sName)
  93. if sType == "" {
  94. continue
  95. }
  96. backends = append(backends, &master_pb.StorageBackend{
  97. Type: sType,
  98. Id: sId,
  99. Properties: s.ToProperties(),
  100. })
  101. }
  102. return
  103. }
  104. func BackendNameToTypeId(backendName string) (backendType, backendId string) {
  105. parts := strings.Split(backendName, ".")
  106. if len(parts) == 1 {
  107. return backendName, "default"
  108. }
  109. if len(parts) != 2 {
  110. return
  111. }
  112. backendType, backendId = parts[0], parts[1]
  113. return
  114. }