func cmd_ArchivedList(w http.ResponseWriter, r *http.Request, plan core.BackupPlan) { err := indexLocalFiles(plan.Name) if err != nil { fmt.Fprintf(w, "Error occured while indexing local files of plan \"%s\": %v", plan.Name, err) return } localFiles := localFilesIndexByPlan[plan.Name] basePath := r.FormValue("basePath") archivedNodesMap := plan.GetArchivedNodesAllRevMap() workPathArchivedNodesMap := make(map[string]*NodeMetaInfoUI) for p, nodes := range archivedNodesMap { if basePath != "" && !base.IsPathInBasePath(basePath, p) { continue } flPath := base.GetFirstLevelPath(basePath, p) if flPath != "" { nodeUI, exists := workPathArchivedNodesMap[flPath] if !exists { nodeUI = &NodeMetaInfoUI{ Path: flPath, IsDir: nodes[0].IsDir() || flPath != p, } workPathArchivedNodesMap[flPath] = nodeUI } d, f := filepath.Split(nodeUI.Path) if f == "" { nodeUI.ShortPath = d } else { nodeUI.ShortPath = f } for i, node := range nodes { nodeUI.AllRevSize += node.Size() if i == len(nodes)-1 { nodeUI.LastRevSize += node.Size() if _, exists := localFiles[node.GetNodePath()]; !exists { nodeUI.LocalDeletedSize += node.Size() } } } } } workPathArchivedNodes := NodeMetaInfoUIList{} for _, nodeUI := range workPathArchivedNodesMap { workPathArchivedNodes = append(workPathArchivedNodes, nodeUI) } sort.Sort(workPathArchivedNodes) basePathList := []map[string]string{} basePathList = append(basePathList, map[string]string{ "Path": "", "ShortPath": "root", }) if basePath != "" { parts := strings.Split(basePath, string(filepath.Separator)) for i, part := range parts { if part == "" { continue } p := make(map[string]string) p["Path"] = filepath.Clean(strings.Join(parts[0:i+1], string(filepath.Separator)) + string(filepath.Separator)) p["ShortPath"] = part basePathList = append(basePathList, p) } } tplData := struct { PlanName string PathSeparator string NodesList []*NodeMetaInfoUI BasePathList []map[string]string }{} tplData.PlanName = plan.Name tplData.PathSeparator = string(filepath.Separator) tplData.NodesList = workPathArchivedNodes tplData.BasePathList = basePathList tplFuncMap := template.FuncMap{ "filesizeHumanView": filesizeHumanView, } t, err := template.New("archived_list").Funcs(tplFuncMap).Parse(getTemplateSrc(templatesPath + "/archived_list.html")) if err != nil { fmt.Fprintf(w, "Error occured while parsing template: %v", err) return } err = t.Execute(w, tplData) if err != nil { fmt.Fprintf(w, "Error occured while parsing template: %v", err) return } }
func (plan BackupPlan) InitRestore(pathList []string, restorePoint *ArchiveMetafile, targetPath string) error { base.Log.Printf("Start initialize data restore for plan: %v\n", plan.Name) if targetPath != OriginTargetPath { tps, err := os.Stat(targetPath) if err != nil || !tps.IsDir() || !filepath.IsAbs(targetPath) { return fmt.Errorf("Target path should be absolute path to existing directory") } } if restorePoint != nil && restorePoint.GetMetaFileId() == 0 { return fmt.Errorf("Restore point is not defined") } // pathes founded in archives pathFounded := make(map[string]bool) nodesRegistered := make(map[string]bool) archNodesToRestore := make(map[string][]NodeMetaInfo) // clear path list from subpathes of each other for i := range pathList { pathList[i] = filepath.Clean(pathList[i]) } pathListUniq := []string{} for i, pathToCheck := range pathList { isSubPath := false for j, path := range pathList { if i == j { continue } if base.IsPathInBasePath(path, pathToCheck) { isSubPath = true break } } if !isSubPath { pathListUniq = append(pathListUniq, pathToCheck) } } metaFiles := plan.GetMetaFiles() restorePointOk := false for i := len(metaFiles) - 1; i >= 0; i-- { mf := plan.GetMetaFile(metaFiles[i]) if !restorePointOk && restorePoint != nil && mf.GetMetaFileId() != restorePoint.GetMetaFileId() { continue } restorePointOk = true nodesToRestore := make([]NodeMetaInfo, 0) for _, node := range mf.GetNodes() { if nodesRegistered[node.GetNodePath()] { continue } for _, path := range pathListUniq { if node.isNodeInPath(path) { nodesRegistered[node.GetNodePath()] = true nodesToRestore = append(nodesToRestore, node) pathFounded[path] = true break } } } if len(nodesToRestore) > 0 { archNodesToRestore[mf.GetMetaFileNameId()] = nodesToRestore } } // check for nothing to restore at all if len(archNodesToRestore) == 0 { return fmt.Errorf("There is nothing to restore by selected pathes") } // check for nothing to restore by path missedPathList := []string{} for _, path := range pathListUniq { if !pathFounded[path] { missedPathList = append(missedPathList, path) } } if len(missedPathList) > 0 { return fmt.Errorf("There is nothing by some of selected pathes: %v", strings.Join(missedPathList, ", ")) } // check locks if plan.CheckOpLocked(restoreOp) { return fmt.Errorf("Restore job is already initialized") } if err := plan.CheckOpLockAllowed("restore"); err != nil { return err } err := plan.SaveRestorePlan(RestorePlan{ TargetPath: targetPath, ArchNodesToRestore: archNodesToRestore, }) if err == nil { base.Log.Printf("Finish initialize data restore for plan: %v\n", plan.Name) } return err }
func (node *NodeMetaInfo) isNodeInPath(path string) bool { return base.IsPathInBasePath(path, node.path) }