package hybridBackup import ( "log" "path/filepath" "strings" "time" ) /* Hybrid Backup This module handle backup functions from the drive with Hieracchy labeled as "backup" Backup modes suport in this module currently consists of Denote P drive as parent drive and B drive as backup drive. 1. Smart (smart): - Any new file created in P will be copied to B within 5 minutes - Any file removed in P will be delete from backup after 24 hours 2. Nightly (nightly): - The whole P drive will be copied to N drive every night 3. Append Only (append) - Any new file created in P will be copied to B within 5 minutes - No file will be removed from B unless drive is fulled (Similar to CCTV recorder) */ type BackupConfig struct { CycleCounter int64 //The number of backup executed in the background LastCycleTime int64 //The execution time of the last cycle 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 Mode string //Backup mode } //Main handler function for hybrid backup func HandleBackupProcess(backupConfig *BackupConfig) (string, error) { log.Println(">>>>>> Running backup process: ", backupConfig) rootPath := filepath.ToSlash(filepath.Clean(backupConfig.ParentPath)) //Check if the target disk is writable and mounted if fileExists(filepath.Join(backupConfig.DiskPath, "aofs.db")) && fileExists(filepath.Join(backupConfig.DiskPath, "aofs.db.lock")) { //This filesystem is mounted } else { //File system not mounted. Skipping log.Println("*HybridBackup* Skipping backup cycle for " + backupConfig.ParentUID + ":/") return "Parent drive (" + backupConfig.ParentUID + ":/) not mounted. Skipping", nil } if backupConfig.Mode == "smart" { //Smart backup mode. Scan new files every minutes and compare creation time scan every hour minutes if backupConfig.CycleCounter%5 == 0 { //Perform deep backup, use walk function } else { //Perform shallow backup fastWalk(rootPath, func(filename string) error { rootAbs, _ := filepath.Abs(rootPath) fileAbs, _ := filepath.Abs(filename) rootAbs = filepath.ToSlash(filepath.Clean(rootAbs)) fileAbs = filepath.ToSlash(filepath.Clean(fileAbs)) relPath := strings.ReplaceAll(fileAbs, rootAbs, "") assumedTargetPosition := filepath.Join(backupConfig.DiskPath, relPath) if !fileExists(assumedTargetPosition) { //Target file not exists in backup disk. Make a copy //WIP log.Println("Copying ", assumedTargetPosition) } return nil }) } } else if backupConfig.Mode == "nightly" { } else if backupConfig.Mode == "append" { } //Add one to the cycle counter backupConfig.CycleCounter++ backupConfig.LastCycleTime = time.Now().Unix() //Return the log information return "", nil }