123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- package main
- import (
- "errors"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "runtime"
- "imuslab.com/arozos/mod/filesystem/hybridBackup"
- "imuslab.com/arozos/mod/permission"
- fs "imuslab.com/arozos/mod/filesystem"
- storage "imuslab.com/arozos/mod/storage"
- )
- var (
- baseStoragePool *storage.StoragePool //base storage pool, all user can access these virtual roots
- fsHandlers []*fs.FileSystemHandler //All File system handlers. All opened handles must be registered in here
- )
- func StorageInit() {
- //Load the default handler for the user storage root
- if !fileExists(filepath.Clean(*root_directory) + "/") {
- os.MkdirAll(filepath.Clean(*root_directory)+"/", 0755)
- }
- //Start loading the base storage pool
- err := LoadBaseStoragePool()
- if err != nil {
- panic(err)
- }
- }
- func LoadBaseStoragePool() error {
- //Use for Debian buster local file system
- localFileSystem := "ext4"
- if runtime.GOOS == "windows" {
- localFileSystem = "ntfs"
- }
- baseHandler, err := fs.NewFileSystemHandler(fs.FileSystemOption{
- Name: "User",
- Uuid: "user",
- Path: filepath.ToSlash(filepath.Clean(*root_directory)) + "/",
- Hierarchy: "user",
- Automount: false,
- Filesystem: localFileSystem,
- })
- if err != nil {
- log.Println("Failed to initiate user root storage directory: " + *root_directory)
- return err
- }
- fsHandlers = append(fsHandlers, baseHandler)
- //Load the tmp folder as storage unit
- tmpHandler, err := fs.NewFileSystemHandler(fs.FileSystemOption{
- Name: "tmp",
- Uuid: "tmp",
- Path: filepath.ToSlash(filepath.Clean(*tmp_directory)) + "/",
- Hierarchy: "user",
- Automount: false,
- Filesystem: localFileSystem,
- })
- if err != nil {
- log.Println("Failed to initiate tmp storage directory: " + *tmp_directory)
- return err
- }
- fsHandlers = append(fsHandlers, tmpHandler)
- //Load all the storage config from file
- rawConfig, err := ioutil.ReadFile(*storage_config_file)
- if err != nil {
- //File not found. Use internal storage only
- log.Println("Storage configuration file not found. Using internal storage only.")
- } else {
- //Configuration loaded. Initializing handler
- externalHandlers, err := fs.NewFileSystemHandlersFromJSON(rawConfig)
- if err != nil {
- log.Println("Failed to load storage configuration: " + err.Error() + " -- Skipping")
- } else {
- for _, thisHandler := range externalHandlers {
- fsHandlers = append(fsHandlers, thisHandler)
- log.Println(thisHandler.Name + " Mounted as " + thisHandler.UUID + ":/")
- }
- }
- }
- //Create a base storage pool for all users
- sp, err := storage.NewStoragePool(fsHandlers, "system")
- if err != nil {
- log.Println("Failed to create base Storaeg Pool")
- return err
- }
- //Update the storage pool permission to readwrite
- sp.OtherPermission = "readwrite"
- baseStoragePool = sp
- return nil
- }
- /*
- Initiate the backup handlers for backup drives
- This function must be called after the scheduler initiated.
- */
- func FilesystemDaemonInit() {
- for _, thisHandler := range fsHandlers {
- if thisHandler.Hierarchy == "backup" {
- //This is a backup drive. Generate it handler
- backupConfig := thisHandler.HierarchyConfig.(hybridBackup.BackupConfig)
- systemScheduler.CreateNewScheduledFunctionJob("backup-daemon ["+thisHandler.UUID+"]",
- "Backup daemon from "+backupConfig.ParentUID+":/ to "+backupConfig.DiskUID+":/",
- 60,
- func() (string, error) {
- return hybridBackup.HandleBackupProcess(&backupConfig)
- },
- )
- }
- //Add other type of handler here
- }
- }
- //Initialize group storage pool
- func GroupStoragePoolInit() {
- //Mount permission groups
- for _, pg := range permissionHandler.PermissionGroups {
- //For each group, check does this group has a config file
- err := LoadStoragePoolForGroup(pg)
- if err != nil {
- continue
- }
- //Do something else, WIP
- }
- //Start editing interface for Storage Pool Editor
- StoragePoolEditorInit()
- }
- func LoadStoragePoolForGroup(pg *permission.PermissionGroup) error {
- expectedConfigPath := "./system/storage/" + pg.Name + ".json"
- if fileExists(expectedConfigPath) {
- //Read the config file
- pgStorageConfig, err := ioutil.ReadFile(expectedConfigPath)
- if err != nil {
- log.Println("Failed to read config for " + pg.Name + ": " + err.Error())
- return errors.New("Failed to read config for " + pg.Name + ": " + err.Error())
- }
- //Generate fsHandler form json
- thisGroupFsHandlers, err := fs.NewFileSystemHandlersFromJSON(pgStorageConfig)
- if err != nil {
- log.Println("Failed to load storage configuration: " + err.Error())
- return errors.New("Failed to load storage configuration: " + err.Error())
- }
- //Add these to mounted handlers
- for _, thisHandler := range thisGroupFsHandlers {
- fsHandlers = append(fsHandlers, thisHandler)
- log.Println(thisHandler.Name + " Mounted as " + thisHandler.UUID + ":/ for group " + pg.Name)
- }
- //Create a storage pool from these handlers
- sp, err := storage.NewStoragePool(thisGroupFsHandlers, pg.Name)
- if err != nil {
- log.Println("Failed to create storage pool for " + pg.Name)
- return errors.New("Failed to create storage pool for " + pg.Name)
- }
- //Set other permission to denied by default
- sp.OtherPermission = "denied"
- //Assign storage pool to group
- pg.StoragePool = sp
- } else {
- //Storage configuration not exists. Fill in the basic information and move to next storage pool
- pg.StoragePool.Owner = pg.Name
- pg.StoragePool.OtherPermission = "denied"
- }
- return nil
- }
- func RegisterStorageSettings() {
- //Storage Pool Configuration
- registerSetting(settingModule{
- Name: "Storage Pools",
- Desc: "Storage Pool Mounting Configuration",
- IconPath: "SystemAO/disk/smart/img/small_icon.png",
- Group: "Disk",
- StartDir: "SystemAO/storage/poolList.html",
- RequireAdmin: true,
- })
- }
- //CloseAllStorages Close all storage database
- func CloseAllStorages() {
- for _, fsh := range fsHandlers {
- fsh.FilesystemDatabase.Close()
- }
- }
|