storage.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package main
  2. import (
  3. "errors"
  4. "io/ioutil"
  5. "log"
  6. "os"
  7. "path/filepath"
  8. "runtime"
  9. "imuslab.com/arozos/mod/permission"
  10. fs "imuslab.com/arozos/mod/filesystem"
  11. storage "imuslab.com/arozos/mod/storage"
  12. )
  13. var (
  14. baseStoragePool *storage.StoragePool //base storage pool, all user can access these virtual roots
  15. fsHandlers []*fs.FileSystemHandler //All File system handlers. All opened handles must be registered in here
  16. )
  17. func StorageInit() {
  18. //Load the default handler for the user storage root
  19. if !fileExists(filepath.Clean(*root_directory) + "/") {
  20. os.MkdirAll(filepath.Clean(*root_directory)+"/", 0755)
  21. }
  22. //Start loading the base storage pool
  23. err := LoadBaseStoragePool()
  24. if err != nil {
  25. panic(err)
  26. }
  27. }
  28. func LoadBaseStoragePool() error {
  29. //Use for Debian buster local file system
  30. localFileSystem := "ext4"
  31. if runtime.GOOS == "windows" {
  32. localFileSystem = "ntfs"
  33. }
  34. baseHandler, err := fs.NewFileSystemHandler(fs.FileSystemOption{
  35. Name: "User",
  36. Uuid: "user",
  37. Path: filepath.ToSlash(filepath.Clean(*root_directory)) + "/",
  38. Hierarchy: "user",
  39. Automount: false,
  40. Filesystem: localFileSystem,
  41. })
  42. if err != nil {
  43. log.Println("Failed to initiate user root storage directory: " + *root_directory)
  44. return err
  45. }
  46. fsHandlers = append(fsHandlers, baseHandler)
  47. //Load the tmp folder as storage unit
  48. tmpHandler, err := fs.NewFileSystemHandler(fs.FileSystemOption{
  49. Name: "tmp",
  50. Uuid: "tmp",
  51. Path: filepath.ToSlash(filepath.Clean(*tmp_directory)) + "/",
  52. Hierarchy: "user",
  53. Automount: false,
  54. Filesystem: localFileSystem,
  55. })
  56. if err != nil {
  57. log.Println("Failed to initiate tmp storage directory: " + *tmp_directory)
  58. return err
  59. }
  60. fsHandlers = append(fsHandlers, tmpHandler)
  61. //Load all the storage config from file
  62. rawConfig, err := ioutil.ReadFile(*storage_config_file)
  63. if err != nil {
  64. //File not found. Use internal storage only
  65. log.Println("Storage configuration file not found. Using internal storage only.")
  66. } else {
  67. //Configuration loaded. Initializing handler
  68. externalHandlers, err := fs.NewFileSystemHandlersFromJSON(rawConfig)
  69. if err != nil {
  70. log.Println("Failed to load storage configuration: " + err.Error() + " -- Skipping")
  71. } else {
  72. for _, thisHandler := range externalHandlers {
  73. fsHandlers = append(fsHandlers, thisHandler)
  74. log.Println(thisHandler.Name + " Mounted as " + thisHandler.UUID + ":/")
  75. }
  76. }
  77. }
  78. //Create a base storage pool for all users
  79. sp, err := storage.NewStoragePool(fsHandlers, "system")
  80. if err != nil {
  81. log.Println("Failed to create base Storaeg Pool")
  82. return err
  83. }
  84. //Update the storage pool permission to readwrite
  85. sp.OtherPermission = "readwrite"
  86. baseStoragePool = sp
  87. return nil
  88. }
  89. /*
  90. Initiate the backup handlers for backup drives
  91. This function must be called after the scheduler initiated.
  92. */
  93. func FilesystemDaemonInit() {
  94. }
  95. //Initialize group storage pool
  96. func GroupStoragePoolInit() {
  97. //Mount permission groups
  98. for _, pg := range permissionHandler.PermissionGroups {
  99. //For each group, check does this group has a config file
  100. err := LoadStoragePoolForGroup(pg)
  101. if err != nil {
  102. continue
  103. }
  104. //Do something else, WIP
  105. }
  106. //Start editing interface for Storage Pool Editor
  107. StoragePoolEditorInit()
  108. }
  109. func LoadStoragePoolForGroup(pg *permission.PermissionGroup) error {
  110. expectedConfigPath := "./system/storage/" + pg.Name + ".json"
  111. if fileExists(expectedConfigPath) {
  112. //Read the config file
  113. pgStorageConfig, err := ioutil.ReadFile(expectedConfigPath)
  114. if err != nil {
  115. log.Println("Failed to read config for " + pg.Name + ": " + err.Error())
  116. return errors.New("Failed to read config for " + pg.Name + ": " + err.Error())
  117. }
  118. //Generate fsHandler form json
  119. thisGroupFsHandlers, err := fs.NewFileSystemHandlersFromJSON(pgStorageConfig)
  120. if err != nil {
  121. log.Println("Failed to load storage configuration: " + err.Error())
  122. return errors.New("Failed to load storage configuration: " + err.Error())
  123. }
  124. //Add these to mounted handlers
  125. for _, thisHandler := range thisGroupFsHandlers {
  126. fsHandlers = append(fsHandlers, thisHandler)
  127. log.Println(thisHandler.Name + " Mounted as " + thisHandler.UUID + ":/ for group " + pg.Name)
  128. }
  129. //Create a storage pool from these handlers
  130. sp, err := storage.NewStoragePool(thisGroupFsHandlers, pg.Name)
  131. if err != nil {
  132. log.Println("Failed to create storage pool for " + pg.Name)
  133. return errors.New("Failed to create storage pool for " + pg.Name)
  134. }
  135. //Set other permission to denied by default
  136. sp.OtherPermission = "denied"
  137. //Assign storage pool to group
  138. pg.StoragePool = sp
  139. } else {
  140. //Storage configuration not exists. Fill in the basic information and move to next storage pool
  141. pg.StoragePool.Owner = pg.Name
  142. pg.StoragePool.OtherPermission = "denied"
  143. }
  144. return nil
  145. }
  146. func GetFsHandlerByUUID(uuid string) (*fs.FileSystemHandler, error) {
  147. for _, fsh := range fsHandlers {
  148. if fsh.UUID == uuid {
  149. return fsh, nil
  150. }
  151. }
  152. return nil, errors.New("Filesystem handler with given UUID not found")
  153. }
  154. func RegisterStorageSettings() {
  155. //Storage Pool Configuration
  156. registerSetting(settingModule{
  157. Name: "Storage Pools",
  158. Desc: "Storage Pool Mounting Configuration",
  159. IconPath: "SystemAO/disk/smart/img/small_icon.png",
  160. Group: "Disk",
  161. StartDir: "SystemAO/storage/poolList.html",
  162. RequireAdmin: true,
  163. })
  164. }
  165. //CloseAllStorages Close all storage database
  166. func CloseAllStorages() {
  167. for _, fsh := range fsHandlers {
  168. fsh.FilesystemDatabase.Close()
  169. }
  170. }