Update issue #236

This is a reworked version of the patch in issue #236.
I have masked the passphrase, and added the cleanup commands as well.

Let me know if this works for you.

git-svn-id: https://duplicati.googlecode.com/svn/trunk@1507 59da171f-624f-0410-aa54-27559c288bec
This commit is contained in:
kenneth@hexad.dk
2013-01-19 14:08:38 +00:00
parent 9a1a1b70c2
commit 487bbdf6b2
4 changed files with 358 additions and 89 deletions
+46 -11
View File
@@ -22,23 +22,24 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FinishedAdd));
this.label1 = new System.Windows.Forms.Label();
this.Summary = new System.Windows.Forms.TextBox();
this.RunNow = new System.Windows.Forms.CheckBox();
this.Tabs = new System.Windows.Forms.TabControl();
this.TabSummary = new System.Windows.Forms.TabPage();
this.TabCommandLine = new System.Windows.Forms.TabPage();
this.CommandLine = new System.Windows.Forms.TextBox();
this.Tabs.SuspendLayout();
this.TabSummary.SuspendLayout();
this.TabCommandLine.SuspendLayout();
this.SuspendLayout();
//
// label1
//
resources.ApplyResources(this.label1, "label1");
this.label1.Name = "label1";
//
// Summary
//
resources.ApplyResources(this.Summary, "Summary");
@@ -51,14 +52,45 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
this.RunNow.Name = "RunNow";
this.RunNow.UseVisualStyleBackColor = true;
//
// Tabs
//
this.Tabs.Controls.Add(this.TabSummary);
this.Tabs.Controls.Add(this.TabCommandLine);
resources.ApplyResources(this.Tabs, "Tabs");
this.Tabs.Name = "Tabs";
this.Tabs.SelectedIndex = 0;
this.Tabs.SelectedIndexChanged += new System.EventHandler(this.Tabs_SelectedIndexChanged);
//
// TabSummary
//
this.TabSummary.Controls.Add(this.Summary);
resources.ApplyResources(this.TabSummary, "TabSummary");
this.TabSummary.Name = "TabSummary";
//
// TabCommandLine
//
this.TabCommandLine.Controls.Add(this.CommandLine);
resources.ApplyResources(this.TabCommandLine, "TabCommandLine");
this.TabCommandLine.Name = "TabCommandLine";
//
// CommandLine
//
resources.ApplyResources(this.CommandLine, "CommandLine");
this.CommandLine.Name = "CommandLine";
this.CommandLine.ReadOnly = true;
//
// FinishedAdd
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.Tabs);
this.Controls.Add(this.RunNow);
this.Controls.Add(this.Summary);
this.Controls.Add(this.label1);
this.Name = "FinishedAdd";
this.Tabs.ResumeLayout(false);
this.TabSummary.ResumeLayout(false);
this.TabSummary.PerformLayout();
this.TabCommandLine.ResumeLayout(false);
this.TabCommandLine.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
@@ -66,8 +98,11 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
#endregion
private System.Windows.Forms.Label label1;
public System.Windows.Forms.TextBox Summary;
public System.Windows.Forms.CheckBox RunNow;
private System.Windows.Forms.TabControl Tabs;
private System.Windows.Forms.TabPage TabSummary;
private System.Windows.Forms.TabPage TabCommandLine;
public System.Windows.Forms.TextBox CommandLine;
}
}
@@ -26,6 +26,7 @@ using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Wizard;
using Duplicati.Datamodel;
using Duplicati.Server;
namespace Duplicati.GUI.Wizard_pages.Add_backup
{
@@ -115,6 +116,9 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
Summary.Text = sb.ToString();
args.TreatAsLast = true;
CommandLine.Text = "";
Tabs.SelectedTab = TabSummary;
}
public override string HelpText
@@ -138,5 +142,141 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
return Strings.FinishedAdd.PageTitleModify;
}
}
private string QuoteIfRequired(string input)
{
if (Library.Utility.Utility.IsClientLinux)
{
input = input.Replace("\\", "\\\\")
.Replace("$", "\\$")
.Replace("*", "\\*")
.Replace("?", "\\?")
.Replace("`", "\\`");
}
if (input.IndexOfAny(new char[] { ' ', '|', '&' }) >= 0)
{
if (!Library.Utility.Utility.IsClientLinux && input.EndsWith("\\"))
input += "\\";
return '"' + input + '"';
}
return input;
}
private void Tabs_SelectedIndexChanged(object sender, EventArgs e)
{
// The CommandLine box is filled only on demand.
if (Tabs.SelectedTab == TabCommandLine && CommandLine.TextLength == 0)
{
// Getting all options for the task
System.Data.LightDatamodel.IDataFetcherWithRelations con = new System.Data.LightDatamodel.DataFetcherNested(Program.DataConnection);
Schedule schedule = con.Add<Schedule>();
m_wrapper.UpdateSchedule(schedule);
Dictionary<string, string> options = new Dictionary<string, string>();
String target = new IncrementalBackupTask(schedule).GetConfiguration(options);
List<Library.Interface.ICommandLineArgument> defaults = SettingOverrides.GetModuleOptions(m_wrapper, null);
defaults.AddRange(new Library.Main.Options(new Dictionary<string, string>()).SupportedCommands);
String source = schedule.Task.SourcePath;
if (source == "")
{
// We need to extract the paths of the "easy" folders
string[] sourceFolders = DynamicSetupHelper.GetSourceFolders(schedule.Task, new ApplicationSettings(schedule.Task.DataParent), new List<KeyValuePair<bool, string>>());
source = String.Join(System.IO.Path.PathSeparator.ToString(), sourceFolders);
}
// We have everything needed to build the Command line
System.Text.StringBuilder sb = new StringBuilder();
sb.AppendLine("Command-line equivalent of this task:");
sb.AppendLine();
sb.Append(QuoteIfRequired(Application.ExecutablePath.Substring(0, Application.ExecutablePath.Length - 4) + ".CommandLine.exe"));
// Filters are handled differently
options.Remove("filter");
//Remove all default values
foreach (Library.Interface.ICommandLineArgument arg in defaults)
{
string defvalue = arg.DefaultValue == null ? "" : arg.DefaultValue;
if (options.ContainsKey(arg.Name) && (defvalue) == (options[arg.Name] == null ? "" : options[arg.Name]))
options.Remove(arg.Name);
if (arg.Aliases != null)
foreach(string a in arg.Aliases)
if (options.ContainsKey(a) && (arg.DefaultValue ?? "") == (options[a] == null ? "" : options[a]))
options.Remove(a);
}
//TODO: Should mask the connection password as well
if (options.ContainsKey("passphrase") && !string.IsNullOrEmpty(options["passphrase"]))
options["passphrase"] = "**********";
foreach (KeyValuePair<string, string> i in options)
{
sb.Append(" --" + i.Key);
if (!string.IsNullOrEmpty(i.Value))
sb.Append("=" + QuoteIfRequired(i.Value));
}
// Filters
foreach (Datamodel.TaskFilter filter in schedule.Task.SortedFilters)
{
sb.Append(" --");
sb.Append(filter.Include ? "include" : "exclude");
sb.Append(filter.GlobbingFilter.Length == 0 ? "-regexp" : "");
sb.Append("=");
sb.Append(QuoteIfRequired(filter.GlobbingFilter.Length > 0 ? filter.GlobbingFilter : filter.Filter));
}
// Source and target
sb.Append(" BACKUP");
sb.Append(" " + QuoteIfRequired(source));
sb.Append(" " + QuoteIfRequired(target));
options.Remove("passphrase");
if (!string.IsNullOrEmpty(m_wrapper.BackupExpireInterval))
{
sb.AppendLine();
sb.AppendLine();
sb.Append(QuoteIfRequired(Application.ExecutablePath.Substring(0, Application.ExecutablePath.Length - 4) + ".CommandLine.exe"));
sb.Append(" delete-older-than ");
sb.Append(QuoteIfRequired(m_wrapper.BackupExpireInterval));
foreach (KeyValuePair<string, string> i in options)
{
sb.Append(" --" + i.Key);
if (!string.IsNullOrEmpty(i.Value))
sb.Append("=" + QuoteIfRequired(i.Value));
}
sb.Append(" " + QuoteIfRequired(target));
}
if (m_wrapper.MaxFullBackups > 0)
{
sb.AppendLine();
sb.Append(QuoteIfRequired(Application.ExecutablePath.Substring(0, Application.ExecutablePath.Length - 4) + ".CommandLine.exe"));
sb.Append(" delete-all-but-n");
sb.Append(" " + QuoteIfRequired(m_wrapper.MaxFullBackups.ToString()));
foreach (KeyValuePair<string, string> i in options)
{
sb.Append(" --" + i.Key);
if (!string.IsNullOrEmpty(i.Value))
sb.Append("=" + QuoteIfRequired(i.Value));
}
sb.Append(" " + QuoteIfRequired(target));
}
CommandLine.Text = sb.ToString();
}
}
}
}
@@ -112,55 +112,31 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
<value>24, 16</value>
</data>
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
<value>50, 13</value>
</data>
<data name="label1.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Summary</value>
</data>
<data name="&gt;&gt;label1.Name" xml:space="preserve">
<value>label1</value>
</data>
<data name="&gt;&gt;label1.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
<value>2</value>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Summary.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="Summary.Font" type="System.Drawing.Font, System.Drawing">
<value>Courier New, 8.25pt</value>
</data>
<data name="Summary.Location" type="System.Drawing.Point, System.Drawing">
<value>24, 40</value>
<value>3, 3</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Summary.Multiline" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Summary.ScrollBars" type="System.Windows.Forms.ScrollBars, System.Windows.Forms">
<value>Both</value>
</data>
<data name="Summary.Size" type="System.Drawing.Size, System.Drawing">
<value>456, 152</value>
<value>450, 146</value>
</data>
<data name="Summary.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
@@ -169,13 +145,13 @@
<value>Summary</value>
</data>
<data name="&gt;&gt;Summary.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;Summary.Parent" xml:space="preserve">
<value>$this</value>
<value>TabSummary</value>
</data>
<data name="&gt;&gt;Summary.ZOrder" xml:space="preserve">
<value>1</value>
<value>0</value>
</data>
<data name="RunNow.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
@@ -196,15 +172,123 @@
<value>RunNow</value>
</data>
<data name="&gt;&gt;RunNow.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;RunNow.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;RunNow.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="TabSummary.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 22</value>
</data>
<data name="TabSummary.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 3, 3, 3</value>
</data>
<data name="TabSummary.Size" type="System.Drawing.Size, System.Drawing">
<value>456, 152</value>
</data>
<data name="TabSummary.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<data name="TabSummary.Text" xml:space="preserve">
<value>Summary</value>
</data>
<data name="&gt;&gt;TabSummary.Name" xml:space="preserve">
<value>TabSummary</value>
</data>
<data name="&gt;&gt;TabSummary.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;TabSummary.Parent" xml:space="preserve">
<value>Tabs</value>
</data>
<data name="&gt;&gt;TabSummary.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="CommandLine.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="CommandLine.Font" type="System.Drawing.Font, System.Drawing">
<value>Courier New, 8.25pt</value>
</data>
<data name="CommandLine.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="CommandLine.Multiline" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="CommandLine.ScrollBars" type="System.Windows.Forms.ScrollBars, System.Windows.Forms">
<value>Both</value>
</data>
<data name="CommandLine.Size" type="System.Drawing.Size, System.Drawing">
<value>450, 146</value>
</data>
<data name="CommandLine.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;CommandLine.Name" xml:space="preserve">
<value>CommandLine</value>
</data>
<data name="&gt;&gt;CommandLine.Type" xml:space="preserve">
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;CommandLine.Parent" xml:space="preserve">
<value>TabCommandLine</value>
</data>
<data name="&gt;&gt;CommandLine.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="TabCommandLine.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 22</value>
</data>
<data name="TabCommandLine.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 3, 3, 3</value>
</data>
<data name="TabCommandLine.Size" type="System.Drawing.Size, System.Drawing">
<value>456, 152</value>
</data>
<data name="TabCommandLine.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="TabCommandLine.Text" xml:space="preserve">
<value>Command Line</value>
</data>
<data name="&gt;&gt;TabCommandLine.Name" xml:space="preserve">
<value>TabCommandLine</value>
</data>
<data name="&gt;&gt;TabCommandLine.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;TabCommandLine.Parent" xml:space="preserve">
<value>Tabs</value>
</data>
<data name="&gt;&gt;TabCommandLine.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="Tabs.Location" type="System.Drawing.Point, System.Drawing">
<value>21, 16</value>
</data>
<data name="Tabs.Size" type="System.Drawing.Size, System.Drawing">
<value>464, 178</value>
</data>
<data name="Tabs.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="&gt;&gt;Tabs.Name" xml:space="preserve">
<value>Tabs</value>
</data>
<data name="&gt;&gt;Tabs.Type" xml:space="preserve">
<value>System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;Tabs.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;Tabs.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
@@ -64,6 +64,55 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
}
}
public static List<Library.Interface.ICommandLineArgument> GetModuleOptions(WizardSettingsWrapper wrapper, Control parent)
{
List<Library.Interface.ICommandLineArgument> res = new List<Library.Interface.ICommandLineArgument>();
try
{
res.AddRange(Library.DynamicLoader.BackendLoader.GetSupportedCommands(wrapper.Backend));
}
catch (Exception ex)
{
if (parent != null)
MessageBox.Show(parent, string.Format(Strings.SettingOverrides.BackendLoadError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
res.AddRange(Library.DynamicLoader.EncryptionLoader.GetSupportedCommands(wrapper.EncryptionModule));
}
catch (Exception ex)
{
if (parent != null)
MessageBox.Show(parent, string.Format(Strings.SettingOverrides.EncryptionLoadError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
res.AddRange(Library.DynamicLoader.CompressionLoader.GetSupportedCommands(wrapper.CompressionModule));
}
catch (Exception ex)
{
if (parent != null)
MessageBox.Show(parent, string.Format(Strings.SettingOverrides.CompressionLoadError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
foreach (Library.Interface.IGenericModule m in Library.DynamicLoader.GenericLoader.Modules)
if (m.SupportedCommands != null)
res.AddRange(m.SupportedCommands);
}
catch (Exception ex)
{
if (parent != null)
MessageBox.Show(parent, string.Format(Strings.SettingOverrides.GenericModuleLoadError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return res;
}
void SettingOverrides_PageEnter(object sender, System.Windows.Forms.Wizard.PageChangedArgs args)
{
if (!OptionGrid.Unsupported)
@@ -73,46 +122,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
if (!m_settings.ContainsKey("Overrides:Table"))
{
IList<Library.Interface.ICommandLineArgument> primary = new Library.Main.Options(new Dictionary<string, string>()).SupportedCommands;
List<Library.Interface.ICommandLineArgument> secondary = new List<Library.Interface.ICommandLineArgument>();
try
{
secondary.AddRange(Library.DynamicLoader.BackendLoader.GetSupportedCommands(m_wrapper.Backend));
}
catch (Exception ex)
{
MessageBox.Show(this, string.Format(Strings.SettingOverrides.BackendLoadError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
secondary.AddRange(Library.DynamicLoader.EncryptionLoader.GetSupportedCommands(m_wrapper.EncryptionModule));
}
catch (Exception ex)
{
MessageBox.Show(this, string.Format(Strings.SettingOverrides.EncryptionLoadError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
secondary.AddRange(Library.DynamicLoader.CompressionLoader.GetSupportedCommands(m_wrapper.CompressionModule));
}
catch (Exception ex)
{
MessageBox.Show(this, string.Format(Strings.SettingOverrides.CompressionLoadError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
foreach(Library.Interface.IGenericModule m in Library.DynamicLoader.GenericLoader.Modules)
if (m.SupportedCommands != null)
secondary.AddRange(m.SupportedCommands);
}
catch (Exception ex)
{
MessageBox.Show(this, string.Format(Strings.SettingOverrides.GenericModuleLoadError, ex), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
IList<Library.Interface.ICommandLineArgument> secondary = GetModuleOptions(m_wrapper, this);
OptionGrid.Setup(primary, secondary, m_wrapper.Overrides);