public static Duplicati.Library.Interface.IBasicResults Run(IRunnerData data, bool fromQueue) { var backup = data.Backup; Duplicati.Library.Utility.TempFolder tempfolder = null; if (backup.Metadata == null) backup.Metadata = new Dictionary<string, string>(); try { var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation)); var sink = new MessageSink(data.TaskID, backup.ID); if (fromQueue) { Program.GenerateProgressState = () => sink.Copy(); Program.StatusEventNotifyer.SignalNewEvent(); } if (data.ExtraOptions != null) foreach(var k in data.ExtraOptions) options[k.Key] = k.Value; // Log file is using the internal log-handler // so we can display output in the GUI as well as log // into the given file if (options.ContainsKey("log-file")) { var file = options["log-file"]; string o; Library.Logging.LogMessageType level; options.TryGetValue("log-level", out o); Enum.TryParse<Library.Logging.LogMessageType>(o, true, out level); options.Remove("log-file"); options.Remove("log-level"); Program.LogHandler.SetOperationFile(file, level); } // Pack in the system or task config for easy restore if (data.Operation == DuplicatiOperation.Backup && options.ContainsKey("store-task-config")) { var all_tasks = string.Equals(options["store-task-config"], "all", StringComparison.InvariantCultureIgnoreCase) || string.Equals(options["store-task-config"], "*", StringComparison.InvariantCultureIgnoreCase); var this_task = Duplicati.Library.Utility.Utility.ParseBool(options["store-task-config"], false); options.Remove("store-task-config"); if (all_tasks || this_task) { if (tempfolder == null) tempfolder = new Duplicati.Library.Utility.TempFolder(); var temppath = System.IO.Path.Combine(tempfolder, "task-setup.json"); using(var tempfile = Duplicati.Library.Utility.TempFile.WrapExistingFile(temppath)) { object taskdata = null; if (all_tasks) taskdata = Program.DataConnection.Backups.Where(x => !x.IsTemporary).Select(x => Program.DataConnection.PrepareBackupForExport(Program.DataConnection.GetBackup(x.ID))); else taskdata = new [] { Program.DataConnection.PrepareBackupForExport(data.Backup) }; using(var fs = System.IO.File.OpenWrite(tempfile)) using(var sw = new System.IO.StreamWriter(fs, System.Text.Encoding.UTF8)) Serializer.SerializeJson(sw, taskdata, true); tempfile.Protected = true; string controlfiles = null; options.TryGetValue("control-files", out controlfiles); if (string.IsNullOrWhiteSpace(controlfiles)) controlfiles = tempfile; else controlfiles += System.IO.Path.PathSeparator + tempfile; options["control-files"] = controlfiles; } } } using(tempfolder) using(var controller = new Duplicati.Library.Main.Controller(backup.TargetURL, options, sink)) { ((RunnerData)data).Controller = controller; switch (data.Operation) { case DuplicatiOperation.Backup: { var filter = ApplyFilter(backup, data.Operation, GetCommonFilter(backup, data.Operation)); var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var r = controller.Backup(sources, filter); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.List: { var r = controller.List(data.FilterStrings); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.Repair: { var r = controller.Repair(data.FilterStrings == null ? null : new Library.Utility.FilterExpression(data.FilterStrings)); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.RepairUpdate: { var r = controller.UpdateDatabaseWithVersions(); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.Remove: { var r = controller.Delete(); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.Restore: { var r = controller.Restore(data.FilterStrings); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.Verify: { var r = controller.Test(); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.CreateReport: { using(var tf = new Duplicati.Library.Utility.TempFile()) { var r = controller.CreateLogDatabase(tf); var tempid = Program.DataConnection.RegisterTempFile("create-bug-report", r.TargetPath, DateTime.Now.AddDays(3)); if (string.Equals(tf, r.TargetPath, Library.Utility.Utility.ClientFilenameStringComparision)) tf.Protected = true; Program.DataConnection.RegisterNotification( NotificationType.Information, "Bugreport ready", "Bugreport is ready for download", null, null, "bug-report:created:" + tempid, (n, a) => n ); return r; } } default: //TODO: Log this return null; } } } catch (Exception ex) { Program.DataConnection.LogError(data.Backup.ID, string.Format("Failed while executing \"{0}\" with id: {1}", data.Operation, data.Backup.ID), ex); UpdateMetadataError(data.Backup, ex); Library.UsageReporter.Reporter.Report(ex); if (!fromQueue) throw; return null; } finally { ((RunnerData)data).Controller = null; Program.LogHandler.RemoveOperationFile(); } }
public static Duplicati.Library.Interface.IBasicResults Run(IRunnerData data, bool fromQueue) { var backup = data.Backup; if (backup.Metadata == null) backup.Metadata = new Dictionary<string, string>(); try { var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation)); var sink = new MessageSink(data.TaskID, backup.ID); if (fromQueue) { Program.GenerateProgressState = () => sink.Copy(); Program.StatusEventNotifyer.SignalNewEvent(); } if (data.ExtraOptions != null) foreach(var k in data.ExtraOptions) options[k.Key] = k.Value; if (options.ContainsKey("log-file")) { var file = options["log-file"]; string o; Library.Logging.LogMessageType level; options.TryGetValue("log-level", out o); Enum.TryParse<Library.Logging.LogMessageType>(o, true, out level); options.Remove("log-file"); options.Remove("log-level"); Program.LogHandler.SetOperationFile(file, level); } using(var controller = new Duplicati.Library.Main.Controller(backup.TargetURL, options, sink)) { ((RunnerData)data).Controller = controller; switch (data.Operation) { case DuplicatiOperation.Backup: { var filter = ApplyFilter(backup, data.Operation, GetCommonFilter(backup, data.Operation)); var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var r = controller.Backup(sources, filter); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.List: { var r = controller.List(data.FilterStrings); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.Repair: { var r = controller.Repair(); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.Remove: { var r = controller.Delete(); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.Restore: { var r = controller.Restore(data.FilterStrings); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.Verify: { var r = controller.Test(); UpdateMetadata(backup, r); return r; } case DuplicatiOperation.CreateReport: { using(var tf = new Duplicati.Library.Utility.TempFile()) { var r = controller.CreateLogDatabase(tf); var tempid = Program.DataConnection.RegisterTempFile("create-bug-report", r.TargetPath, DateTime.Now.AddDays(3)); if (string.Equals(tf, r.TargetPath, Library.Utility.Utility.ClientFilenameStringComparision)) tf.Protected = true; Program.DataConnection.RegisterNotification( NotificationType.Information, "Bugreport ready", "Bugreport is ready for download", null, null, "bug-report:created:" + tempid, (n, a) => n ); return r; } } default: //TODO: Log this return null; } } } catch (Exception ex) { Program.DataConnection.LogError(data.Backup.ID, string.Format("Failed while executing \"{0}\" with id: {1}", data.Operation, data.Backup.ID), ex); UpdateMetadataError(data.Backup, ex); if (!fromQueue) throw; return null; } finally { ((RunnerData)data).Controller = null; Program.LogHandler.RemoveOperationFile(); } }
public static string GetCommandLine(IRunnerData data) { var backup = data.Backup; var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation)); if (data.ExtraOptions != null) foreach(var k in data.ExtraOptions) options[k.Key] = k.Value; var cf = Program.DataConnection.Filters; var bf = backup.Filters; var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var cmd = new System.Text.StringBuilder(); var exe = System.IO.Path.Combine( Library.AutoUpdater.UpdaterManager.InstalledBaseDir, System.IO.Path.GetFileName( typeof(Duplicati.CommandLine.Commands).Assembly.Location ) ); Func<string, string> appendBackslash = x => x.EndsWith("\\") ? x + "\\" : x; exe = "\"" + appendBackslash(exe) + "\""; if (Library.Utility.Utility.IsMono) exe = "mono " + exe; cmd.Append(exe); cmd.Append(" backup"); cmd.AppendFormat(" \"{0}\"", appendBackslash(backup.TargetURL)); cmd.Append(" \"" + string.Join("\" \"", sources.Select(x => appendBackslash(x))) + "\""); foreach(var opt in options) cmd.AppendFormat(" --{0}={1}", opt.Key, string.IsNullOrWhiteSpace(opt.Value) ? "" : "\"" + appendBackslash(opt.Value) + "\""); if (cf != null) foreach(var f in cf) cmd.AppendFormat(" --{0}=\"{1}\"", f.Include ? "include" : "exclude", appendBackslash(f.Expression)); if (bf != null) foreach(var f in bf) cmd.AppendFormat(" --{0}=\"{1}\"", f.Include ? "include" : "exclude", appendBackslash(f.Expression)); return cmd.ToString(); }
public static Duplicati.Library.Interface.IBasicResults Run(IRunnerData data, bool fromQueue) { if (data is CustomRunnerTask task) { try { var sink = new MessageSink(task.TaskID, null); Program.GenerateProgressState = sink.Copy; Program.StatusEventNotifyer.SignalNewEvent(); task.Run(sink); } catch (Exception ex) { Program.DataConnection.LogError(string.Empty, "Failed while executing custom task", ex); } return(null); } var backup = data.Backup; if (backup.Metadata == null) { backup.Metadata = new Dictionary <string, string>(); } Duplicati.Library.Utility.TempFolder tempfolder = null; try { var sink = new MessageSink(data.TaskID, backup.ID); if (fromQueue) { Program.GenerateProgressState = () => sink.Copy(); Program.StatusEventNotifyer.SignalNewEvent(); } var options = ApplyOptions(backup, GetCommonOptions()); if (data.ExtraOptions != null) { foreach (var k in data.ExtraOptions) { options[k.Key] = k.Value; } } // Pack in the system or task config for easy restore if (data.Operation == DuplicatiOperation.Backup && options.ContainsKey("store-task-config")) { tempfolder = StoreTaskConfigAndGetTempFolder(data, options); } // Attach a log scope that tags all messages to relay the TaskID and BackupID using (Library.Logging.Log.StartScope(log => { log[LogWriteHandler.LOG_EXTRA_TASKID] = data.TaskID.ToString(); log[LogWriteHandler.LOG_EXTRA_BACKUPID] = data.BackupID; })) using (tempfolder) using (var controller = new Duplicati.Library.Main.Controller(backup.TargetURL, options, sink)) { try { if (options.ContainsKey("throttle-upload")) { ((RunnerData)data).OriginalUploadSpeed = Duplicati.Library.Utility.Sizeparser.ParseSize(options["throttle-upload"], "kb"); } } catch { } try { if (options.ContainsKey("throttle-download")) { ((RunnerData)data).OriginalDownloadSpeed = Duplicati.Library.Utility.Sizeparser.ParseSize(options["throttle-download"], "kb"); } } catch { } ((RunnerData)data).Controller = controller; data.UpdateThrottleSpeed(); if (backup.Metadata.ContainsKey("LastCompactFinished")) { controller.LastCompact = Library.Utility.Utility.DeserializeDateTime(backup.Metadata["LastCompactFinished"]); } if (backup.Metadata.ContainsKey("LastVacuumFinished")) { controller.LastVacuum = Library.Utility.Utility.DeserializeDateTime(backup.Metadata["LastVacuumFinished"]); } switch (data.Operation) { case DuplicatiOperation.Backup: { var filter = ApplyFilter(backup, GetCommonFilter()); var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var r = controller.Backup(sources, filter); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.List: { var r = controller.List(data.FilterStrings, null); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Repair: { var r = controller.Repair(data.FilterStrings == null ? null : new Library.Utility.FilterExpression(data.FilterStrings)); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.RepairUpdate: { var r = controller.UpdateDatabaseWithVersions(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Remove: { var r = controller.Delete(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Restore: { var r = controller.Restore(data.FilterStrings); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Verify: { var r = controller.Test(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Compact: { var r = controller.Compact(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.CreateReport: { using (var tf = new Duplicati.Library.Utility.TempFile()) { var r = controller.CreateLogDatabase(tf); var tempid = Program.DataConnection.RegisterTempFile("create-bug-report", r.TargetPath, DateTime.Now.AddDays(3)); if (string.Equals(tf, r.TargetPath, Library.Utility.Utility.ClientFilenameStringComparison)) { tf.Protected = true; } Program.DataConnection.RegisterNotification( NotificationType.Information, "Bugreport ready", "Bugreport is ready for download", null, null, "bug-report:created:" + tempid, null, "BugreportCreatedReady", "", (n, a) => n ); return(r); } } case DuplicatiOperation.ListRemote: { var r = controller.ListRemote(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Delete: { if (Library.Utility.Utility.ParseBoolOption(data.ExtraOptions, "delete-remote-files")) { controller.DeleteAllRemoteFiles(); } if (Library.Utility.Utility.ParseBoolOption(data.ExtraOptions, "delete-local-db")) { string dbpath; options.TryGetValue("dbpath", out dbpath); if (!string.IsNullOrWhiteSpace(dbpath) && System.IO.File.Exists(dbpath)) { System.IO.File.Delete(dbpath); } } Program.DataConnection.DeleteBackup(backup); Program.Scheduler.Reschedule(); return(null); } case DuplicatiOperation.Vacuum: { var r = controller.Vacuum(); UpdateMetadata(backup, r); return(r); } default: //TODO: Log this return(null); } } } catch (Exception ex) { Program.DataConnection.LogError(data.Backup.ID, string.Format("Failed while executing \"{0}\" with id: {1}", data.Operation, data.Backup.ID), ex); UpdateMetadataError(data.Backup, ex); Library.UsageReporter.Reporter.Report(ex); if (!fromQueue) { throw; } return(null); } finally { ((RunnerData)data).Controller = null; } }
private static Duplicati.Library.Utility.TempFolder StoreTaskConfigAndGetTempFolder(IRunnerData data, Dictionary <string, string> options) { var all_tasks = string.Equals(options["store-task-config"], "all", StringComparison.OrdinalIgnoreCase) || string.Equals(options["store-task-config"], "*", StringComparison.OrdinalIgnoreCase); var this_task = Duplicati.Library.Utility.Utility.ParseBool(options["store-task-config"], false); options.Remove("store-task-config"); Duplicati.Library.Utility.TempFolder tempfolder = null; if (all_tasks || this_task) { tempfolder = new Duplicati.Library.Utility.TempFolder(); var temppath = System.IO.Path.Combine(tempfolder, "task-setup.json"); using (var tempfile = Duplicati.Library.Utility.TempFile.WrapExistingFile(temppath)) { object taskdata = null; if (all_tasks) { taskdata = Program.DataConnection.Backups.Where(x => !x.IsTemporary).Select(x => Program.DataConnection.PrepareBackupForExport(Program.DataConnection.GetBackup(x.ID))); } else { taskdata = new[] { Program.DataConnection.PrepareBackupForExport(data.Backup) } }; using (var fs = System.IO.File.OpenWrite(tempfile)) using (var sw = new System.IO.StreamWriter(fs, System.Text.Encoding.UTF8)) Serializer.SerializeJson(sw, taskdata, true); tempfile.Protected = true; options.TryGetValue("control-files", out string controlfiles); if (string.IsNullOrWhiteSpace(controlfiles)) { controlfiles = tempfile; } else { controlfiles += System.IO.Path.PathSeparator + tempfile; } options["control-files"] = controlfiles; } } return(tempfolder); }
public static string GetCommandLine(IRunnerData data) { var backup = data.Backup; var options = ApplyOptions(backup, GetCommonOptions()); if (data.ExtraOptions != null) { foreach (var k in data.ExtraOptions) { options[k.Key] = k.Value; } } var cf = Program.DataConnection.Filters; var bf = backup.Filters; var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var exe = System.IO.Path.Combine( Library.AutoUpdater.UpdaterManager.InstalledBaseDir, System.IO.Path.GetFileName( typeof(Duplicati.CommandLine.Commands).Assembly.Location ) ); var cmd = new System.Text.StringBuilder(); if (Library.Utility.Utility.IsMono) { cmd.Append("mono "); } cmd.Append(Library.Utility.Utility.WrapAsCommandLine(new string[] { exe, "backup", backup.TargetURL }, false)); cmd.Append(" "); cmd.Append(Library.Utility.Utility.WrapAsCommandLine(sources, true)); // TODO: We should check each option to see if it is a path, and allow expansion on that foreach (var opt in options) { cmd.AppendFormat(" --{0}={1}", opt.Key, Library.Utility.Utility.WrapCommandLineElement(opt.Value, false)); } if (cf != null) { foreach (var f in cf) { cmd.AppendFormat(" --{0}={1}", f.Include ? "include" : "exclude", Library.Utility.Utility.WrapCommandLineElement(f.Expression, true)); } } if (bf != null) { foreach (var f in bf) { cmd.AppendFormat(" --{0}={1}", f.Include ? "include" : "exclude", Library.Utility.Utility.WrapCommandLineElement(f.Expression, true)); } } return(cmd.ToString()); }
public static Duplicati.Library.Interface.IBasicResults Run(IRunnerData data, bool fromQueue) { var backup = data.Backup; Duplicati.Library.Utility.TempFolder tempfolder = null; if (backup.Metadata == null) { backup.Metadata = new Dictionary <string, string>(); } try { var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation)); var sink = new MessageSink(data.TaskID, backup.ID); if (fromQueue) { Program.GenerateProgressState = () => sink.Copy(); Program.StatusEventNotifyer.SignalNewEvent(); } if (data.ExtraOptions != null) { foreach (var k in data.ExtraOptions) { options[k.Key] = k.Value; } } // Log file is using the internal log-handler // so we can display output in the GUI as well as log // into the given file if (options.ContainsKey("log-file")) { var file = options["log-file"]; string o; Library.Logging.LogMessageType level; options.TryGetValue("log-level", out o); Enum.TryParse <Library.Logging.LogMessageType>(o, true, out level); options.Remove("log-file"); options.Remove("log-level"); Program.LogHandler.SetOperationFile(file, level); } // Pack in the system or task config for easy restore if (data.Operation == DuplicatiOperation.Backup && options.ContainsKey("store-task-config")) { var all_tasks = string.Equals(options["store-task-config"], "all", StringComparison.InvariantCultureIgnoreCase) || string.Equals(options["store-task-config"], "*", StringComparison.InvariantCultureIgnoreCase); var this_task = Duplicati.Library.Utility.Utility.ParseBool(options["store-task-config"], false); options.Remove("store-task-config"); if (all_tasks || this_task) { if (tempfolder == null) { tempfolder = new Duplicati.Library.Utility.TempFolder(); } var temppath = System.IO.Path.Combine(tempfolder, "task-setup.json"); using (var tempfile = Duplicati.Library.Utility.TempFile.WrapExistingFile(temppath)) { object taskdata = null; if (all_tasks) { taskdata = Program.DataConnection.Backups.Where(x => !x.IsTemporary).Select(x => Program.DataConnection.PrepareBackupForExport(Program.DataConnection.GetBackup(x.ID))); } else { taskdata = new [] { Program.DataConnection.PrepareBackupForExport(data.Backup) } }; using (var fs = System.IO.File.OpenWrite(tempfile)) using (var sw = new System.IO.StreamWriter(fs, System.Text.Encoding.UTF8)) Serializer.SerializeJson(sw, taskdata, true); tempfile.Protected = true; string controlfiles = null; options.TryGetValue("control-files", out controlfiles); if (string.IsNullOrWhiteSpace(controlfiles)) { controlfiles = tempfile; } else { controlfiles += System.IO.Path.PathSeparator + tempfile; } options["control-files"] = controlfiles; } } } using (tempfolder) using (var controller = new Duplicati.Library.Main.Controller(backup.TargetURL, options, sink)) { ((RunnerData)data).Controller = controller; switch (data.Operation) { case DuplicatiOperation.Backup: { var filter = ApplyFilter(backup, data.Operation, GetCommonFilter(backup, data.Operation)); var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var r = controller.Backup(sources, filter); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.List: { var r = controller.List(data.FilterStrings); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Repair: { var r = controller.Repair(data.FilterStrings == null ? null : new Library.Utility.FilterExpression(data.FilterStrings)); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.RepairUpdate: { var r = controller.UpdateDatabaseWithVersions(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Remove: { var r = controller.Delete(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Restore: { var r = controller.Restore(data.FilterStrings); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Verify: { var r = controller.Test(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.CreateReport: { using (var tf = new Duplicati.Library.Utility.TempFile()) { var r = controller.CreateLogDatabase(tf); var tempid = Program.DataConnection.RegisterTempFile("create-bug-report", r.TargetPath, DateTime.Now.AddDays(3)); if (string.Equals(tf, r.TargetPath, Library.Utility.Utility.ClientFilenameStringComparision)) { tf.Protected = true; } Program.DataConnection.RegisterNotification( NotificationType.Information, "Bugreport ready", "Bugreport is ready for download", null, null, "bug-report:created:" + tempid, (n, a) => n ); return(r); } } default: //TODO: Log this return(null); } } } catch (Exception ex) { Program.DataConnection.LogError(data.Backup.ID, string.Format("Failed while executing \"{0}\" with id: {1}", data.Operation, data.Backup.ID), ex); UpdateMetadataError(data.Backup, ex); Library.UsageReporter.Reporter.Report(ex); if (!fromQueue) { throw; } return(null); } finally { ((RunnerData)data).Controller = null; Program.LogHandler.RemoveOperationFile(); } }
public static string GetCommandLine(IRunnerData data) { var backup = data.Backup; var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation)); if (data.ExtraOptions != null) { foreach (var k in data.ExtraOptions) { options[k.Key] = k.Value; } } var cf = Program.DataConnection.Filters; var bf = backup.Filters; var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var cmd = new System.Text.StringBuilder(); var exe = System.IO.Path.Combine( Library.AutoUpdater.UpdaterManager.InstalledBaseDir, System.IO.Path.GetFileName( typeof(Duplicati.CommandLine.Commands).Assembly.Location ) ); Func <string, string> appendBackslash = x => x.EndsWith("\\") ? x + "\\" : x; exe = "\"" + appendBackslash(exe) + "\""; if (Library.Utility.Utility.IsMono) { exe = "mono " + exe; } cmd.Append(exe); cmd.Append(" backup"); cmd.AppendFormat(" \"{0}\"", appendBackslash(backup.TargetURL)); cmd.Append(" \"" + string.Join("\" \"", sources.Select(x => appendBackslash(x))) + "\""); foreach (var opt in options) { cmd.AppendFormat(" --{0}={1}", opt.Key, string.IsNullOrWhiteSpace(opt.Value) ? "" : "\"" + appendBackslash(opt.Value) + "\""); } if (cf != null) { foreach (var f in cf) { cmd.AppendFormat(" --{0}=\"{1}\"", f.Include ? "include" : "exclude", appendBackslash(f.Expression)); } } if (bf != null) { foreach (var f in bf) { cmd.AppendFormat(" --{0}=\"{1}\"", f.Include ? "include" : "exclude", appendBackslash(f.Expression)); } } return(cmd.ToString()); }
public static Duplicati.Library.Interface.IBasicResults Run(IRunnerData data, bool fromQueue) { if (data is CustomRunnerTask) { try { var sink = new MessageSink(data.TaskID, null); Program.GenerateProgressState = () => sink.Copy(); Program.StatusEventNotifyer.SignalNewEvent(); ((CustomRunnerTask)data).Run(sink); } catch (Exception ex) { Program.DataConnection.LogError(string.Empty, "Failed while executing custom task", ex); } return(null); } var backup = data.Backup; Duplicati.Library.Utility.TempFolder tempfolder = null; if (backup.Metadata == null) { backup.Metadata = new Dictionary <string, string>(); } try { var sink = new MessageSink(data.TaskID, backup.ID); if (fromQueue) { Program.GenerateProgressState = () => sink.Copy(); Program.StatusEventNotifyer.SignalNewEvent(); } var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation)); if (data.ExtraOptions != null) { foreach (var k in data.ExtraOptions) { options[k.Key] = k.Value; } } // Pack in the system or task config for easy restore if (data.Operation == DuplicatiOperation.Backup && options.ContainsKey("store-task-config")) { var all_tasks = string.Equals(options["store-task-config"], "all", StringComparison.OrdinalIgnoreCase) || string.Equals(options["store-task-config"], "*", StringComparison.OrdinalIgnoreCase); var this_task = Duplicati.Library.Utility.Utility.ParseBool(options["store-task-config"], false); options.Remove("store-task-config"); if (all_tasks || this_task) { if (tempfolder == null) { tempfolder = new Duplicati.Library.Utility.TempFolder(); } var temppath = System.IO.Path.Combine(tempfolder, "task-setup.json"); using (var tempfile = Duplicati.Library.Utility.TempFile.WrapExistingFile(temppath)) { object taskdata = null; if (all_tasks) { taskdata = Program.DataConnection.Backups.Where(x => !x.IsTemporary).Select(x => Program.DataConnection.PrepareBackupForExport(Program.DataConnection.GetBackup(x.ID))); } else { taskdata = new [] { Program.DataConnection.PrepareBackupForExport(data.Backup) } }; using (var fs = System.IO.File.OpenWrite(tempfile)) using (var sw = new System.IO.StreamWriter(fs, System.Text.Encoding.UTF8)) Serializer.SerializeJson(sw, taskdata, true); tempfile.Protected = true; string controlfiles = null; options.TryGetValue("control-files", out controlfiles); if (string.IsNullOrWhiteSpace(controlfiles)) { controlfiles = tempfile; } else { controlfiles += System.IO.Path.PathSeparator + tempfile; } options["control-files"] = controlfiles; } } } // Attach a log scope that tags all messages to relay the TaskID and BackupID using (Library.Logging.Log.StartScope(log => { log[LogWriteHandler.LOG_EXTRA_TASKID] = data.TaskID.ToString(); log[LogWriteHandler.LOG_EXTRA_BACKUPID] = data.BackupID; })) using (tempfolder) using (var controller = new Duplicati.Library.Main.Controller(backup.TargetURL, options, sink)) { try { if (options.ContainsKey("throttle-upload")) { ((RunnerData)data).OriginalUploadSpeed = Duplicati.Library.Utility.Sizeparser.ParseSize(options["throttle-upload"], "kb"); } } catch { } try { if (options.ContainsKey("throttle-download")) { ((RunnerData)data).OriginalDownloadSpeed = Duplicati.Library.Utility.Sizeparser.ParseSize(options["throttle-download"], "kb"); } } catch { } ((RunnerData)data).Controller = controller; data.UpdateThrottleSpeed(); switch (data.Operation) { case DuplicatiOperation.Backup: { IEnumerable <Library.Utility.IFilter> defaultFilters = null; string defaultFiltersValue; if (options.TryGetValue("default-filters", out defaultFiltersValue) || options.TryGetValue("default-filter", out defaultFiltersValue)) { defaultFilters = Library.Utility.DefaultFilters.GetFilters(Library.Utility.Utility.ExpandEnvironmentVariables(defaultFiltersValue ?? string.Empty)); } var filter = ApplyFilter(backup, data.Operation, GetCommonFilter(backup, data.Operation), defaultFilters); var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var r = controller.Backup(sources, filter); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.List: { var r = controller.List(data.FilterStrings); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Repair: { var r = controller.Repair(data.FilterStrings == null ? null : new Library.Utility.FilterExpression(data.FilterStrings)); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.RepairUpdate: { var r = controller.UpdateDatabaseWithVersions(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Remove: { var r = controller.Delete(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Restore: { var r = controller.Restore(data.FilterStrings); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Verify: { var r = controller.Test(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Compact: { var r = controller.Compact(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.CreateReport: { using (var tf = new Duplicati.Library.Utility.TempFile()) { var r = controller.CreateLogDatabase(tf); var tempid = Program.DataConnection.RegisterTempFile("create-bug-report", r.TargetPath, DateTime.Now.AddDays(3)); if (string.Equals(tf, r.TargetPath, Library.Utility.Utility.ClientFilenameStringComparision)) { tf.Protected = true; } Program.DataConnection.RegisterNotification( NotificationType.Information, "Bugreport ready", "Bugreport is ready for download", null, null, "bug-report:created:" + tempid, null, "BugreportCreatedReady", "", (n, a) => n ); return(r); } } case DuplicatiOperation.ListRemote: { var r = controller.ListRemote(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Delete: { if (Library.Utility.Utility.ParseBoolOption(data.ExtraOptions, "delete-remote-files")) { controller.DeleteAllRemoteFiles(); } if (Library.Utility.Utility.ParseBoolOption(data.ExtraOptions, "delete-local-db")) { string dbpath; options.TryGetValue("db-path", out dbpath); if (!string.IsNullOrWhiteSpace(dbpath) && System.IO.File.Exists(dbpath)) { System.IO.File.Delete(dbpath); } } Program.DataConnection.DeleteBackup(backup); Program.Scheduler.Reschedule(); return(null); } case DuplicatiOperation.Vacuum: { var r = controller.Vacuum(); UpdateMetadata(backup, r); return(r); } default: //TODO: Log this return(null); } } } catch (Exception ex) { Program.DataConnection.LogError(data.Backup.ID, string.Format("Failed while executing \"{0}\" with id: {1}", data.Operation, data.Backup.ID), ex); UpdateMetadataError(data.Backup, ex); Library.UsageReporter.Reporter.Report(ex); if (!fromQueue) { throw; } return(null); } finally { ((RunnerData)data).Controller = null; } }
public static Duplicati.Library.Interface.IBasicResults Run(IRunnerData data, bool fromQueue) { var backup = data.Backup; try { var options = ApplyOptions(backup, data.Operation, GetCommonOptions(backup, data.Operation)); var sink = new MessageSink(data.TaskID, backup.ID); if (fromQueue) { Program.GenerateProgressState = () => sink.Copy(); Program.StatusEventNotifyer.SignalNewEvent(); } if (data.ExtraOptions != null) { foreach (var k in data.ExtraOptions) { options[k.Key] = k.Value; } } if (options.ContainsKey("log-file")) { var file = options["log-file"]; string o; Library.Logging.LogMessageType level; options.TryGetValue("log-level", out o); Enum.TryParse <Library.Logging.LogMessageType>(o, true, out level); options.Remove("log-file"); options.Remove("log-level"); Program.LogHandler.SetOperationFile(file, level); } using (var controller = new Duplicati.Library.Main.Controller(backup.TargetURL, options, sink)) { ((RunnerData)data).Controller = controller; switch (data.Operation) { case DuplicatiOperation.Backup: { var filter = ApplyFilter(backup, data.Operation, GetCommonFilter(backup, data.Operation)); var sources = (from n in backup.Sources let p = SpecialFolders.ExpandEnvironmentVariables(n) where !string.IsNullOrWhiteSpace(p) select p).ToArray(); var r = controller.Backup(sources, filter); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.List: { var r = controller.List(data.FilterStrings); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Repair: { var r = controller.Repair(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Remove: { var r = controller.Delete(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Restore: { var r = controller.Restore(data.FilterStrings); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.Verify: { var r = controller.Test(); UpdateMetadata(backup, r); return(r); } case DuplicatiOperation.CreateReport: { using (var tf = new Duplicati.Library.Utility.TempFile()) { var r = controller.CreateLogDatabase(tf); tf.Protected = true; return(r); } } default: //TODO: Log this return(null); } } } catch (Exception ex) { Program.DataConnection.LogError(data.Backup.ID, string.Format("Failed while executing \"{0}\" with id: {1}", data.Operation, data.Backup.ID), ex); UpdateMetadataError(data.Backup, ex); if (!fromQueue) { throw; } return(null); } finally { ((RunnerData)data).Controller = null; Program.LogHandler.RemoveOperationFile(); } }