Browse Source

Fixed a lot of bugs

TC pushbot 5 4 years ago
parent
commit
fe8374e19b

+ 2 - 0
main.flags.go

@@ -3,6 +3,7 @@ package main
 import (
 	"flag"
 	"os"
+	"time"
 
 	apt "imuslab.com/arozos/mod/apt"
 	auth "imuslab.com/arozos/mod/auth"
@@ -39,6 +40,7 @@ var iconSystem = "img/vendor/system_icon.png"          //System icon location
 // =========== RUNTTIME RELATED ================S
 var max_upload_size int64 = 8192 << 20                         //Maxmium upload size, default 8GB
 var sudo_mode bool = (os.Geteuid() == 0 || os.Geteuid() == -1) //Check if the program is launched as sudo mode or -1 on windows
+var startupTime int64 = time.Now().Unix()                      //The startup time of the ArozOS Core
 
 // =========== SYSTEM FLAGS ==============
 //Flags related to System startup

+ 3 - 3
main.go

@@ -41,9 +41,9 @@ func executeShutdownSequence() {
 	log.Println("\r- Shutting down auth gateway")
 	authAgent.Close()
 
-	//Shutdown file system handler db
-	log.Println("\r- Shutting down fsdb")
-	CloseAllStorages()
+	//Shutdown all storage pools
+	log.Println("\r- Shutting down storage pools")
+	closeAllStoragePools()
 
 	//Shutdown Subservices
 	log.Println("\r- Shutting down background subservices")

+ 53 - 40
mod/disk/hybridBackup/basicBackup.go

@@ -15,6 +15,8 @@ import (
 	This script handle basic backup process
 */
 
+var autoDeleteTime int64 = 86400 * 30
+
 func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
 	copiedFileList := []string{}
 
@@ -34,14 +36,15 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
 	if len(parentRootAbs) >= len(backupRootAbs) {
 		if parentRootAbs[:len(backupRootAbs)] == backupRootAbs {
 			//parent root is within backup root. Raise configuration error
-			log.Println("*HyperBackup* Invalid backup cycle: Parent drive is located inside backup drive")
+			log.Println("[HyperBackup] Invalid backup cycle: Parent drive is located inside backup drive")
 			return "", errors.New("Configuration Error. Skipping backup cycle.")
 		}
 	}
 
 	//Add file cycles
+	//log.Println("[Debug] Cycle 1: Adding files")
 	fastWalk(rootPath, func(filename string) error {
-		if filepath.Base(filename) == "aofs.db" || filepath.Base(filename) == "aofs.db.lock" {
+		if filepath.Ext(filename) == ".db" || filepath.Ext(filename) == ".lock" {
 			//Reserved filename, skipping
 			return nil
 		}
@@ -110,7 +113,7 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
 					}
 
 					if srcHash != targetHash {
-						log.Println("[Debug] Hash mismatch. Copying ", fileAbs)
+						//log.Println("[Debug] Hash mismatch. Copying ", fileAbs)
 						//This file has been recently changed. Copy it to new location
 						err = BufferedLargeFileCopy(fileAbs, assumedTargetPosition, 1024)
 						if err != nil {
@@ -125,6 +128,7 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
 						if ok {
 							//File exists. remove it from delete file amrker
 							delete(backupConfig.DeleteFileMarkers, relPath)
+							backupConfig.Database.Delete("DeleteMarkers", relPath)
 							log.Println("Removing ", relPath, " from delete marker list")
 						}
 					}
@@ -133,47 +137,56 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
 			}
 		}
 
-		///Remove file cycle
-		backupDriveRootPath := filepath.ToSlash(filepath.Clean(filepath.Join(backupConfig.DiskPath, "/backup/")))
-		fastWalk(backupConfig.DiskPath, func(filename string) error {
-			if filepath.Base(filename) == "aofs.db" || filepath.Base(filename) == "aofs.db.lock" {
-				//Reserved filename, skipping
-				return nil
-			}
-			//Get the target paste location
-			rootAbs, _ := filepath.Abs(backupDriveRootPath)
-			fileAbs, _ := filepath.Abs(filename)
-
-			rootAbs = filepath.ToSlash(filepath.Clean(rootAbs))
-			fileAbs = filepath.ToSlash(filepath.Clean(fileAbs))
-
-			thisFileRel := filename[len(backupDriveRootPath):]
-			originalFileOnDiskPath := filepath.ToSlash(filepath.Clean(filepath.Join(backupConfig.ParentPath, thisFileRel)))
-
-			//Check if the taget file not exists and this file has been here for more than 24h
-			if !fileExists(originalFileOnDiskPath) {
-				//This file not exists. Check if it is in the delete file marker for more than 24 hours
-				val, ok := backupConfig.DeleteFileMarkers[thisFileRel]
-				if !ok {
-					//This file is newly deleted. Push into the marker map
-					backupConfig.DeleteFileMarkers[thisFileRel] = time.Now().Unix()
-					log.Println("[Debug] Adding " + filename + " to delete marker")
-				} else {
-					//This file has been marked. Check if it is time to delete
-					if time.Now().Unix()-val > 3600*24 {
-						log.Println("[Debug] Deleting " + filename)
+		return nil
+	})
 
-						//Remove the backup file
-						os.RemoveAll(filename)
+	///Remove file cycle
+	//log.Println("[Debug] Cycle 2: Removing files")
+	backupDriveRootPath := filepath.ToSlash(filepath.Clean(filepath.Join(backupConfig.DiskPath, "/backup/")))
+	fastWalk(backupConfig.DiskPath, func(filename string) error {
+		if filepath.Ext(filename) == ".db" || filepath.Ext(filename) == ".lock" {
+			//Reserved filename, skipping
+			return nil
+		}
+		//Get the target paste location
+		rootAbs, _ := filepath.Abs(backupDriveRootPath)
+		fileAbs, _ := filepath.Abs(filename)
 
-						//Remove file from delete file markers
-						delete(backupConfig.DeleteFileMarkers, thisFileRel)
-					}
+		rootAbs = filepath.ToSlash(filepath.Clean(rootAbs))
+		fileAbs = filepath.ToSlash(filepath.Clean(fileAbs))
+
+		thisFileRel := filename[len(backupDriveRootPath):]
+		originalFileOnDiskPath := filepath.ToSlash(filepath.Clean(filepath.Join(backupConfig.ParentPath, thisFileRel)))
+
+		//Check if the taget file not exists and this file has been here for more than 24h
+		if !fileExists(originalFileOnDiskPath) {
+			//This file not exists. Check if it is in the delete file marker for more than 24 hours
+			val, ok := backupConfig.DeleteFileMarkers[thisFileRel]
+			if !ok {
+				//This file is newly deleted. Push into the marker map
+				deleteTime := time.Now().Unix()
+				backupConfig.DeleteFileMarkers[thisFileRel] = deleteTime
+
+				//Write the delete marker to database
+				backupConfig.Database.Write("DeleteMarkers", thisFileRel, deleteTime)
+
+				log.Println("[HybridBackup] Adding " + filename + " to delete marker")
+			} else {
+				//This file has been marked for 30 days. Check if it is time to delete
+				if time.Now().Unix()-val > autoDeleteTime {
+					//log.Println("[Debug] Deleting " + filename)
+
+					//Remove the backup file
+					os.RemoveAll(filename)
+
+					//Remove file from delete file markers
+					delete(backupConfig.DeleteFileMarkers, thisFileRel)
+
+					//Remove file from database
+					backupConfig.Database.Delete("DeleteMarkers", thisFileRel)
 				}
 			}
-			return nil
-		})
-
+		}
 		return nil
 	})
 

+ 1 - 1
mod/disk/hybridBackup/compareRoots.go

@@ -45,7 +45,7 @@ func (t *BackupTask) compareRootPaths() ([]*RestorableFile, error) {
 				RelpathOnDisk: filepath.ToSlash(key),
 				RestorePoint:  filepath.ToSlash(assumedSourcePosition),
 				BackupDiskUID: t.DiskUID,
-				RemainingTime: 86400 - (time.Now().Unix() - value),
+				RemainingTime: autoDeleteTime - (time.Now().Unix() - value),
 				DeleteTime:    value,
 				IsSnapshot:    false,
 			}

+ 51 - 12
mod/disk/hybridBackup/hybridBackup.go

@@ -3,6 +3,7 @@ package hybridBackup
 import (
 	"crypto/sha256"
 	"encoding/hex"
+	"encoding/json"
 	"errors"
 	"io"
 	"log"
@@ -10,6 +11,8 @@ import (
 	"path/filepath"
 	"strings"
 	"time"
+
+	"imuslab.com/arozos/mod/database"
 )
 
 /*
@@ -41,16 +44,17 @@ type Manager struct {
 }
 
 type BackupTask struct {
-	JobName           string           //The name used by the scheduler for executing this config
-	CycleCounter      int64            //The number of backup executed in the background
-	LastCycleTime     int64            //The execution time of the last cycle
-	Enabled           bool             //Check if the task is enabled. Will not execute if this is set to false
-	DiskUID           string           //The UID of the target fsandlr
-	DiskPath          string           //The mount point for the disk
-	ParentUID         string           //Parent virtal disk UUID
-	ParentPath        string           //Parent disk path
-	DeleteFileMarkers map[string]int64 //Markers for those files delete pending, [file path (relative)] time
-	Mode              string           //Backup mode
+	JobName           string             //The name used by the scheduler for executing this config
+	CycleCounter      int64              //The number of backup executed in the background
+	LastCycleTime     int64              //The execution time of the last cycle
+	Enabled           bool               //Check if the task is enabled. Will not execute if this is set to false
+	DiskUID           string             //The UID of the target fsandlr
+	DiskPath          string             //The mount point for the disk
+	ParentUID         string             //Parent virtal disk UUID
+	ParentPath        string             //Parent disk path
+	DeleteFileMarkers map[string]int64   //Markers for those files delete pending, [file path (relative)] time
+	Database          *database.Database //The database for storing requried data
+	Mode              string             //Backup mode
 }
 
 //A snapshot summary
@@ -117,7 +121,7 @@ func NewHyperBackupManager() *Manager {
 
 func (m *Manager) AddTask(newtask *BackupTask) error {
 	//Create a job for this
-	newtask.JobName = "backup-[" + newtask.DiskUID + "]"
+	newtask.JobName = "backup-" + newtask.DiskUID + ""
 
 	//Check if the same job name exists
 	for _, task := range m.Tasks {
@@ -126,6 +130,32 @@ func (m *Manager) AddTask(newtask *BackupTask) error {
 		}
 	}
 
+	//Create / Load a backup database for the task
+	dbPath := filepath.Join(newtask.DiskPath, newtask.JobName+".db")
+	thisdb, err := database.NewDatabase(dbPath, false)
+	if err != nil {
+		log.Println("[HybridBackup] Failed to create database for backup tasks. Running without one.")
+	} else {
+		newtask.Database = thisdb
+		thisdb.NewTable("DeleteMarkers")
+	}
+
+	if newtask.Mode == "basic" || newtask.Mode == "nightly" {
+		//Load the delete marker from the database if exists
+		if thisdb.TableExists("DeleteMarkers") {
+			//Table exists. Read all its content to delete markers
+			entries, _ := thisdb.ListTable("DeleteMarkers")
+			for _, keypairs := range entries {
+				relPath := string(keypairs[0])
+				delTime := int64(0)
+				json.Unmarshal(keypairs[1], &delTime)
+
+				//Add this to delete marker
+				newtask.DeleteFileMarkers[relPath] = delTime
+			}
+		}
+	}
+
 	//Add task to list
 	m.Tasks = append(m.Tasks, newtask)
 
@@ -161,10 +191,16 @@ func (m *Manager) StopTask(jobname string) {
 
 //Stop all managed handlers
 func (m *Manager) Close() error {
+	//Stop the schedule
 	if m != nil {
 		m.StopTicker <- true
 	}
 
+	//Close all database opened by backup task
+	for _, task := range m.Tasks {
+		task.Database.Close()
+	}
+
 	return nil
 }
 
@@ -199,7 +235,10 @@ func (backupConfig *BackupTask) HandleBackupProcess() (string, error) {
 
 		//Add one to the cycle counter
 		backupConfig.CycleCounter++
-		executeBackup(backupConfig, deepBackup)
+		_, err := executeBackup(backupConfig, deepBackup)
+		if err != nil {
+			log.Println("[HybridBackup] Backup failed: " + err.Error())
+		}
 	} else if backupConfig.Mode == "nightly" {
 		if time.Now().Unix()-backupConfig.LastCycleTime >= 86400 {
 			//24 hours from last backup. Execute deep backup now

+ 0 - 1
mod/filesystem/filesystem.go

@@ -119,7 +119,6 @@ func NewFileSystemHandler(option FileSystemOption) (*FileSystemHandler, error) {
 			}
 
 		}
-
 		//Create the fsdb for this handler
 		fsdb, err := db.NewDatabase(filepath.ToSlash(filepath.Join(filepath.Clean(option.Path), "aofs.db")), false)
 		if err != nil {

+ 3 - 2
mod/storage/storage.go

@@ -100,13 +100,14 @@ func (s *StoragePool) HasHigherOrEqualPermissionThan(a *StoragePool) bool {
 
 //Close all fsHandler under this storage pool
 func (s *StoragePool) Close() {
+	//Close the running backup tasks
+	s.HyperBackupManager.Close()
+
 	//For each storage pool, close it
 	for _, fsh := range s.Storages {
 		fsh.Close()
 	}
 
-	//Close the running backup tasks
-	s.HyperBackupManager.Close()
 }
 
 //Helper function

+ 13 - 0
storage.go

@@ -18,6 +18,7 @@ import (
 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
+	storagePools    []*storage.StoragePool  //All Storage pool opened
 )
 
 func StorageInit() {
@@ -97,6 +98,9 @@ func LoadBaseStoragePool() error {
 		return err
 	}
 
+	//Push base pool into the opened storage pool list
+	storagePools = append(storagePools, sp)
+
 	//Update the storage pool permission to readwrite
 	sp.OtherPermission = "readwrite"
 	baseStoragePool = sp
@@ -156,11 +160,14 @@ func LoadStoragePoolForGroup(pg *permission.PermissionGroup) error {
 
 		//Assign storage pool to group
 		pg.StoragePool = sp
+
+		storagePools = append(storagePools, 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
 }
 
@@ -198,3 +205,9 @@ func CloseAllStorages() {
 		fsh.FilesystemDatabase.Close()
 	}
 }
+
+func closeAllStoragePools() {
+	for _, sp := range storagePools {
+		sp.Close()
+	}
+}

+ 11 - 1
web/SystemAO/disk/disk_restore.html

@@ -244,7 +244,17 @@
 
             var hDisplay = h > 0 ? h.toString().padStart(2, "0") + (h == 1 ? " hour, " : " hours, ") : "";
             var mDisplay = m > 0 ? m.toString().padStart(2, "0") + (m == 1 ? " minute, " : " minutes") : "";
-            return hDisplay + mDisplay; 
+            
+            if (h > 24){
+                var days = Math.floor(h/24);
+                days = days + (days == 1 ? " day, " : " days, ")
+                var hours = h % 24 + (h == 1 ? " hour, " : " hours, ");
+                return days + hours + mDisplay; 
+            } else{
+                return hDisplay + mDisplay; 
+            }
+            
+            
         }
 
         function timeConverter(UNIX_timestamp){