|
@@ -35,7 +35,9 @@ import (
|
|
*/
|
|
*/
|
|
|
|
|
|
type Manager struct {
|
|
type Manager struct {
|
|
- Tasks []*BackupTask
|
|
|
|
|
|
+ Ticker *time.Ticker //The main ticker
|
|
|
|
+ StopTicker chan bool //Channel for stopping the backup
|
|
|
|
+ Tasks []*BackupTask //The backup tasks that is running under this manager
|
|
}
|
|
}
|
|
|
|
|
|
type BackupTask struct {
|
|
type BackupTask struct {
|
|
@@ -64,52 +66,65 @@ type RestorableReport struct {
|
|
RestorableFiles []RestorableFile //A list of restorable files
|
|
RestorableFiles []RestorableFile //A list of restorable files
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+var (
|
|
|
|
+ internalTickerTime time.Duration = 60
|
|
|
|
+)
|
|
|
|
+
|
|
func NewHyperBackupManager() *Manager {
|
|
func NewHyperBackupManager() *Manager {
|
|
- return &Manager{
|
|
|
|
- Tasks: []*BackupTask{},
|
|
|
|
|
|
+ //Create a new minute ticker
|
|
|
|
+ ticker := time.NewTicker(internalTickerTime * time.Second)
|
|
|
|
+ stopper := make(chan bool, 1)
|
|
|
|
+
|
|
|
|
+ newManager := &Manager{
|
|
|
|
+ Ticker: ticker,
|
|
|
|
+ StopTicker: stopper,
|
|
|
|
+ Tasks: []*BackupTask{},
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
-func (m *Manager) AddTask(newtask *BackupTask) error {
|
|
|
|
- log.Println(">>>> [Debug] New Backup Tasks added: ", newtask)
|
|
|
|
-
|
|
|
|
- /*for _, thisHandler := range fsHandlers {
|
|
|
|
|
|
+ ///Create task executor
|
|
|
|
+ go func() {
|
|
|
|
+ defer log.Println("[HybridBackup] Ticker Stopped")
|
|
|
|
+ for {
|
|
|
|
+ select {
|
|
|
|
+ case <-ticker.C:
|
|
|
|
+ for _, task := range newManager.Tasks {
|
|
|
|
+ task.HandleBackupProcess()
|
|
|
|
+ }
|
|
|
|
+ case <-stopper:
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }()
|
|
|
|
|
|
- if thisHandler.Hierarchy == "backup" {
|
|
|
|
- //This is a backup drive. Generate it handler
|
|
|
|
- backupConfig := thisHandler.HierarchyConfig.(hybridBackup.BackupTask)
|
|
|
|
|
|
+ //Return the manager
|
|
|
|
+ return newManager
|
|
|
|
+}
|
|
|
|
|
|
- //Get its parent mount point for backup
|
|
|
|
- parentFileSystemHandler, err := GetFsHandlerByUUID(backupConfig.ParentUID)
|
|
|
|
- if err != nil {
|
|
|
|
- log.Println("Virtual Root with UUID: " + backupConfig.ParentUID + " not loaded. Unable to start backup process.")
|
|
|
|
- break
|
|
|
|
- }
|
|
|
|
|
|
+func (m *Manager) AddTask(newtask *BackupTask) error {
|
|
|
|
+ //Create a job for this
|
|
|
|
+ newtask.JobName = "backup-[" + newtask.DiskUID + "]"
|
|
|
|
|
|
- backupConfig.JobName = "backup-daemon [" + thisHandler.UUID + "]"
|
|
|
|
- backupConfig.ParentPath = parentFileSystemHandler.Path
|
|
|
|
- backupConfig.CycleCounter = 1
|
|
|
|
|
|
+ //Check if the same job name exists
|
|
|
|
+ for _, task := range m.Tasks {
|
|
|
|
+ if task.JobName == newtask.JobName {
|
|
|
|
+ return errors.New("Task already exists")
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- //Debug backup execution
|
|
|
|
- hybridBackup.HandleBackupProcess(&backupConfig)
|
|
|
|
|
|
+ m.Tasks = append(m.Tasks, newtask)
|
|
|
|
|
|
- //Remove the previous job if it exists
|
|
|
|
- if systemScheduler.JobExists(backupConfig.JobName) {
|
|
|
|
- systemScheduler.RemoveJobFromScheduleList(backupConfig.JobName)
|
|
|
|
- }
|
|
|
|
|
|
+ log.Println(">>>> [Debug] New Backup Tasks added: ", newtask.JobName, newtask)
|
|
|
|
|
|
- //Create a scheudler for this disk
|
|
|
|
- systemScheduler.CreateNewScheduledFunctionJob(backupConfig.JobName,
|
|
|
|
- "Backup daemon from "+backupConfig.ParentUID+":/ to "+backupConfig.DiskUID+":/",
|
|
|
|
- 60,
|
|
|
|
- func() (string, error) {
|
|
|
|
- return hybridBackup.HandleBackupProcess(&backupConfig)
|
|
|
|
- },
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
|
|
- }*/
|
|
|
|
|
|
+func (m *Manager) StopTask(jobname string) error {
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
|
|
|
|
+//Stop all managed handlers
|
|
|
|
+func (m *Manager) Close() error {
|
|
|
|
+ m.StopTicker <- true
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -166,7 +181,7 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
|
|
//Copy the file to target
|
|
//Copy the file to target
|
|
err := BufferedLargeFileCopy(fileAbs, assumedTargetPosition, 1024)
|
|
err := BufferedLargeFileCopy(fileAbs, assumedTargetPosition, 1024)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Println("*Hybrid Backup* Copy Failed for file "+filepath.Base(fileAbs), err.Error(), " Skipping.")
|
|
|
|
|
|
+ log.Println("[HybridBackup] Copy Failed for file "+filepath.Base(fileAbs), err.Error(), " Skipping.")
|
|
} else {
|
|
} else {
|
|
//No problem. Add this filepath into the list
|
|
//No problem. Add this filepath into the list
|
|
copiedFileList = append(copiedFileList, assumedTargetPosition)
|
|
copiedFileList = append(copiedFileList, assumedTargetPosition)
|
|
@@ -175,10 +190,15 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
|
|
} else {
|
|
} else {
|
|
//Deep copy. Check and match the modtime of each file
|
|
//Deep copy. Check and match the modtime of each file
|
|
if !fileExists(assumedTargetPosition) {
|
|
if !fileExists(assumedTargetPosition) {
|
|
|
|
+ if !fileExists(filepath.Dir(assumedTargetPosition)) {
|
|
|
|
+ //Folder containing this file not exists. Create it
|
|
|
|
+ os.MkdirAll(filepath.Dir(assumedTargetPosition), 0755)
|
|
|
|
+ }
|
|
|
|
+
|
|
//Copy the file to target
|
|
//Copy the file to target
|
|
err := BufferedLargeFileCopy(fileAbs, assumedTargetPosition, 1024)
|
|
err := BufferedLargeFileCopy(fileAbs, assumedTargetPosition, 1024)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Println("*Hybrid Backup* Copy Failed for file "+filepath.Base(fileAbs), err.Error(), " Skipping.")
|
|
|
|
|
|
+ log.Println("[HybridBackup] Copy Failed for file "+filepath.Base(fileAbs), err.Error(), " Skipping.")
|
|
return nil
|
|
return nil
|
|
} else {
|
|
} else {
|
|
//No problem. Add this filepath into the list
|
|
//No problem. Add this filepath into the list
|
|
@@ -188,12 +208,12 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
|
|
//Target file already exists. Check if their hash matches
|
|
//Target file already exists. Check if their hash matches
|
|
srcHash, err := getFileHash(fileAbs)
|
|
srcHash, err := getFileHash(fileAbs)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Println("*Hybrid Backup* Hash calculation failed for file "+filepath.Base(fileAbs), err.Error(), " Skipping.")
|
|
|
|
|
|
+ log.Println("[HybridBackup] Hash calculation failed for file "+filepath.Base(fileAbs), err.Error(), " Skipping.")
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
targetHash, err := getFileHash(assumedTargetPosition)
|
|
targetHash, err := getFileHash(assumedTargetPosition)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Println("*Hybrid Backup* Hash calculation failed for file "+filepath.Base(assumedTargetPosition), err.Error(), " Skipping.")
|
|
|
|
|
|
+ log.Println("[HybridBackup] Hash calculation failed for file "+filepath.Base(assumedTargetPosition), err.Error(), " Skipping.")
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -202,7 +222,7 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
|
|
//This file has been recently changed. Copy it to new location
|
|
//This file has been recently changed. Copy it to new location
|
|
err = BufferedLargeFileCopy(fileAbs, assumedTargetPosition, 1024)
|
|
err = BufferedLargeFileCopy(fileAbs, assumedTargetPosition, 1024)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Println("*Hybrid Backup* Copy Failed for file "+filepath.Base(fileAbs), err.Error(), " Skipping.")
|
|
|
|
|
|
+ log.Println("[HybridBackup] Copy Failed for file "+filepath.Base(fileAbs), err.Error(), " Skipping.")
|
|
} else {
|
|
} else {
|
|
//No problem. Add this filepath into the list
|
|
//No problem. Add this filepath into the list
|
|
copiedFileList = append(copiedFileList, assumedTargetPosition)
|
|
copiedFileList = append(copiedFileList, assumedTargetPosition)
|
|
@@ -259,7 +279,7 @@ func executeBackup(backupConfig *BackupTask, deepBackup bool) (string, error) {
|
|
}
|
|
}
|
|
|
|
|
|
//Main handler function for hybrid backup
|
|
//Main handler function for hybrid backup
|
|
-func HandleBackupProcess(backupConfig *BackupTask) (string, error) {
|
|
|
|
|
|
+func (backupConfig *BackupTask) HandleBackupProcess() (string, error) {
|
|
log.Println(">>>>>> [Debug] Running backup process: ", backupConfig)
|
|
log.Println(">>>>>> [Debug] Running backup process: ", backupConfig)
|
|
|
|
|
|
//Check if the target disk is writable and mounted
|
|
//Check if the target disk is writable and mounted
|
|
@@ -268,13 +288,13 @@ func HandleBackupProcess(backupConfig *BackupTask) (string, error) {
|
|
|
|
|
|
} else {
|
|
} else {
|
|
//File system not mounted even after 3 backup cycle. Terminate backup scheduler
|
|
//File system not mounted even after 3 backup cycle. Terminate backup scheduler
|
|
- log.Println("*HybridBackup* Skipping backup cycle for " + backupConfig.ParentUID + ":/")
|
|
|
|
|
|
+ log.Println("[HybridBackup] Skipping backup cycle for " + backupConfig.ParentUID + ":/")
|
|
return "Parent drive (" + backupConfig.ParentUID + ":/) not mounted", nil
|
|
return "Parent drive (" + backupConfig.ParentUID + ":/) not mounted", nil
|
|
}
|
|
}
|
|
|
|
|
|
//Check if the backup disk is mounted. If no, stop the scheulder
|
|
//Check if the backup disk is mounted. If no, stop the scheulder
|
|
if backupConfig.CycleCounter > 3 && !(fileExists(filepath.Join(backupConfig.DiskPath, "aofs.db")) && fileExists(filepath.Join(backupConfig.DiskPath, "aofs.db.lock"))) {
|
|
if backupConfig.CycleCounter > 3 && !(fileExists(filepath.Join(backupConfig.DiskPath, "aofs.db")) && fileExists(filepath.Join(backupConfig.DiskPath, "aofs.db.lock"))) {
|
|
- log.Println("*HybridBackup* Backup schedule stopped for " + backupConfig.DiskUID + ":/")
|
|
|
|
|
|
+ log.Println("[HybridBackup] Backup schedule stopped for " + backupConfig.DiskUID + ":/")
|
|
return "Backup drive (" + backupConfig.DiskUID + ":/) not mounted", errors.New("Backup File System Handler not mounted")
|
|
return "Backup drive (" + backupConfig.DiskUID + ":/) not mounted", errors.New("Backup File System Handler not mounted")
|
|
}
|
|
}
|
|
|
|
|
|
@@ -309,14 +329,14 @@ func HandleBackupProcess(backupConfig *BackupTask) (string, error) {
|
|
}
|
|
}
|
|
|
|
|
|
//Restore accidentailly removed file from backup
|
|
//Restore accidentailly removed file from backup
|
|
-func HandleRestore(backupConfig *BackupTask, targetFile string) error {
|
|
|
|
|
|
+func HandleRestore(parentDiskID string, restoreDiskID string, targetFileRelpath string) error {
|
|
|
|
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
//List the file that is restorable from the given disk
|
|
//List the file that is restorable from the given disk
|
|
-func ListRestorable(backupConfig *BackupTask) {
|
|
|
|
-
|
|
|
|
|
|
+func (m *Manager) ListRestorable(parentDiskID string) RestorableReport {
|
|
|
|
+ return RestorableReport{}
|
|
}
|
|
}
|
|
|
|
|
|
//Get and return the file hash for a file
|
|
//Get and return the file hash for a file
|