storage.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. "os"
  11. "strings"
  12. "imuslab.com/arozos/mod/filesystem"
  13. fs "imuslab.com/arozos/mod/filesystem"
  14. "imuslab.com/arozos/mod/filesystem/arozfs"
  15. )
  16. type StoragePool struct {
  17. Owner string //Owner of the storage pool, also act as the resolver's username
  18. OtherPermission string //Permissions on other users but not the owner
  19. Storages []*fs.FileSystemHandler //Storage pool accessable by this owner
  20. //HyperBackupManager *hybridBackup.Manager //HyperBackup Manager
  21. }
  22. /*
  23. Permission Levels (From TOP to BOTTOM -> HIGHEST to LOWEST)
  24. 1. readwrite
  25. 2. readonly
  26. 3. denied
  27. */
  28. //Create all the required folder structure if it didn't exists
  29. func init() {
  30. os.MkdirAll("./system/storage", 0755)
  31. }
  32. //Create a new StoragePool objects with given uuids
  33. func NewStoragePool(fsHandlers []*fs.FileSystemHandler, owner string) (*StoragePool, error) {
  34. //Move all fshandler into the storageHandler
  35. storageHandlers := []*fs.FileSystemHandler{}
  36. for _, fsHandler := range fsHandlers {
  37. //Move the handler pointer to the target
  38. storageHandlers = append(storageHandlers, fsHandler)
  39. }
  40. return &StoragePool{
  41. Owner: owner,
  42. OtherPermission: arozfs.FsReadOnly,
  43. Storages: storageHandlers,
  44. }, nil
  45. }
  46. //Check if this storage pool contain this particular disk ID
  47. func (s *StoragePool) ContainDiskID(diskID string) bool {
  48. for _, fsh := range s.Storages {
  49. if fsh.UUID == diskID {
  50. return true
  51. }
  52. }
  53. return false
  54. }
  55. //Use to compare two StoragePool permissions leve
  56. func (s *StoragePool) HasHigherOrEqualPermissionThan(a *StoragePool) bool {
  57. if s.OtherPermission == arozfs.FsReadOnly && a.OtherPermission == arozfs.FsReadWrite {
  58. return false
  59. } else if s.OtherPermission == arozfs.FsDenied && a.OtherPermission != arozfs.FsDenied {
  60. return false
  61. }
  62. return true
  63. }
  64. //Get fsh from virtual path
  65. func (s *StoragePool) GetFSHandlerFromVirtualPath(vpath string) (*fs.FileSystemHandler, string, error) {
  66. fshid, subpath, err := filesystem.GetIDFromVirtualPath(vpath)
  67. if err != nil {
  68. return nil, subpath, err
  69. }
  70. fsh, err := s.GetFsHandlerByUUID(fshid)
  71. if err != nil {
  72. return nil, subpath, err
  73. }
  74. return fsh, subpath, nil
  75. }
  76. func (s *StoragePool) GetFsHandlerByUUID(uuid string) (*fs.FileSystemHandler, error) {
  77. //Filter out the :/ fropm uuid if exists
  78. if strings.Contains(uuid, ":") {
  79. uuid = strings.Split(uuid, ":")[0]
  80. }
  81. for _, fsh := range s.Storages {
  82. if fsh.UUID == uuid {
  83. return fsh, nil
  84. }
  85. }
  86. return nil, arozfs.ErrFSHNotFOund
  87. }
  88. //Attach a file system handler to this pool
  89. func (s *StoragePool) AttachFsHandler(fsh *filesystem.FileSystemHandler) error {
  90. if s.ContainDiskID(fsh.UUID) {
  91. return errors.New("file system handler with same uuid already exists in this pool")
  92. }
  93. s.Storages = append(s.Storages, fsh)
  94. return nil
  95. }
  96. //Detech a file system handler from this pool array
  97. func (s *StoragePool) DetachFsHandler(uuid string) {
  98. newFshList := []*fs.FileSystemHandler{}
  99. for _, fsh := range s.Storages {
  100. if fsh.UUID != uuid {
  101. newFshList = append(newFshList, fsh)
  102. }
  103. }
  104. s.Storages = newFshList
  105. }
  106. //Close all fsHandler under this storage pool
  107. func (s *StoragePool) Close() {
  108. //For each storage pool, close it
  109. for _, fsh := range s.Storages {
  110. fsh.Close()
  111. }
  112. }