CP-39929: Add timestamps to update logs

- Add option to the display options page
- Add related setting
- Refactor `ExtensionMethods` to be more compact and flexible
- Add docs to `ExtensionMethods`
- Whitespace fixes

Signed-off-by: Danilo Del Busso <Danilo.Del.Busso@citrix.com>
This commit is contained in:
Danilo Del Busso 2022-08-10 15:44:07 +01:00
parent 1fd39713f1
commit 54a9f22c87
No known key found for this signature in database
GPG Key ID: 0C48542619080FD4
9 changed files with 290 additions and 64 deletions

View File

@ -29,30 +29,32 @@
* SUCH DAMAGE.
*/
using System.Drawing;
using System;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace XenAdmin.Core
{
internal static class ExtensionMethods
{
/// <summary>
/// Internationalization of True/False
/// </summary>
public static string ToStringI18n(this bool value)
{
return value ? Messages.TRUE : Messages.FALSE;
}
internal static class ExtensionMethods
{
private const int DEFAULT_STRING_INDENTATION = 2;
/// <summary>
/// Internationalization of True/False
/// </summary>
public static string ToStringI18n(this bool value)
{
return value ? Messages.TRUE : Messages.FALSE;
}
/// <summary>
/// Turns a bool to internationalized Yes/No (on occasion it's user friendlier than True/False)
/// </summary>
public static string ToYesNoStringI18n(this bool value)
{
return value ? Messages.YES : Messages.NO;
}
/// <summary>
/// Turns a bool to internationalized Yes/No (on occasion it's user friendlier than True/False)
/// </summary>
public static string ToYesNoStringI18n(this bool value)
{
return value ? Messages.YES : Messages.NO;
}
/// <summary>
/// This has the same bahvoiur as the standard ellipsise extension but this uses graphics
@ -88,24 +90,79 @@ namespace XenAdmin.Core
return text.Ellipsise(c);
}
public static StringBuilder AppendIndented(this StringBuilder builder, string value, int indent = 2)
/// <summary>
/// Append the input value after it's been prepended with the specified amount of spaces.
/// If the value spans multiple lines, each line will be indented.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder"/> to which the modified value will be appended.</param>
/// <param name="value">The value to prepend with spaces and then append.</param>
/// <param name="indent">The amount of spaces to prepend to each line in the input value.</param>
/// <returns>The input <see cref="StringBuilder"/> after the operation has been completed.</returns>
public static StringBuilder AppendIndented(this StringBuilder builder, string value, int indent = DEFAULT_STRING_INDENTATION)
{
var indentString = "";
var i = 0;
while (i++ < indent)
indentString += " ";
var newvalue = value.Replace(System.Environment.NewLine, string.Format("{0}{1}", System.Environment.NewLine, indentString));
return builder.Append(string.Format("{0}{1}", indentString, newvalue));
return builder.Append(PrependIndentation(value, indent));
}
public static StringBuilder AppendIndented(this StringBuilder builder, StringBuilder value, int indent = 2)
/// <summary>
/// Add a new line to the input <see cref="StringBuilder"/>, with options to format the input value before it's appended.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder"/> to which the modified value will be appended.</param>
/// <param name="value">The value to format before appending.</param>
/// <param name="addTimestamp">true if each line should be prepended with a timestamp</param>
/// <param name="indent">true if each line should be prepended with indentation. Uses the default indentation defined in <see cref="ExtensionMethods"/>: <see cref="DEFAULT_STRING_INDENTATION"/></param>
/// <param name="addExtraLine">true to append an extra line.</param>
/// <returns>The input <see cref="StringBuilder"/> after the operation has been completed.</returns>
public static StringBuilder AppendFormattedLine(this StringBuilder builder, string value, bool addTimestamp = false, bool indent = false, bool addExtraLine = false)
{
var indentString = "";
var i = 0;
while (i++ < indent)
indentString += " ";
var newvalue = value.Replace(System.Environment.NewLine, string.Format("{0}{1}", System.Environment.NewLine, indentString));
return builder.Append(string.Format("{0}{1}", indentString, newvalue));
var formattedValue = value;
if (!string.IsNullOrEmpty(value))
{
if (indent)
{
formattedValue = PrependIndentation(formattedValue);
}
if (addTimestamp)
{
formattedValue = PrependTimestamps(formattedValue);
}
}
builder.AppendLine(formattedValue);
if (addExtraLine)
{
builder.AppendLine();
}
return builder;
}
}
/// <summary>
/// Prepend every line in the input value with the specified indentation level.
/// </summary>
/// <param name="value">The value to which indentation will be applied</param>
/// <param name="indent">The level of indentation, i.e. the number of spaces to prepend to every line in the value.</param>
/// <returns>The input value with prepended indentation./</returns>
private static string PrependIndentation(string value, int indent = DEFAULT_STRING_INDENTATION)
{
var indentString = new string(' ', indent);
var newValue = value.Replace(Environment.NewLine, $"{Environment.NewLine}{indentString}");
return $"{indentString}{newValue}";
}
/// <summary>
/// Prepend every line in the input value with a formatted string of <see cref="DateTime.Now"/>.
/// </summary>
/// <param name="value">The input value</param>
/// <param name="localize">true to format the string with the user's locale</param>
/// <returns>The input value with prepended timestamps/</returns>
public static string PrependTimestamps(string value, bool localize = true)
{
var timestamp = DateTime.Now;
var timestampString = HelpersGUI.DateTimeToString(timestamp, Messages.DATEFORMAT_HMS, localize);
// normalise all line endings before splitting
var lines = value.Replace(Environment.NewLine, "\n").Split('\n');
return string.Join(Environment.NewLine, lines.Select(line => $"{timestampString}> {line}"));
}
}
}

View File

@ -30,6 +30,9 @@ namespace XenAdmin.Dialogs.OptionsPages
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DisplayOptionsPage));
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.updateLogOptionsDecentGroupBox = new XenAdmin.Controls.DecentGroupBox();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.showTimestampsCheckBox = new System.Windows.Forms.CheckBox();
this.GraphTypeGroupBox = new XenAdmin.Controls.DecentGroupBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.label5 = new XenAdmin.Controls.Common.AutoHeightLabel();
@ -41,6 +44,8 @@ namespace XenAdmin.Dialogs.OptionsPages
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.checkBoxStoreTab = new System.Windows.Forms.CheckBox();
this.tableLayoutPanel3.SuspendLayout();
this.updateLogOptionsDecentGroupBox.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.GraphTypeGroupBox.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
@ -52,10 +57,32 @@ namespace XenAdmin.Dialogs.OptionsPages
// tableLayoutPanel3
//
resources.ApplyResources(this.tableLayoutPanel3, "tableLayoutPanel3");
this.tableLayoutPanel3.Controls.Add(this.updateLogOptionsDecentGroupBox, 0, 2);
this.tableLayoutPanel3.Controls.Add(this.GraphTypeGroupBox, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.TabGroupBox, 0, 1);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
//
// updateLogOptionsDecentGroupBox
//
resources.ApplyResources(this.updateLogOptionsDecentGroupBox, "updateLogOptionsDecentGroupBox");
this.updateLogOptionsDecentGroupBox.Controls.Add(this.tableLayoutPanel4);
this.updateLogOptionsDecentGroupBox.Name = "updateLogOptionsDecentGroupBox";
this.updateLogOptionsDecentGroupBox.TabStop = false;
//
// tableLayoutPanel4
//
resources.ApplyResources(this.tableLayoutPanel4, "tableLayoutPanel4");
this.tableLayoutPanel4.Controls.Add(this.showTimestampsCheckBox, 0, 0);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
//
// showTimestampsCheckBox
//
resources.ApplyResources(this.showTimestampsCheckBox, "showTimestampsCheckBox");
this.showTimestampsCheckBox.Checked = true;
this.showTimestampsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.showTimestampsCheckBox.Name = "showTimestampsCheckBox";
this.showTimestampsCheckBox.UseVisualStyleBackColor = true;
//
// GraphTypeGroupBox
//
resources.ApplyResources(this.GraphTypeGroupBox, "GraphTypeGroupBox");
@ -135,6 +162,10 @@ namespace XenAdmin.Dialogs.OptionsPages
this.Name = "DisplayOptionsPage";
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
this.updateLogOptionsDecentGroupBox.ResumeLayout(false);
this.updateLogOptionsDecentGroupBox.PerformLayout();
this.tableLayoutPanel4.ResumeLayout(false);
this.tableLayoutPanel4.PerformLayout();
this.GraphTypeGroupBox.ResumeLayout(false);
this.GraphTypeGroupBox.PerformLayout();
this.tableLayoutPanel1.ResumeLayout(false);
@ -163,5 +194,8 @@ namespace XenAdmin.Dialogs.OptionsPages
private System.Windows.Forms.PictureBox pictureBox2;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.CheckBox checkBoxStoreTab;
private Controls.DecentGroupBox updateLogOptionsDecentGroupBox;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private System.Windows.Forms.CheckBox showTimestampsCheckBox;
}
}

View File

@ -48,6 +48,7 @@ namespace XenAdmin.Dialogs.OptionsPages
GraphAreasRadioButton.Checked = Properties.Settings.Default.FillAreaUnderGraphs;
GraphLinesRadioButton.Checked = !Properties.Settings.Default.FillAreaUnderGraphs;
checkBoxStoreTab.Checked = Properties.Settings.Default.RememberLastSelectedTab;
showTimestampsCheckBox.Checked = Properties.Settings.Default.ShowTimestampsInUpdatesLog;
}
#region IOptionsPage Members
@ -59,20 +60,24 @@ namespace XenAdmin.Dialogs.OptionsPages
public void ShowValidationMessages()
{
// no message
}
public void HideValidationMessages()
{
// no message
}
public void Save()
{
if (GraphAreasRadioButton.Checked != Properties.Settings.Default.FillAreaUnderGraphs)
Properties.Settings.Default.FillAreaUnderGraphs = GraphAreasRadioButton.Checked;
Properties.Settings.Default.FillAreaUnderGraphs = GraphAreasRadioButton.Checked;
if (checkBoxStoreTab.Checked != Properties.Settings.Default.RememberLastSelectedTab)
Properties.Settings.Default.RememberLastSelectedTab = checkBoxStoreTab.Checked;
if (showTimestampsCheckBox.Checked != Properties.Settings.Default.ShowTimestampsInUpdatesLog)
Properties.Settings.Default.ShowTimestampsInUpdatesLog = showTimestampsCheckBox.Checked;
}
#endregion

View File

@ -128,6 +128,115 @@
<data name="tableLayoutPanel3.ColumnCount" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="updateLogOptionsDecentGroupBox.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="updateLogOptionsDecentGroupBox.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
<value>GrowAndShrink</value>
</data>
<data name="tableLayoutPanel4.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="tableLayoutPanel4.ColumnCount" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="showTimestampsCheckBox.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="showTimestampsCheckBox.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="showTimestampsCheckBox.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 3</value>
</data>
<data name="showTimestampsCheckBox.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 0, 0, 0</value>
</data>
<data name="showTimestampsCheckBox.Size" type="System.Drawing.Size, System.Drawing">
<value>201, 17</value>
</data>
<data name="showTimestampsCheckBox.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="showTimestampsCheckBox.Text" xml:space="preserve">
<value>Show timestamps in the update logs</value>
</data>
<data name="&gt;&gt;showTimestampsCheckBox.Name" xml:space="preserve">
<value>showTimestampsCheckBox</value>
</data>
<data name="&gt;&gt;showTimestampsCheckBox.Type" xml:space="preserve">
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;showTimestampsCheckBox.Parent" xml:space="preserve">
<value>tableLayoutPanel4</value>
</data>
<data name="&gt;&gt;showTimestampsCheckBox.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tableLayoutPanel4.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="tableLayoutPanel4.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 16</value>
</data>
<data name="tableLayoutPanel4.RowCount" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="tableLayoutPanel4.Size" type="System.Drawing.Size, System.Drawing">
<value>617, 49</value>
</data>
<data name="tableLayoutPanel4.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="&gt;&gt;tableLayoutPanel4.Name" xml:space="preserve">
<value>tableLayoutPanel4</value>
</data>
<data name="&gt;&gt;tableLayoutPanel4.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableLayoutPanel4.Parent" xml:space="preserve">
<value>updateLogOptionsDecentGroupBox</value>
</data>
<data name="&gt;&gt;tableLayoutPanel4.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tableLayoutPanel4.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="showTimestampsCheckBox" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,Absolute,49,Absolute,49,Absolute,49" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="updateLogOptionsDecentGroupBox.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="updateLogOptionsDecentGroupBox.Font" type="System.Drawing.Font, System.Drawing">
<value>Tahoma, 8pt</value>
</data>
<data name="updateLogOptionsDecentGroupBox.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 337</value>
</data>
<data name="updateLogOptionsDecentGroupBox.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 3, 3, 6</value>
</data>
<data name="updateLogOptionsDecentGroupBox.Size" type="System.Drawing.Size, System.Drawing">
<value>623, 71</value>
</data>
<data name="updateLogOptionsDecentGroupBox.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="updateLogOptionsDecentGroupBox.Text" xml:space="preserve">
<value>Update logs options</value>
</data>
<data name="&gt;&gt;updateLogOptionsDecentGroupBox.Name" xml:space="preserve">
<value>updateLogOptionsDecentGroupBox</value>
</data>
<data name="&gt;&gt;updateLogOptionsDecentGroupBox.Type" xml:space="preserve">
<value>XenAdmin.Controls.DecentGroupBox, [XenCenter_No_Space]Main, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;updateLogOptionsDecentGroupBox.Parent" xml:space="preserve">
<value>tableLayoutPanel3</value>
</data>
<data name="&gt;&gt;updateLogOptionsDecentGroupBox.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="GraphTypeGroupBox.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
@ -146,7 +255,6 @@
<data name="label5.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="label5.Font" type="System.Drawing.Font, System.Drawing">
<value>Tahoma, 8pt</value>
</data>
@ -172,7 +280,7 @@
<value>label5</value>
</data>
<data name="&gt;&gt;label5.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>XenAdmin.Controls.Common.AutoHeightLabel, [XenCenter_No_Space]Main, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;label5.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
@ -373,13 +481,13 @@
<value>GraphTypeGroupBox</value>
</data>
<data name="&gt;&gt;GraphTypeGroupBox.Type" xml:space="preserve">
<value>XenAdmin.Controls.DecentGroupBox, XenCenterMain, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
<value>XenAdmin.Controls.DecentGroupBox, [XenCenter_No_Space]Main, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;GraphTypeGroupBox.Parent" xml:space="preserve">
<value>tableLayoutPanel3</value>
</data>
<data name="&gt;&gt;GraphTypeGroupBox.ZOrder" xml:space="preserve">
<value>0</value>
<value>1</value>
</data>
<data name="TabGroupBox.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
@ -481,13 +589,13 @@
<value>TabGroupBox</value>
</data>
<data name="&gt;&gt;TabGroupBox.Type" xml:space="preserve">
<value>XenAdmin.Controls.DecentGroupBox, XenCenterMain, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
<value>XenAdmin.Controls.DecentGroupBox, [XenCenter_No_Space]Main, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;TabGroupBox.Parent" xml:space="preserve">
<value>tableLayoutPanel3</value>
</data>
<data name="&gt;&gt;TabGroupBox.ZOrder" xml:space="preserve">
<value>1</value>
<value>2</value>
</data>
<data name="tableLayoutPanel3.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
@ -520,7 +628,7 @@
<value>0</value>
</data>
<data name="tableLayoutPanel3.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="GraphTypeGroupBox" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="TabGroupBox" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,AutoSize,0,Percent,100,Absolute,20,Absolute,20,Absolute,20" /&gt;&lt;/TableLayoutSettings&gt;</value>
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="updateLogOptionsDecentGroupBox" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="GraphTypeGroupBox" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="TabGroupBox" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,AutoSize,0,Percent,100,Absolute,20,Absolute,20,Absolute,20" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>

View File

@ -865,5 +865,18 @@ namespace XenAdmin.Properties {
this["IgnoreFirstRunWizards"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
[global::System.Configuration.SettingsManageabilityAttribute(global::System.Configuration.SettingsManageability.Roaming)]
public bool ShowTimestampsInUpdatesLog {
get {
return ((bool)(this["ShowTimestampsInUpdatesLog"]));
}
set {
this["ShowTimestampsInUpdatesLog"] = value;
}
}
}
}

View File

@ -200,5 +200,8 @@
<Value Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
&lt;ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" /&gt;</Value>
</Setting>
<Setting Name="ShowTimestampsInUpdatesLog" Roaming="true" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -97,7 +97,8 @@ namespace XenAdmin.Wizards.PatchingWizard
return;
using (var dialog = new WarningDialog(ReconsiderCancellationMessage(),
ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo){WindowTitle = Text})
ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo)
{ WindowTitle = Text })
{
if (dialog.ShowDialog(this) != DialogResult.Yes)
{
@ -164,7 +165,7 @@ namespace XenAdmin.Wizards.PatchingWizard
_backgroundWorkers = new List<UpdateProgressBackgroundWorker>();
_failedWorkers = new List<UpdateProgressBackgroundWorker>();
var atLeastOneWorkerStarted = false;
foreach (var pool in SelectedPools)
{
var planActions = GenerateHostPlans(pool, out _);
@ -253,10 +254,12 @@ namespace XenAdmin.Wizards.PatchingWizard
newVal = 0;
else if (newVal > 100)
newVal = 100;
progressBar.Value = (int) newVal;
progressBar.Value = (int)newVal;
var stringBuilder = new StringBuilder();
var addTimestamp = Properties.Settings.Default.ShowTimestampsInUpdatesLog;
foreach (var bgw in _backgroundWorkers)
{
var bgwErrorCount = 0;
@ -265,13 +268,13 @@ namespace XenAdmin.Wizards.PatchingWizard
var errorSb = new StringBuilder();
if (!string.IsNullOrEmpty(bgw.Name))
sb.AppendLine($"{bgw.Name}:");
sb.AppendFormattedLine($"{bgw.Name}:", addTimestamp);
foreach (var pa in bgw.DoneActions)
{
pa.ProgressHistory.ForEach(step => sb.AppendIndented(step).AppendLine());
pa.ProgressHistory.ForEach(step => sb.AppendFormattedLine(step, addTimestamp, true));
if (pa.Error == null)
if (pa.Error == null)
continue;
if (pa.Error is CancelledException)
@ -279,14 +282,12 @@ namespace XenAdmin.Wizards.PatchingWizard
bgwCancellationCount++;
continue;
}
errorSb.AppendLine(!(pa.Error.InnerException is Failure innerEx) ? pa.Error.Message : innerEx.Message);
errorSb.AppendFormattedLine(!(pa.Error.InnerException is Failure innerEx) ? pa.Error.Message : innerEx.Message, addTimestamp, true, true);
if (pa.IsSkippable)
{
Debug.Assert(!string.IsNullOrEmpty(pa.Title));
errorSb.AppendLine(string.Format(Messages.RPU_WIZARD_ERROR_SKIP_MSG, pa.Title))
.AppendLine();
errorSb.AppendFormattedLine(string.Format(Messages.RPU_WIZARD_ERROR_SKIP_MSG, pa.Title), addTimestamp, true, true);
}
bgwErrorCount++;
@ -294,23 +295,25 @@ namespace XenAdmin.Wizards.PatchingWizard
foreach (var pa in bgw.InProgressActions)
{
pa.ProgressHistory.ForEach(step => sb.AppendIndented(step).AppendLine());
pa.ProgressHistory.ForEach(step => sb.AppendFormattedLine(step, addTimestamp, true));
}
sb.AppendLine();
if (bgwCancellationCount > 0)
{
sb.AppendIndented(UserCancellationMessage()).AppendLine();
sb.AppendFormattedLine(UserCancellationMessage(), addTimestamp, indent: true);
}
else if (bgwErrorCount > 0)
{
sb.AppendIndented(FailureMessagePerPool(bgwErrorCount > 1)).AppendLine();
sb.AppendIndented(errorSb);
sb.AppendFormattedLine(FailureMessagePerPool(bgwErrorCount > 1), addTimestamp, true);
// we don't add formatting since errorSb has its own
sb.Append(errorSb.ToString());
}
else if (!bgw.IsBusy)
{
sb.AppendIndented(WarningMessagePerPool(bgw.Pool) ?? SuccessMessagePerPool(bgw.Pool)).AppendLine();
sb.AppendFormattedLine(WarningMessagePerPool(bgw.Pool) ?? SuccessMessagePerPool(bgw.Pool), addTimestamp, true);
}
sb.AppendLine();
@ -318,7 +321,7 @@ namespace XenAdmin.Wizards.PatchingWizard
}
var newText = stringBuilder.ToString();
if (!_userMovedVerticalScrollbar)
{
textBoxLog.Text = newText;
@ -361,7 +364,7 @@ namespace XenAdmin.Wizards.PatchingWizard
// Step 2: UpdatesPlanActions (priority update action)
bgw.ProgressIncrement = bgw.UpdatesActionsIncrement(hp);
var planActions = hp.UpdatesPlanActions;
var planActions = hp.UpdatesPlanActions;
foreach (var a in planActions)
{
action = a;
@ -539,7 +542,7 @@ namespace XenAdmin.Wizards.PatchingWizard
using (var dlg = new WarningDialog(string.Format(skippableWorkers.Count > 1 ? Messages.MESSAGEBOX_SKIP_RPU_STEPS : Messages.MESSAGEBOX_SKIP_RPU_STEP, msg),
ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo)
{WindowTitle = ParentForm != null ? ParentForm.Text : BrandManager.BrandConsole})
{ WindowTitle = ParentForm != null ? ParentForm.Text : BrandManager.BrandConsole })
{
if (dlg.ShowDialog(this) != DialogResult.Yes)
return;
@ -578,7 +581,7 @@ namespace XenAdmin.Wizards.PatchingWizard
}
}
#endregion
protected HostPlan GetUpdatePlanActionsForHost(Host host, List<Host> hosts, List<XenServerPatch> minimalPatches,
List<XenServerPatch> uploadedPatches, KeyValuePair<XenServerPatch, string> patchFromDisk, bool repatriateVms = true)
{
@ -651,7 +654,7 @@ namespace XenAdmin.Wizards.PatchingWizard
?? planActionsPerHost.FindLast(a => a is RestartHostPlanAction);
if (lastRestart != null)
((RestartHostPlanAction) lastRestart).EnableOnly = false;
((RestartHostPlanAction)lastRestart).EnableOnly = false;
}
return new HostPlan(host, null, planActionsPerHost, delayedActionsPerHost);

View File

@ -106,7 +106,7 @@ namespace XenAdmin.Wizards.PatchingWizard
foreach (var kvp in ManualTextInstructions)
{
sb.AppendFormat("{0}:", kvp.Key).AppendLine();
sb.AppendIndented(kvp.Value).AppendLine();
sb.AppendIndented(kvp.Value.ToString()).AppendLine();
}
textBoxLog.Text = sb.ToString();
}

View File

@ -195,6 +195,9 @@
<ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
</value>
</setting>
<setting name="ShowTimestampsInUpdatesLog" serializeAs="String">
<value>True</value>
</setting>
</XenAdmin.Properties.Settings>
</userSettings>