ソースを参照

Added backup core script (WIP)

TC pushbot 5 4 年 前
コミット
6f201462d8

+ 53 - 0
backup.go

@@ -0,0 +1,53 @@
+package main
+
+import (
+	"encoding/json"
+	"net/http"
+
+	prout "imuslab.com/arozos/mod/prouter"
+)
+
+func backup_init() {
+	//Register HybridBackup storage restore endpoints
+	router := prout.NewModuleRouter(prout.RouterOption{
+		AdminOnly:   false,
+		UserHandler: userHandler,
+		DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
+			sendErrorResponse(w, "Permission Denied")
+		},
+	})
+
+	router.HandleFunc("/system/backup/listRestorable", backup_listRestorable)
+}
+
+func backup_listRestorable(w http.ResponseWriter, r *http.Request) {
+	//Get user accessiable storage pools
+	userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
+	if err != nil {
+		sendErrorResponse(w, "User not logged in")
+		return
+	}
+
+	//Get Vroot ID from request
+	vroot, err := mv(r, "vroot", false)
+	if err != nil {
+		sendErrorResponse(w, "Invalid vroot given")
+		return
+	}
+
+	//Get fsh from the id
+	fsh, err := GetFsHandlerByUUID(vroot)
+	if err != nil {
+		sendErrorResponse(w, err.Error())
+	}
+
+	//Get the user's storage pool and list restorable by the user's storage pool access
+	restorableReport, err := userinfo.HomeDirectories.HyperBackupManager.ListRestorable(fsh.UUID)
+	if err != nil {
+		sendErrorResponse(w, err.Error())
+		return
+	}
+
+	js, _ := json.Marshal(restorableReport)
+	sendJSONResponse(w, string(js))
+}

+ 35 - 0
mod/disk/hybridBackup/compareRoots.go

@@ -0,0 +1,35 @@
+package hybridBackup
+
+import (
+	"log"
+	"path/filepath"
+	"strings"
+)
+
+/*
+	Compare roots
+
+	This script compare the files between two folder recursively
+
+*/
+
+//This function check which file exists in backup but not source drive
+func (t *BackupTask) compareRootPaths() ([]*RestorableFile, error) {
+	results := []*RestorableFile{}
+
+	//Check if the source and the backup disk exists
+	fastWalk(t.DiskPath, func(filename string) error {
+		rootAbs, _ := filepath.Abs(t.DiskPath)
+		fileAbs, _ := filepath.Abs(filename)
+
+		rootAbs = filepath.ToSlash(filepath.Clean(rootAbs))
+		fileAbs = filepath.ToSlash(filepath.Clean(fileAbs))
+
+		relPath := strings.ReplaceAll(fileAbs, rootAbs, "")
+		assumedTargetPosition := filepath.Join(t.ParentPath, relPath)
+		log.Println(assumedTargetPosition)
+		return nil
+	})
+
+	return results, nil
+}

+ 5 - 0
mod/disk/hybridBackup/handlers.go

@@ -0,0 +1,5 @@
+package hybridBackup
+
+func HandleRestorableList() {
+
+}

+ 68 - 9
mod/disk/hybridBackup/hybridBackup.go

@@ -44,6 +44,7 @@ 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
@@ -56,14 +57,15 @@ type BackupTask struct {
 type RestorableFile struct {
 	Filename      string //Filename of this restorable object
 	RelpathOnDisk string //Relative path of this file to the root
-	Deleteime     int64  //Delete remaining time
+	BackupDiskUID string //The UID of disk that is hold the backup of this file
+	RemainingTime int64  //Remaining time till auto remove
+	Deleteime     int64  //Delete time
 }
 
 //The restorable report
 type RestorableReport struct {
-	ParentUID       string           //The Disk ID to be restored to
-	DiskUID         string           //The Backup disk UID
-	RestorableFiles []RestorableFile //A list of restorable files
+	ParentUID       string            //The Disk ID to be restored to
+	RestorableFiles []*RestorableFile //A list of restorable files
 }
 
 var (
@@ -88,7 +90,9 @@ func NewHyperBackupManager() *Manager {
 			select {
 			case <-ticker.C:
 				for _, task := range newManager.Tasks {
-					task.HandleBackupProcess()
+					if task.Enabled == true {
+						task.HandleBackupProcess()
+					}
 				}
 			case <-stopper:
 				return
@@ -111,15 +115,33 @@ func (m *Manager) AddTask(newtask *BackupTask) error {
 		}
 	}
 
+	//Add task to list
 	m.Tasks = append(m.Tasks, newtask)
 
+	//Start the task
+	m.StartTask(newtask.JobName)
+
 	log.Println(">>>> [Debug] New Backup Tasks added: ", newtask.JobName, newtask)
 
 	return nil
 }
 
-func (m *Manager) StopTask(jobname string) error {
-	return nil
+//Start a given task given name
+func (m *Manager) StartTask(jobname string) {
+	for _, task := range m.Tasks {
+		if task.JobName == jobname {
+			task.Enabled = true
+		}
+	}
+}
+
+//Stop a given task given its job name
+func (m *Manager) StopTask(jobname string) {
+	for _, task := range m.Tasks {
+		if task.JobName == jobname {
+			task.Enabled = false
+		}
+	}
 }
 
 //Stop all managed handlers
@@ -335,8 +357,45 @@ func HandleRestore(parentDiskID string, restoreDiskID string, targetFileRelpath
 }
 
 //List the file that is restorable from the given disk
-func (m *Manager) ListRestorable(parentDiskID string) RestorableReport {
-	return RestorableReport{}
+func (m *Manager) ListRestorable(parentDiskID string) (RestorableReport, error) {
+	//List all the backup process that is mirroring this parent disk
+	tasks := m.getTaskByParentDiskID(parentDiskID)
+	if len(tasks) == 0 {
+		return RestorableReport{}, errors.New("No backup root found for this " + parentDiskID + ":/ virtual root.")
+	}
+
+	diffFiles := []*RestorableFile{}
+
+	//Extract all comparasion
+	for _, task := range tasks {
+		restorableFiles, err := task.compareRootPaths()
+		if err != nil {
+			//Unable to list restorable. SKip this
+		} else {
+			for _, restorable := range restorableFiles {
+				diffFiles = append(diffFiles, restorable)
+			}
+		}
+	}
+
+	//Create a Restorable Report
+	thisReport := RestorableReport{
+		ParentUID:       parentDiskID,
+		RestorableFiles: diffFiles,
+	}
+
+	return thisReport, nil
+}
+
+func (m *Manager) getTaskByParentDiskID(parentDiskID string) []*BackupTask {
+	possibleTask := []*BackupTask{}
+	for _, task := range m.Tasks {
+		if task.ParentUID == parentDiskID {
+			//This task parent is the target disk. push this to list
+			possibleTask = append(possibleTask, task)
+		}
+	}
+	return possibleTask
 }
 
 //Get and return the file hash for a file

+ 2 - 1
startup.go

@@ -53,7 +53,7 @@ func RunStartup() {
 	FileSystemInit()    //Start FileSystem
 	DesktopInit()       //Start Desktop
 	HardwarePowerInit() //Start host power manager
-	StorageDaemonInit() //Start File System handler daemon (for backup and other sync process)
+	//StorageDaemonInit() //Start File System handler daemon (for backup and other sync process)
 
 	//8 Start AGI and Subservice modules (Must start after module)
 	AGIInit()        //ArOZ Javascript Gateway Interface, must start after fs
@@ -83,6 +83,7 @@ func RunStartup() {
 	system_resetpw_init()
 	mediaServer_init()
 	security_init()
+	backup_init()
 
 	//Start High Level Services that requires full arozos architectures
 	FTPServerInit() //Start FTP Server Endpoints

+ 0 - 9
storage.go

@@ -103,15 +103,6 @@ func LoadBaseStoragePool() error {
 	return nil
 }
 
-/*
-	Initiate the backup handlers for backup drives
-
-	This function must be called after the scheduler initiated.
-*/
-func StorageDaemonInit() {
-
-}
-
 //Initialize group storage pool
 func GroupStoragePoolInit() {
 	//Mount permission groups