Beispiel #1
0
        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
                });
            }
        }
Beispiel #3
0
        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();
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #6
0
        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
                });
            }
        }