Merge pull request #97 from MihaelaStoica/CP-8547

CP-8547: Add button in XenCenter to initiate space reclamation on an SR.
This commit is contained in:
Stephen Turner 2014-06-24 15:29:08 +01:00
commit 7d2e113130
12 changed files with 546 additions and 131 deletions

View File

@ -0,0 +1,80 @@
/* Copyright (c) Citrix Systems Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System.Collections.Generic;
using XenAdmin.Actions;
using XenAdmin.Core;
using XenAPI;
namespace XenAdmin.Commands
{
internal class TrimSRCommand : SRCommand
{
/// <summary>
/// Initializes a new instance of this Command. The parameter-less constructor is required in the derived
/// class if it is to be attached to a ToolStrip menu item or button. It should not be used in any other scenario.
/// </summary>
public TrimSRCommand()
{
}
public TrimSRCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection)
: base(mainWindow, selection)
{
}
public TrimSRCommand(IMainWindow mainWindow, SR sr)
: base(mainWindow, sr)
{
}
protected override void ExecuteCore(SelectedItemCollection selection)
{
var actions = new List<AsyncAction>();
foreach (SR sr in selection.AsXenObjects<SR>(CanExecute))
{
actions.Add(new SrTrimAction(sr.Connection, sr));
}
RunMultipleActions(actions, null, Messages.ACTION_SR_TRIM_DESCRIPTION, Messages.ACTION_SR_TRIM_DONE, true);
}
protected override bool CanExecuteCore(SelectedItemCollection selection)
{
return selection.AllItemsAre<SR>() && selection.AtLeastOneXenObjectCan<SR>(CanExecute);
}
private static bool CanExecute(SR sr)
{
return sr != null && sr.SupportsTrim;
}
}
}

View File

@ -35,21 +35,24 @@ namespace XenAdmin.TabPages
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PhysicalStoragePage));
this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.listViewSrs = new XenAdmin.Controls.ListViewEx();
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
this.columnHeader4 = new System.Windows.Forms.ColumnHeader();
this.columnHeader5 = new System.Windows.Forms.ColumnHeader();
this.columnHeader6 = new System.Windows.Forms.ColumnHeader();
this.columnHeader7 = new System.Windows.Forms.ColumnHeader();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader6 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader7 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.labelNetworkheadings = new System.Windows.Forms.Label();
this.TitleLabel = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.newSRButton = new XenAdmin.Commands.CommandButton();
this.trimButton = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.buttonProperties = new System.Windows.Forms.Button();
this.newSRButton = new XenAdmin.Commands.CommandButton();
this.pageContainerPanel.SuspendLayout();
this.panel1.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// pageContainerPanel
@ -67,7 +70,6 @@ namespace XenAdmin.TabPages
// listViewSrs
//
this.listViewSrs.AllowColumnReorder = true;
resources.ApplyResources(this.listViewSrs, "listViewSrs");
this.listViewSrs.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2,
@ -77,6 +79,7 @@ namespace XenAdmin.TabPages
this.columnHeader6,
this.columnHeader7});
this.listViewSrs.ContextMenuStrip = this.contextMenuStrip;
resources.ApplyResources(this.listViewSrs, "listViewSrs");
this.listViewSrs.HideSelection = false;
this.listViewSrs.MultiSelect = false;
this.listViewSrs.Name = "listViewSrs";
@ -126,13 +129,33 @@ namespace XenAdmin.TabPages
// panel1
//
resources.ApplyResources(this.panel1, "panel1");
this.panel1.Controls.Add(this.groupBox1);
this.panel1.Controls.Add(this.buttonProperties);
this.panel1.Controls.Add(this.newSRButton);
this.panel1.Controls.Add(this.listViewSrs);
this.panel1.MaximumSize = new System.Drawing.Size(900, 400);
this.panel1.Controls.Add(this.flowLayoutPanel1);
this.panel1.Name = "panel1";
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Controls.Add(this.newSRButton);
this.flowLayoutPanel1.Controls.Add(this.trimButton);
this.flowLayoutPanel1.Controls.Add(this.groupBox1);
this.flowLayoutPanel1.Controls.Add(this.buttonProperties);
resources.ApplyResources(this.flowLayoutPanel1, "flowLayoutPanel1");
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
//
// newSRButton
//
this.newSRButton.Command = new XenAdmin.Commands.NewSRCommand();
resources.ApplyResources(this.newSRButton, "newSRButton");
this.newSRButton.Name = "newSRButton";
this.newSRButton.UseVisualStyleBackColor = true;
//
// trimButton
//
resources.ApplyResources(this.trimButton, "trimButton");
this.trimButton.Name = "trimButton";
this.trimButton.UseVisualStyleBackColor = true;
this.trimButton.Click += new System.EventHandler(this.trimButton_Click);
//
// groupBox1
//
resources.ApplyResources(this.groupBox1, "groupBox1");
@ -146,13 +169,6 @@ namespace XenAdmin.TabPages
this.buttonProperties.UseVisualStyleBackColor = true;
this.buttonProperties.Click += new System.EventHandler(this.buttonProperties_Click);
//
// newSRButton
//
resources.ApplyResources(this.newSRButton, "newSRButton");
this.newSRButton.Command = new XenAdmin.Commands.NewSRCommand();
this.newSRButton.Name = "newSRButton";
this.newSRButton.UseVisualStyleBackColor = true;
//
// PhysicalStoragePage
//
resources.ApplyResources(this, "$this");
@ -164,7 +180,9 @@ namespace XenAdmin.TabPages
this.pageContainerPanel.ResumeLayout(false);
this.pageContainerPanel.PerformLayout();
this.panel1.ResumeLayout(false);
this.flowLayoutPanel1.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
@ -185,5 +203,7 @@ namespace XenAdmin.TabPages
private System.Windows.Forms.Button buttonProperties;
private System.Windows.Forms.GroupBox groupBox1;
private XenAdmin.Commands.CommandButton newSRButton;
private System.Windows.Forms.Button trimButton;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
}
}

View File

@ -374,6 +374,30 @@ namespace XenAdmin.TabPages
private void RefreshButtons()
{
buttonProperties.Enabled = listViewSrs.SelectedItems.Count == 1;
// Trim button
if (listViewSrs.SelectedItems.Count == 1)
{
SR sr = (SR)listViewSrs.SelectedItems[0].Tag;
TrimSRCommand trimCmd = new TrimSRCommand(Program.MainWindow, sr);
trimButton.Visible = trimCmd.CanExecute();
}
else
{
trimButton.Visible = false;
}
}
private void trimButton_Click(object sender, EventArgs e)
{
if (listViewSrs.SelectedItems.Count != 1)
return;
SR sr = (SR)listViewSrs.SelectedItems[0].Tag;
TrimSRCommand trimCmd = new TrimSRCommand(Program.MainWindow, sr);
if (trimCmd.CanExecute())
trimCmd.Execute();
}
}

View File

@ -112,107 +112,19 @@
<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="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="panel1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
</data>
<data name="groupBox1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="groupBox1.Location" type="System.Drawing.Point, System.Drawing">
<value>108, 306</value>
</data>
<data name="groupBox1.Size" type="System.Drawing.Size, System.Drawing">
<value>2, 20</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="groupBox1.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;groupBox1.Name" xml:space="preserve">
<value>groupBox1</value>
</data>
<data name="&gt;&gt;groupBox1.Type" xml:space="preserve">
<value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;groupBox1.Parent" xml:space="preserve">
<value>panel1</value>
</data>
<data name="&gt;&gt;groupBox1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="buttonProperties.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
</data>
<data name="buttonProperties.Location" type="System.Drawing.Point, System.Drawing">
<value>116, 306</value>
</data>
<data name="buttonProperties.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 23</value>
</data>
<data name="buttonProperties.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="buttonProperties.Text" xml:space="preserve">
<value>P&amp;roperties</value>
</data>
<data name="&gt;&gt;buttonProperties.Name" xml:space="preserve">
<value>buttonProperties</value>
</data>
<data name="&gt;&gt;buttonProperties.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonProperties.Parent" xml:space="preserve">
<value>panel1</value>
</data>
<data name="&gt;&gt;buttonProperties.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="newSRButton.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
</data>
<data name="newSRButton.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 306</value>
</data>
<data name="newSRButton.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>0, 0, 0, 0</value>
</data>
<data name="newSRButton.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 23</value>
</data>
<data name="newSRButton.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="newSRButton.Text" xml:space="preserve">
<value>&amp;New SR...</value>
</data>
<data name="&gt;&gt;newSRButton.Name" xml:space="preserve">
<value>newSRButton</value>
</data>
<data name="&gt;&gt;newSRButton.Type" xml:space="preserve">
<value>XenAdmin.Commands.CommandButton, XenCenterMain, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;newSRButton.Parent" xml:space="preserve">
<value>panel1</value>
</data>
<data name="&gt;&gt;newSRButton.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="listViewSrs.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
</data>
<data name="columnHeader1.Text" xml:space="preserve">
<value>Name</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="columnHeader1.Width" type="System.Int32, mscorlib">
<value>160</value>
</data>
@ -249,9 +161,10 @@
<data name="columnHeader7.Width" type="System.Int32, mscorlib">
<value>119</value>
</data>
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
<value>61, 4</value>
</data>
@ -259,16 +172,19 @@
<value>contextMenuStrip</value>
</data>
<data name="&gt;&gt;contextMenuStrip.Type" xml:space="preserve">
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="listViewSrs.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="listViewSrs.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 1</value>
<value>0, 0</value>
</data>
<data name="listViewSrs.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>0, 0, 0, 5</value>
</data>
<data name="listViewSrs.Size" type="System.Drawing.Size, System.Drawing">
<value>897, 300</value>
<value>897, 259</value>
</data>
<data name="listViewSrs.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@ -283,13 +199,160 @@
<value>panel1</value>
</data>
<data name="&gt;&gt;listViewSrs.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="newSRButton.Location" type="System.Drawing.Point, System.Drawing">
<value>3, 5</value>
</data>
<data name="newSRButton.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 0, 3, 0</value>
</data>
<data name="newSRButton.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 23</value>
</data>
<data name="newSRButton.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="newSRButton.Text" xml:space="preserve">
<value>&amp;New SR...</value>
</data>
<data name="&gt;&gt;newSRButton.Name" xml:space="preserve">
<value>newSRButton</value>
</data>
<data name="&gt;&gt;newSRButton.Type" xml:space="preserve">
<value>XenAdmin.Commands.CommandButton, XenCenterMain, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;newSRButton.Parent" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="&gt;&gt;newSRButton.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="trimButton.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Right</value>
</data>
<data name="trimButton.Location" type="System.Drawing.Point, System.Drawing">
<value>111, 5</value>
</data>
<data name="trimButton.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 0, 3, 0</value>
</data>
<data name="trimButton.Size" type="System.Drawing.Size, System.Drawing">
<value>127, 23</value>
</data>
<data name="trimButton.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="trimButton.Text" xml:space="preserve">
<value>Re&amp;claim freed space</value>
</data>
<data name="&gt;&gt;trimButton.Name" xml:space="preserve">
<value>trimButton</value>
</data>
<data name="&gt;&gt;trimButton.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;trimButton.Parent" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="&gt;&gt;trimButton.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="groupBox1.Location" type="System.Drawing.Point, System.Drawing">
<value>244, 5</value>
</data>
<data name="groupBox1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 0, 3, 0</value>
</data>
<data name="groupBox1.Size" type="System.Drawing.Size, System.Drawing">
<value>2, 20</value>
</data>
<data name="groupBox1.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="groupBox1.Text" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;groupBox1.Name" xml:space="preserve">
<value>groupBox1</value>
</data>
<data name="&gt;&gt;groupBox1.Type" xml:space="preserve">
<value>System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;groupBox1.Parent" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="&gt;&gt;groupBox1.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="buttonProperties.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Right</value>
</data>
<data name="buttonProperties.Location" type="System.Drawing.Point, System.Drawing">
<value>252, 5</value>
</data>
<data name="buttonProperties.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 0, 3, 0</value>
</data>
<data name="buttonProperties.Size" type="System.Drawing.Size, System.Drawing">
<value>102, 23</value>
</data>
<data name="buttonProperties.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="buttonProperties.Text" xml:space="preserve">
<value>P&amp;roperties</value>
</data>
<data name="&gt;&gt;buttonProperties.Name" xml:space="preserve">
<value>buttonProperties</value>
</data>
<data name="&gt;&gt;buttonProperties.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;buttonProperties.Parent" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="&gt;&gt;buttonProperties.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="flowLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Bottom</value>
</data>
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 259</value>
</data>
<data name="flowLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>0, 5, 0, 0</value>
</data>
<data name="flowLayoutPanel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>0, 5, 0, 0</value>
</data>
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
<value>897, 34</value>
</data>
<data name="flowLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
<value>5</value>
</data>
<data name="&gt;&gt;flowLayoutPanel1.Name" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="&gt;&gt;flowLayoutPanel1.Type" xml:space="preserve">
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;flowLayoutPanel1.Parent" xml:space="preserve">
<value>panel1</value>
</data>
<data name="&gt;&gt;flowLayoutPanel1.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
<value>10, 35</value>
</data>
<data name="panel1.MaximumSize" type="System.Drawing.Size, System.Drawing">
<value>900, 400</value>
</data>
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
<value>897, 334</value>
<value>897, 293</value>
</data>
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@ -298,7 +361,7 @@
<value>panel1</value>
</data>
<data name="&gt;&gt;panel1.Type" xml:space="preserve">
<value>System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;panel1.Parent" xml:space="preserve">
<value>pageContainerPanel</value>
@ -337,7 +400,7 @@
<value>labelNetworkheadings</value>
</data>
<data name="&gt;&gt;labelNetworkheadings.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;labelNetworkheadings.Parent" xml:space="preserve">
<value>pageContainerPanel</value>
@ -345,8 +408,11 @@
<data name="&gt;&gt;labelNetworkheadings.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="pageContainerPanel.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 78</value>
</data>
<data name="pageContainerPanel.Size" type="System.Drawing.Size, System.Drawing">
<value>920, 385</value>
<value>920, 344</value>
</data>
<data name="pageContainerPanel.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
@ -355,7 +421,7 @@
<value>pageContainerPanel</value>
</data>
<data name="&gt;&gt;pageContainerPanel.Type" xml:space="preserve">
<value>System.Windows.Forms.Panel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;pageContainerPanel.Parent" xml:space="preserve">
<value>$this</value>
@ -394,9 +460,9 @@
<value>TitleLabel</value>
</data>
<data name="&gt;&gt;TitleLabel.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<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">
@ -412,43 +478,43 @@
<value>columnHeader1</value>
</data>
<data name="&gt;&gt;columnHeader1.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader2.Name" xml:space="preserve">
<value>columnHeader2</value>
</data>
<data name="&gt;&gt;columnHeader2.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader3.Name" xml:space="preserve">
<value>columnHeader3</value>
</data>
<data name="&gt;&gt;columnHeader3.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader4.Name" xml:space="preserve">
<value>columnHeader4</value>
</data>
<data name="&gt;&gt;columnHeader4.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader5.Name" xml:space="preserve">
<value>columnHeader5</value>
</data>
<data name="&gt;&gt;columnHeader5.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader6.Name" xml:space="preserve">
<value>columnHeader6</value>
</data>
<data name="&gt;&gt;columnHeader6.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;columnHeader7.Name" xml:space="preserve">
<value>columnHeader7</value>
</data>
<data name="&gt;&gt;columnHeader7.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>PhysicalStoragePage</value>

View File

@ -123,6 +123,7 @@
<Compile Include="Commands\Controls\EditPropertiesToolStripMenuItem.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Commands\TrimSRCommand.cs" />
<Compile Include="Controls\AffinityPicker.cs">
<SubType>UserControl</SubType>
</Compile>

View File

@ -0,0 +1,137 @@
/* Copyright (c) Citrix Systems Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using XenAdmin.Core;
using XenAdmin.Network;
using XenAPI;
namespace XenAdmin.Actions
{
public class SrTrimAction : PureAsyncAction
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public SrTrimAction(IXenConnection connection, SR sr)
: base(connection, string.Format(Messages.ACTION_SR_TRIM_TITLE, sr.NameWithoutHost), false)
{
SR = sr;
}
protected override void Run()
{
Description = Messages.ACTION_SR_TRIM_DESCRIPTION;
var host = Helpers.GetMaster(Connection);
var result = false;
try
{
var args = new Dictionary<string, string> { { "sr_uuid", SR.uuid } };
Result = Host.call_plugin(Session, host.opaque_ref, "trim", "do_trim", args);
result = Result.ToLower() == "true";
}
catch (Failure failure)
{
log.WarnFormat("Plugin call trim.do_trim({0}) on {1} failed with {2}", SR.uuid, host.Name,
failure.Message);
throw;
}
if (result)
Description = Messages.ACTION_SR_TRIM_DONE;
else
{
log.WarnFormat("Plugin call trim.do_trim({0}) on {1} failed with {2}", SR.uuid, host.Name, Result);
var error = GetTrimError(Result);
Exception = new Exception(error ?? Messages.ERROR_UNKNOWN);
}
}
/* Example of trim output in case of exception:
<trim_response>
<key_value_pair>
<key>errcode</key>
<value>UnsupportedSRForTrim</value>
</key_value_pair>
<key_value_pair>
<key>errmsg</key>
<value>Trim on [some-uuid] not supported</value>
</key_value_pair>
</trim_response>
*/
private static string GetTrimError(string xml)
{
try
{
var doc = new XmlDocument();
doc.LoadXml(xml);
string errcode = null;
string errmsg = null;
var kvpNodes = doc.SelectNodes("/trim_response/key_value_pair");
if (kvpNodes == null)
return null;
foreach (XmlNode kvpNode in kvpNodes)
{
var keyNode = kvpNode.ChildNodes.Cast<XmlNode>().FirstOrDefault(node => node.Name == "key");
var valueNode = kvpNode.ChildNodes.Cast<XmlNode>().FirstOrDefault(node => node.Name == "value");
if (keyNode != null && valueNode != null && keyNode.InnerText == "errcode")
errcode = valueNode.InnerText;
if (keyNode != null && valueNode != null && keyNode.InnerText == "errmsg")
errmsg = valueNode.InnerText;
}
return GetErrorMessageFromResources(errcode) ?? errmsg;
}
catch (Exception e)
{
log.DebugFormat("Exception parsing xml '{0}'", xml.Substring(0, 10000));
log.Debug(e, e);
return null;
}
}
private static string GetErrorMessageFromResources(string errCode)
{
if (errCode == null)
return null;
return PropertyManager.GetFriendlyName("Message.name-" + errCode);
}
}
}

View File

@ -4094,6 +4094,33 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Cannot reclaim freed space because the SR is already busy.
/// </summary>
public static string Message_name_SRUnavailable {
get {
return ResourceManager.GetString("Message.name-SRUnavailable", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An unknown error occurred when reclaiming freed space.
/// </summary>
public static string Message_name_UnknownTrimException {
get {
return ResourceManager.GetString("Message.name-UnknownTrimException", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reclaiming freed space not supported on this SR.
/// </summary>
public static string Message_name_UnsupportedSRForTrim {
get {
return ResourceManager.GetString("Message.name-UnsupportedSRForTrim", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to VM Disk QoS Failed.
/// </summary>

View File

@ -1679,4 +1679,13 @@
<data name="Label-host.edition-free/libre" xml:space="preserve">
<value>Citrix XenServer</value>
</data>
<data name="Message.name-SRUnavailable" xml:space="preserve">
<value>Cannot reclaim freed space because the SR is already busy</value>
</data>
<data name="Message.name-UnknownTrimException" xml:space="preserve">
<value>An unknown error occurred when reclaiming freed space</value>
</data>
<data name="Message.name-UnsupportedSRForTrim" xml:space="preserve">
<value>Reclaiming freed space not supported on this SR</value>
</data>
</root>

View File

@ -1689,6 +1689,33 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Reclaiming freed space.
/// </summary>
public static string ACTION_SR_TRIM_DESCRIPTION {
get {
return ResourceManager.GetString("ACTION_SR_TRIM_DESCRIPTION", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Completed.
/// </summary>
public static string ACTION_SR_TRIM_DONE {
get {
return ResourceManager.GetString("ACTION_SR_TRIM_DONE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reclaiming freed space on SR &apos;{0}&apos;.
/// </summary>
public static string ACTION_SR_TRIM_TITLE {
get {
return ResourceManager.GetString("ACTION_SR_TRIM_TITLE", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Upgrade SR &apos;{0}&apos; on &apos;{1}&apos;.
/// </summary>

View File

@ -681,6 +681,15 @@
<data name="ACTION_SR_SHARING" xml:space="preserve">
<value>Sharing SR {0}</value>
</data>
<data name="ACTION_SR_TRIM_DESCRIPTION" xml:space="preserve">
<value>Reclaiming freed space</value>
</data>
<data name="ACTION_SR_TRIM_DONE" xml:space="preserve">
<value>Completed</value>
</data>
<data name="ACTION_SR_TRIM_TITLE" xml:space="preserve">
<value>Reclaiming freed space on SR '{0}'</value>
</data>
<data name="ACTION_SR_UPGRADE" xml:space="preserve">
<value>Upgrade SR '{0}' on '{1}'</value>
</data>

View File

@ -1032,7 +1032,21 @@ namespace XenAPI
SRTypes currentType = sr.GetSRType(true);
return currentType == SRTypes.cslg || currentType == SRTypes.equal || currentType == SRTypes.netapp;
}
/// <summary>
/// Whether the underlying SR backend supports SR_TRIM
/// </summary>
/// <returns></returns>
public bool SupportsTrim
{
get
{
System.Diagnostics.Trace.Assert(Connection != null, "Connection must not be null");
SM sm = SM.GetByType(Connection, type);
return sm != null && sm.features != null && sm.features.ContainsKey("SR_TRIM");
}
}
#region IEquatable<SR> Members

View File

@ -91,6 +91,7 @@
<Compile Include="Actions\Pool_Patch\CopyPatchFromHostToOther.cs" />
<Compile Include="Actions\Pool_Patch\UploadPatchAction.cs" />
<Compile Include="Actions\ProduceConsumerQueue.cs" />
<Compile Include="Actions\SR\SrTrimAction.cs" />
<Compile Include="Actions\StorageLink\SrCslgAdaptersScanAction.cs" />
<Compile Include="Actions\Updates\DownloadAndUnzipXenServerPatchAction.cs" />
<Compile Include="Actions\Updates\DownloadUpdatesXmlAction.cs" />