func (plan BackupPlan) DoRestore() error { base.Log.Printf("Trying to start restore for plan: %v\n", plan.Name) rplan, err := plan.GetRestorePlan() if err != nil { return err } if err := plan.CreateOpLock("restore"); err != nil { return err } base.Log.Printf("Start doing restore for plan: %v\n", plan.Name) restoredNodes, err := plan.getRestoredNodes() if err != nil { return err } errInProgress := false if err := plan.CheckTmpDir(); err != nil { return err } ARCH_LOOP: for archNameId, nodes := range rplan.ArchNodesToRestore { nodesToRestore := make([]NodeMetaInfo, 0) for _, node := range nodes { if !restoredNodes[node.GetNodePath()] { nodesToRestore = append(nodesToRestore, node) } } if len(nodesToRestore) > 0 { // TODO если восстанавливаются только директории - не качать архив archName := "archive_" + archNameId mf := GetMetaFile(filepath.Join(plan.BaseDir, GetMetaFileName(archName))) archLocalFilePath := filepath.Join(plan.TmpDir, "restore_archive_"+archName+".zip") _, err := os.Stat(archLocalFilePath) if err != nil { if os.IsNotExist(err) { var decrypter *crypter.Decrypter if mf.encrypted { decrypter = crypter.GetDecrypter(plan.Encrypt_passphrase) } base.Log.Printf("Start downloading archive %v\n", archName+".zip") err = plan.Storage.DownloadFile(mf.GetStorageInfo(), archLocalFilePath, decrypter) if err == nil { base.Log.Printf("Finish downloading archive %v\n", archName+".zip") } } if err != nil { if err == base.ErrStorageRequestInProgress { base.Log.Println(err) errInProgress = true continue ARCH_LOOP } else { return err } } } nodesUnarch, err := UnarchiveNodes(archLocalFilePath, nodesToRestore, rplan.TargetPath) if err != nil { return err } fh, err := os.OpenFile(plan.getRestorePlanDoneFilePath(), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { return err } defer fh.Close() for _, node := range nodesUnarch { if _, err := fh.WriteString(node.GetNodePath() + "\r\n"); err != nil { return err } } if err = fh.Close(); err != nil { return err } if err = os.Remove(archLocalFilePath); err != nil { base.LogErr.Println(err) } } } if errInProgress { return base.ErrStorageRequestInProgress } if err = os.Remove(plan.getRestorePlanDoneFilePath()); err != nil { base.LogErr.Println(err) } else if err = os.Remove(plan.getRestorePlanFilePath()); err != nil { base.LogErr.Println(err) } err = plan.RemoveOpLock("restore") if err == nil { base.Log.Printf("Finish doing restore for plan: %v\n", plan.Name) } return err // достаем список уже восстановленных файлов // для каждого архива из файла // - определяем файлы которые еще не восстановили // - скачиваем архив (если еще не скачали) // - восстанавливаем файлы // входные параметры: путь к архиву, список файлов // выходные: список восстановленных файлов, ошибка // если восстанавливаемый файл существует, и совпадает размер и дата - пропускаем (считаем восстановлненным) // - удаляем архив }
func (plan BackupPlan) SyncMeta(cleanLocalMeta bool) error { base.Log.Printf("Trying to sync metafiles from storage for plan: %v\n", plan.Name) syncLocked := plan.CheckOpLocked("sync") if !syncLocked && len(plan.GetMetaFiles()) != 0 { if cleanLocalMeta { err := plan.CleanLocalMeta() if err != nil { return err } } else { return base.ErrLocalMetaExists } } if err := plan.CreateOpLock("sync"); err != nil { return err } base.Log.Printf("Start doing sync metafiles from storage for plan: %v\n", plan.Name) remoteMetaFiles, err := plan.GetRemoteMetaFiles() if err != nil { return err } localMetaFilesMap := make(map[string]bool) for _, lmf := range plan.GetMetaFiles() { localMetaFilesMap[lmf] = true } var procMetaFiles []base.GenericStorageFileInfo for _, rmf := range remoteMetaFiles { if cf, _ := CleanMetaFileNameEnc(rmf.GetFilename()); !localMetaFilesMap[cf] { procMetaFiles = append(procMetaFiles, rmf) } } errInProgress := false for _, pmf := range procMetaFiles { base.Log.Printf("Start downloading metafile %v\n", pmf.GetFilename()) cf, encrypted := CleanMetaFileNameEnc(pmf.GetFilename()) var decrypter *crypter.Decrypter if encrypted { decrypter = crypter.GetDecrypter(plan.Encrypt_passphrase) } err := plan.Storage.DownloadFile(pmf.GetFileStorageId(), filepath.Join(plan.BaseDir, cf), decrypter) if err != nil { if err == base.ErrStorageRequestInProgress { base.Log.Println(err) errInProgress = true } else { return err } } else { base.Log.Printf("Finish downloading metafile %v\n", pmf.GetFilename()) } } if !errInProgress { err := plan.RemoveOpLock("sync") if err == nil { base.Log.Printf("Finish doing sync metafiles from storage for plan: %v\n", plan.Name) } return err } else { base.Log.Printf("Start doing sync metafiles from storage for plan: %v\n", plan.Name) return base.ErrStorageRequestInProgress } }