public static bool IsBackupOrSnapshot(string filePath) { var extension = Path.GetExtension(filePath); return (BackupUtils.IsBackupFile(filePath) || Constants.Documents.PeriodicBackup.SnapshotExtension.Equals(extension, StringComparison.OrdinalIgnoreCase)); }
private async Task UpdateRestorePoints(List <FileInfoDetails> fileInfos) { var firstFile = true; var snapshotRestore = false; var isEncrypted = false; foreach (var fileInfo in fileInfos) { var extension = Path.GetExtension(fileInfo.FullPath); var isSnapshot = Constants.Documents.PeriodicBackup.SnapshotExtension.Equals(extension, StringComparison.OrdinalIgnoreCase) || Constants.Documents.PeriodicBackup.EncryptedSnapshotExtension.Equals(extension, StringComparison.OrdinalIgnoreCase); if (firstFile) { snapshotRestore = isSnapshot; if (Constants.Documents.PeriodicBackup.EncryptedSnapshotExtension.Equals(extension, StringComparison.OrdinalIgnoreCase) || Constants.Documents.PeriodicBackup.EncryptedIncrementalBackupExtension.Equals(extension, StringComparison.OrdinalIgnoreCase) || Constants.Documents.PeriodicBackup.EncryptedFullBackupExtension.Equals(extension, StringComparison.OrdinalIgnoreCase)) { isEncrypted = true; } else if (isSnapshot && this is LocalRestorePoints) { // checking legacy encrypted snapshot backups, it was saved with the same extension as the non-encrypted one // local only since this might require the download of the whole file isEncrypted = await CheckIfSnapshotIsEncrypted(fileInfo.FullPath); } } else if (isSnapshot) { throw new InvalidOperationException($"Cannot have a snapshot backup file ({GetFileName(fileInfo.FullPath)}) after other backup files!"); } firstFile = false; while (_sortedList.ContainsKey(fileInfo.LastModified)) { fileInfo.LastModified = fileInfo.LastModified.AddMilliseconds(1); } var folderDetails = ParseFolderNameFrom(fileInfo.DirectoryPath); _sortedList.Add(fileInfo.LastModified, new RestorePoint { DateTime = fileInfo.LastModified, Location = fileInfo.DirectoryPath, FileName = fileInfo.FullPath, IsSnapshotRestore = snapshotRestore, IsIncremental = BackupUtils.IsIncrementalBackupFile(extension), IsEncrypted = isEncrypted, DatabaseName = folderDetails.DatabaseName, NodeTag = folderDetails.NodeTag }); } }
private void DoBackupFile(BackupFile file, BackupedFiles backupedFiles) { try { if (cancelToken.IsCanceled || IsHidden(file.Info) || ExcludePath(file.Info.FullName)) { return; } string backupFileName; string fileHash = BackupUtils.GetHash(file.Info.FullName); if (cancelToken.IsCanceled) { return; } if (backupedFiles.Add(fileHash, file.Info.Extension, out backupFileName)) { string destPath = Path.Combine(FilesDestFolderPath, backupFileName); do { File.Copy(file.Info.FullName, destPath, true); } while (fileHash != BackupUtils.GetHash(file.Info.FullName)); addedFiles.Add(destPath); } lock (addedToDbFoldersFiles) { (DbFile? dbFile, DbFolderFile folderFile) = db.AddFile(file.Info.Name, fileHash, backupFileName, file.FolderId); if (dbFile.HasValue) { addedToDbFiles.Add(dbFile.Value); } addedToDbFoldersFiles.Add(folderFile); } } catch { } finally { IncreaseProgressLocked(); } }
protected async Task FetchRestorePointsForPath(string path, bool assertLegacyBackups) { var fileInfos = (await GetFiles(path)) .Where(filePath => { if (assertLegacyBackups) { const string legacyEsentBackupFile = "RavenDB.Backup"; const string legacyVoronBackupFile = "RavenDB.Voron.Backup"; var fileName = filePath.FullPath; if (fileName.Equals(legacyEsentBackupFile, StringComparison.OrdinalIgnoreCase) || fileName.Equals(legacyVoronBackupFile, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Cannot restore a legacy backup (v3.x and below). " + "You can restore a v3.x periodic export backup or " + "use an export from v3.x and import it using the studio"); } } return(IsBackupOrSnapshot(filePath.FullPath)); }) .OrderBy(x => Path.GetFileNameWithoutExtension(x.FullPath)) .ThenBy(x => Path.GetExtension(x.FullPath), PeriodicBackupFileExtensionComparer.Instance) .ThenBy(x => x.LastModified); var folderDetails = ParseFolderNameFrom(path); var filesCount = 0; var firstFile = true; var snapshotRestore = false; var isEncrypted = false; foreach (var fileInfo in fileInfos) { var extension = Path.GetExtension(fileInfo.FullPath); var isSnapshot = Constants.Documents.PeriodicBackup.SnapshotExtension.Equals(extension, StringComparison.OrdinalIgnoreCase) || Constants.Documents.PeriodicBackup.EncryptedSnapshotExtension.Equals(extension, StringComparison.OrdinalIgnoreCase); if (firstFile) { snapshotRestore = isSnapshot; if (Constants.Documents.PeriodicBackup.EncryptedSnapshotExtension.Equals(extension, StringComparison.OrdinalIgnoreCase) || Constants.Documents.PeriodicBackup.EncryptedIncrementalBackupExtension.Equals(extension, StringComparison.OrdinalIgnoreCase) || Constants.Documents.PeriodicBackup.EncryptedFullBackupExtension.Equals(extension, StringComparison.OrdinalIgnoreCase)) { isEncrypted = true; } else { if (isSnapshot) { isEncrypted = await CheckIfSnapshotIsEncrypted(fileInfo.FullPath); } } } else if (isSnapshot) { throw new InvalidOperationException($"Cannot have a snapshot backup file ({GetFileName(fileInfo.FullPath)}) after other backup files!"); } firstFile = false; filesCount++; while (_sortedList.ContainsKey(fileInfo.LastModified)) { fileInfo.LastModified = fileInfo.LastModified.AddMilliseconds(1); } _sortedList.Add(fileInfo.LastModified, new RestorePoint { DateTime = fileInfo.LastModified, Location = path, FileName = fileInfo.FullPath, IsSnapshotRestore = snapshotRestore, IsIncremental = BackupUtils.IsIncrementalBackupFile(extension), IsEncrypted = isEncrypted, FilesToRestore = filesCount, DatabaseName = folderDetails.DatabaseName, NodeTag = folderDetails.NodeTag }); } }
private bool UpdateFoldersToDelete(GetFoldersResult folders, DateTime now, List <string> foldersToDelete) { var firstDateInRetentionRange = now - _retentionPolicy.MinimumBackupAgeToKeep.Value; foreach (var folder in folders.List) { CancellationToken.ThrowIfCancellationRequested(); var folderName = GetFolderName(folder); var folderDetails = RestorePointsBase.ParseFolderName(folderName); if (folderDetails.BackupTimeAsString == null) { if (Logger.IsInfoEnabled) { Logger.Info($"Failed to get backup date time for folder: {folder}"); } continue; } if (DateTime.TryParseExact( folderDetails.BackupTimeAsString, BackupTask.GetDateTimeFormat(folderDetails.BackupTimeAsString), CultureInfo.InvariantCulture, DateTimeStyles.None, out var backupTime) == false) { if (Logger.IsInfoEnabled) { Logger.Info($"Failed to parse backup date time for folder: {folder}"); } continue; } if (now - backupTime < _retentionPolicy.MinimumBackupAgeToKeep) { // all backups are sorted by date return(false); } if (string.Equals(folderDetails.DatabaseName, _databaseName, StringComparison.OrdinalIgnoreCase) == false) { continue; // a backup for a different database } var backupFiles = GetBackupFilesInFolder(folder, firstDateInRetentionRange); if (backupFiles == null) { continue; // folder is empty } var hasFullBackupOrSnapshot = BackupUtils.IsFullBackupOrSnapshot(backupFiles.FirstFile); if (hasFullBackupOrSnapshot == false) { continue; // no snapshot or full backup } if (GotFreshIncrementalBackup(backupFiles, now)) { continue; } foldersToDelete.Add(folder); } return(true); }
public static void FetchRestorePoints( string directoryPath, SortedList <DateTime, RestorePoint> sortedList, bool assertLegacyBackups = false) { const string legacyEsentBackupFile = "RavenDB.Backup"; const string legacyVoronBackupFile = "RavenDB.Voron.Backup"; var files = Directory.GetFiles(directoryPath) .Where(filePath => { if (assertLegacyBackups) { var fileName = Path.GetFileName(filePath); if (fileName.Equals(legacyEsentBackupFile, StringComparison.OrdinalIgnoreCase) || fileName.Equals(legacyVoronBackupFile, StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("Cannot restore a legacy backup (v3.x and below). " + "You can restore a v3.x periodic export backup or " + "use an export from v3.x and import it using the studio"); } } return(IsBackupOrSnapshot(filePath)); }) .OrderBackups(); var folderDetails = ParseFolderName(directoryPath); var filesCount = 0; var firstFile = true; var snapshotRestore = false; foreach (var filePath in files) { var extension = Path.GetExtension(filePath); var isSnapshot = Constants.Documents.PeriodicBackup.SnapshotExtension.Equals(extension, StringComparison.OrdinalIgnoreCase); if (firstFile) { snapshotRestore = isSnapshot; } else if (isSnapshot) { throw new InvalidOperationException($"Cannot have a snapshot backup file ({Path.GetFileName(filePath)}) after other backup files!"); } firstFile = false; filesCount++; var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); var fileDate = TryExtractDateFromFileName(fileNameWithoutExtension, filePath); while (sortedList.ContainsKey(fileDate)) { fileDate = fileDate.AddMilliseconds(1); } sortedList.Add(fileDate, new RestorePoint { DateTime = fileDate, Location = directoryPath, FileName = Path.GetFileName(filePath), IsSnapshotRestore = snapshotRestore, IsIncremental = BackupUtils.IsIncrementalBackupFile(extension), FilesToRestore = filesCount, DatabaseName = folderDetails.DatabaseName, NodeTag = folderDetails.NodeTag }); } }