private static async Task <int> ServerCopyAsync(ServerCopyOptions options, CancellationToken cancellationToken = default) { var sourceCloudStorageAccount = GetCloudStorageAccount(options.SourceConnectionString, options.SourceSASToken, options.SourceStorageAccountName); var sourceCloudFileClient = sourceCloudStorageAccount.CreateCloudFileClient(); var azureShareSnapshotManager = new AzureShareSnapshotManager(sourceCloudFileClient, $"AzureShareBackupServerCopySnapshot_{Guid.NewGuid():N}"); var snapshotShare = await azureShareSnapshotManager.CreateManagedSnapshotAsync(options.SourceShareName, cancellationToken); try { var targetCloudStorageAccount = GetCloudStorageAccount(options.TargetConnectionString, options.TargetSASToken, options.TargetStorageAccountName); var targetCloudFileClient = targetCloudStorageAccount.CreateCloudFileClient(); var targetFileShare = targetCloudFileClient.GetShareReference(options.TargetShareName); var targetDirectoryName = $"{snapshotShare.SnapshotTime:yyyyMMdd-HHmmss}"; var targetDirectory = targetFileShare.GetRootDirectoryReference().GetDirectoryReference(targetDirectoryName); await targetDirectory.CreateAsync(cancellationToken); var backupProvider = new AzureServerSideCopyBackupProvider(snapshotShare.GetRootDirectoryReference(), targetDirectory); await backupProvider.RunAsync(cancellationToken); } finally { // ReSharper disable once PossibleInvalidOperationException // we want this to happen regardless of the rest being cancelled await azureShareSnapshotManager.DeleteManagedSnapshotAsync(snapshotShare.Name, snapshotShare.SnapshotTime.Value, CancellationToken.None); } return(0); }
public static async Task <int> Main(string[] args) { ServiceHostDefaults.Apply(); var cts = new CancellationTokenSource(); Console.CancelKeyPress += (sender, eventArgs) => { Log.Info(() => "Ctrl-C pressed, aborting..."); eventArgs.Cancel = true; cts.Cancel(); }; var retval = 1; try { Log.Info(() => "AzureBackup.ConsoleHost starting"); var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("config.json", true) .AddCommandLine(args) .Build(); switch (config["mode"].ToLowerInvariant()) { case "snapshot": var snapshotOptions = new SnapshotOptions(); config.Bind("snapshot", snapshotOptions); retval = await SnapshotAsync(snapshotOptions, cts.Token); break; case "backuplocal": var backupLocalOptions = new BackupLocalArchiveOptions(); config.Bind("backuplocal", backupLocalOptions); retval = await BackupLocalArchiveAsync(backupLocalOptions, cts.Token); break; case "backupblob": var backupBlobOptions = new BackupBlobStorageArchiveOptions(); config.Bind("backupblob", backupBlobOptions); retval = await BackupBlobStorageArchiveAsync(backupBlobOptions, cts.Token); break; case "servercopy": var serverCopyOptions = new ServerCopyOptions(); config.Bind("servercopy", serverCopyOptions); retval = await ServerCopyAsync(serverCopyOptions, cts.Token); break; default: Log.Fatal(() => $"Unknown mode '{config["mode"]}'"); retval = 1; break; } } catch (TaskCanceledException) { } catch (Exception ex) { Log.Fatal(ex, () => "Unhandled exception"); } Log.Info(() => "AzureBackup.ConsoleHost finished"); return(retval); }