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.

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