storage.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package storage
  2. /*
  3. ArOZ Online Storage Handler Module
  4. author: tobychui
  5. This is a system for allowing generic interfacing to the filesystems
  6. To add more supports for different type of file system, add more storage handlers.
  7. */
  8. import (
  9. "errors"
  10. "log"
  11. "os"
  12. "strings"
  13. "imuslab.com/arozos/mod/disk/hybridBackup"
  14. "imuslab.com/arozos/mod/filesystem"
  15. fs "imuslab.com/arozos/mod/filesystem"
  16. )
  17. type StoragePool struct {
  18. Owner string //Owner of the storage pool, also act as the resolver's username
  19. OtherPermission string //Permissions on other users but not the owner
  20. Storages []*fs.FileSystemHandler //Storage pool accessable by this owner
  21. HyperBackupManager *hybridBackup.Manager //HyperBackup Manager
  22. }
  23. /*
  24. Permission Levels (From TOP to BOTTOM -> HIGHEST to LOWEST)
  25. 1. readwrite
  26. 2. readonly
  27. 3. denied
  28. */
  29. //Create all the required folder structure if it didn't exists
  30. func init() {
  31. os.MkdirAll("./system/storage", 0755)
  32. }
  33. //Create a new StoragePool objects with given uuids
  34. func NewStoragePool(fsHandlers []*fs.FileSystemHandler, owner string) (*StoragePool, error) {
  35. //Create new HypberBackup Manager
  36. backupManager := hybridBackup.NewHyperBackupManager()
  37. //Move all fshandler into the storageHandler
  38. storageHandlers := []*fs.FileSystemHandler{}
  39. for _, fsHandler := range fsHandlers {
  40. //Move the handler pointer to the target
  41. storageHandlers = append(storageHandlers, fsHandler)
  42. if fsHandler.Hierarchy == "backup" {
  43. //Backup disk. Build the Hierarchy Config for this drive
  44. backupConfig := fsHandler.HierarchyConfig.(hybridBackup.BackupTask)
  45. //Resolve parent path for backup File System Handler
  46. parentExists := false
  47. for _, potentialParnet := range fsHandlers {
  48. if potentialParnet.UUID == backupConfig.ParentUID {
  49. //This is the parent
  50. backupConfig.ParentPath = potentialParnet.Path
  51. parentExists = true
  52. }
  53. }
  54. if parentExists {
  55. backupManager.AddTask(&backupConfig)
  56. } else {
  57. log.Println("*ERROR* Backup disk " + backupConfig.DiskUID + ":/ source disk not found: " + backupConfig.ParentUID + ":/ not exists or it is from other storage pool!")
  58. }
  59. }
  60. }
  61. return &StoragePool{
  62. Owner: owner,
  63. OtherPermission: "readonly",
  64. Storages: storageHandlers,
  65. HyperBackupManager: backupManager,
  66. }, nil
  67. }
  68. //Check if this storage pool contain this particular disk ID
  69. func (s *StoragePool) ContainDiskID(diskID string) bool {
  70. for _, fsh := range s.Storages {
  71. if fsh.UUID == diskID {
  72. return true
  73. }
  74. }
  75. return false
  76. }
  77. //Use to compare two StoragePool permissions leve
  78. func (s *StoragePool) HasHigherOrEqualPermissionThan(a *StoragePool) bool {
  79. if s.OtherPermission == "readonly" && a.OtherPermission == "readwrite" {
  80. return false
  81. } else if s.OtherPermission == "denied" && a.OtherPermission != "denied" {
  82. return false
  83. }
  84. return true
  85. }
  86. //Get fsh from virtual path
  87. func (s *StoragePool) GetFSHandlerFromVirtualPath(vpath string) (*fs.FileSystemHandler, string, error) {
  88. fshid, subpath, err := filesystem.GetIDFromVirtualPath(vpath)
  89. if err != nil {
  90. return nil, subpath, err
  91. }
  92. fsh, err := s.GetFsHandlerByUUID(fshid)
  93. if err != nil {
  94. return nil, subpath, err
  95. }
  96. return fsh, subpath, nil
  97. }
  98. func (s *StoragePool) GetFsHandlerByUUID(uuid string) (*fs.FileSystemHandler, error) {
  99. //Filter out the :/ fropm uuid if exists
  100. if strings.Contains(uuid, ":") {
  101. uuid = strings.Split(uuid, ":")[0]
  102. }
  103. for _, fsh := range s.Storages {
  104. if fsh.UUID == uuid {
  105. return fsh, nil
  106. }
  107. }
  108. return nil, errors.New("Filesystem handler with given UUID not found")
  109. }
  110. //Close all fsHandler under this storage pool
  111. func (s *StoragePool) Close() {
  112. //Close the running backup tasks
  113. s.HyperBackupManager.Close()
  114. //For each storage pool, close it
  115. for _, fsh := range s.Storages {
  116. fsh.Close()
  117. }
  118. }
  119. //Helper function
  120. func inSlice(slice []string, val string) bool {
  121. for _, item := range slice {
  122. if item == val {
  123. return true
  124. }
  125. }
  126. return false
  127. }