in Source/NuGetGallery.Operations/Tasks/Backups/BackupPackagesTask.cs [41:140]
public override void ExecuteCommand()
{
Log.Info(
"Backing up '{0}/packages' -> '{1}/package-backups'.",
StorageAccount.Credentials.AccountName,
BackupStorage.Credentials.AccountName);
var client = CreateBlobClient();
var backupClient = BackupStorage.CreateCloudBlobClient();
// Get the state file object
var state = GetStateFile(backupClient);
var lastId = state.LastBackedUpId;
bool forcedRecheck = false;
if (state.LastBackupCompletedUtc.HasValue && ((DateTimeOffset.UtcNow - state.LastBackupCompletedUtc.Value) > TimeSpan.FromDays(1)))
{
// Do a "full" backup (check every package file) every day
lastId = null;
forcedRecheck = true;
}
var packagesToBackUp = GetPackagesToBackUp(lastId, forcedRecheck);
var processedCount = 0;
var backupBlobs = backupClient.GetContainerReference("package-backups");
var packageBlobs = client.GetContainerReference("packages");
if (!WhatIf)
{
backupBlobs.CreateIfNotExists();
}
Parallel.ForEach(packagesToBackUp, new ParallelOptions { MaxDegreeOfParallelism = SingleThreaded ? 1 : 10 }, package =>
{
try
{
var packageBlob = packageBlobs.GetBlockBlobReference(Util.GetPackageFileName(package.Id, package.Version));
var backupBlob = backupBlobs.GetBlockBlobReference(Util.GetPackageBackupFileName(package.Id, package.Version, package.Hash));
if (packageBlob.Exists())
{
bool shouldCopy = backupBlob.Exists();
// Verify the package, if it exists
if (shouldCopy)
{
packageBlob.FetchAttributes();
backupBlob.FetchAttributes();
shouldCopy =
String.IsNullOrEmpty(packageBlob.Properties.ContentMD5) ||
String.IsNullOrEmpty(backupBlob.Properties.ContentMD5) ||
!String.Equals(packageBlob.Properties.ContentMD5, backupBlob.Properties.ContentMD5, StringComparison.Ordinal);
}
if (!shouldCopy && !WhatIf)
{
backupBlob.StartCopyFromBlob(packageBlob);
}
Interlocked.Increment(ref processedCount);
Log.Trace(
"[{2:000000}/{3:000000} {4:00.0}%] {5} Backup of '{0}@{1}'.",
package.Id,
package.Version,
processedCount,
packagesToBackUp.Count,
(double)processedCount / (double)packagesToBackUp.Count,
shouldCopy ? "Skipped" : "Started");
}
else
{
Log.Warn(
"[{2:000000}/{3:000000} {4:00.0}%] Package File not found in source: '{0}@{1}'",
package.Id,
package.Version,
processedCount,
packagesToBackUp.Count,
(double)processedCount / (double)packagesToBackUp.Count);
}
}
catch (Exception ex)
{
Interlocked.Increment(ref processedCount);
Log.Error(
"[{2:000000}/{3:000000} {4:00.0}%] Error Starting Backup of '{0}@{1}': {5}",
package.Id,
package.Version,
processedCount,
packagesToBackUp.Count,
(double)processedCount / (double)packagesToBackUp.Count,
ex.Message);
}
});
Log.Info("Backed up {0} packages from {1} to {2}", processedCount, StorageAccount.Credentials.AccountName, BackupStorage.Credentials.AccountName);
state.LastBackupCompletedUtc = DateTimeOffset.UtcNow;
state.LastBackedUpId = packagesToBackUp.Max(p => p.Key);
WriteStateFile(backupClient, state);
}