mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2025-01-20 07:19:18 +01:00
Prevent crash and improve behaviour when the user tries to configure/disable HA in a pool that has lost the HA statefile.
Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
This commit is contained in:
parent
dd81a5d14c
commit
8f2794b89d
@ -38,6 +38,8 @@ using XenAdmin.Core;
|
||||
using XenAdmin.Dialogs;
|
||||
using XenAdmin.Wizards;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace XenAdmin.Commands
|
||||
@ -47,6 +49,8 @@ namespace XenAdmin.Commands
|
||||
/// </summary>
|
||||
internal class HACommand : Command
|
||||
{
|
||||
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of this Command. The parameter-less constructor is required if
|
||||
/// this Command is to be attached to a ToolStrip menu item or button. It should not be used in any other scenario.
|
||||
@ -88,8 +92,27 @@ namespace XenAdmin.Commands
|
||||
}
|
||||
else if (pool.ha_enabled)
|
||||
{
|
||||
// Show VM restart priority editor
|
||||
MainWindowCommandInterface.ShowPerConnectionWizard(connection, new EditVmHaPrioritiesDialog(pool));
|
||||
if (pool.ha_statefiles.Any(sf => pool.Connection.Resolve(new XenRef<VDI>(sf)) != null))
|
||||
{
|
||||
// Show VM restart priority editor
|
||||
MainWindowCommandInterface.ShowPerConnectionWizard(connection, new EditVmHaPrioritiesDialog(pool));
|
||||
}
|
||||
else
|
||||
{
|
||||
log.ErrorFormat("Cannot resolve HA statefile VDI (pool {0} has {1} statefiles).",
|
||||
pool.Name(), pool.ha_statefiles.Length);
|
||||
|
||||
using (var dlg = new ThreeButtonDialog(
|
||||
new ThreeButtonDialog.Details(
|
||||
SystemIcons.Error,
|
||||
string.Format(Messages.HA_CONFIGURE_NO_STATEFILE, Helpers.GetName(pool).Ellipsise(30)),
|
||||
Messages.CONFIGURE_HA),
|
||||
"HADisable",
|
||||
ThreeButtonDialog.ButtonOK))
|
||||
{
|
||||
dlg.ShowDialog(Program.MainWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -105,26 +128,24 @@ namespace XenAdmin.Commands
|
||||
|
||||
protected override bool CanExecuteCore(SelectedItemCollection selection)
|
||||
{
|
||||
if (selection.Count == 1)
|
||||
{
|
||||
Pool poolAncestor = selection[0].PoolAncestor;
|
||||
bool inPool = poolAncestor != null;
|
||||
if (selection.Count != 1)
|
||||
return false;
|
||||
|
||||
if (inPool )
|
||||
{
|
||||
Host master = Helpers.GetMaster(poolAncestor.Connection);
|
||||
Pool poolAncestor = selection[0].PoolAncestor;
|
||||
if (poolAncestor == null || poolAncestor.Locked)
|
||||
return false;
|
||||
|
||||
if (master == null || HelpersGUI.FindActiveHaAction(poolAncestor.Connection) != null || poolAncestor.Locked)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (poolAncestor.Connection == null || !poolAncestor.Connection.IsConnected)
|
||||
return false;
|
||||
|
||||
if (HelpersGUI.FindActiveHaAction(poolAncestor.Connection) != null)
|
||||
return false;
|
||||
|
||||
Host master = Helpers.GetMaster(poolAncestor.Connection);
|
||||
if (master == null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override string GetCantExecuteReasonCore(IXenObject item)
|
||||
|
@ -59,16 +59,13 @@ namespace XenAdmin.Dialogs
|
||||
/// </summary>
|
||||
private readonly long originalNtol;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pool">May not be null. HA must be turned off on the pool.</param>
|
||||
public EditVmHaPrioritiesDialog(Pool pool)
|
||||
{
|
||||
if (pool == null)
|
||||
throw new ArgumentNullException("pool");
|
||||
if (!pool.ha_enabled)
|
||||
throw new ArgumentException("You may only show the EditVmHaPrioritiesDialog for pools that already have HA turned on");
|
||||
throw new ArgumentException("Can only configure HA for pools that already have HA turned on");
|
||||
|
||||
this.pool = pool;
|
||||
InitializeComponent();
|
||||
@ -78,23 +75,6 @@ namespace XenAdmin.Dialogs
|
||||
pool.PropertyChanged += pool_PropertyChanged;
|
||||
originalNtol = pool.ha_host_failures_to_tolerate;
|
||||
|
||||
if (pool.ha_statefiles.Length != 1)
|
||||
{
|
||||
log.ErrorFormat("Cannot show dialog: pool {0} has {1} statefiles, but this dialog can only handle exactly 1. Closing dialog.",
|
||||
pool.Name(), pool.ha_statefiles.Length);
|
||||
this.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
XenRef<VDI> vdiRef = new XenRef<VDI>(pool.ha_statefiles[0]);
|
||||
VDI vdi = pool.Connection.Resolve(vdiRef);
|
||||
if (vdi == null)
|
||||
{
|
||||
log.Error("Could not resolve HA statefile reference. Closing dialog.");
|
||||
this.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
pictureBoxWarningIcon.Image = SystemIcons.Warning.ToBitmap();
|
||||
Rebuild();
|
||||
}
|
||||
|
@ -33,8 +33,10 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using XenAdmin.Actions;
|
||||
using XenAdmin.Commands;
|
||||
using XenAdmin.Controls;
|
||||
using XenAdmin.Core;
|
||||
using XenAdmin.Dialogs;
|
||||
@ -629,6 +631,21 @@ namespace XenAdmin.TabPages
|
||||
return;
|
||||
}
|
||||
|
||||
if (pool.ha_statefiles.All(sf => pool.Connection.Resolve(new XenRef<VDI>(sf)) == null)) //empty gives true, which is correct
|
||||
{
|
||||
using (var dlg = new ThreeButtonDialog(
|
||||
new ThreeButtonDialog.Details(
|
||||
SystemIcons.Error,
|
||||
string.Format(Messages.HA_DISABLE_NO_STATEFILE, Helpers.GetName(pool).Ellipsise(30)),
|
||||
Messages.DISABLE_HA),
|
||||
"HADisable",
|
||||
ThreeButtonDialog.ButtonOK))
|
||||
{
|
||||
dlg.ShowDialog(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirm the user wants to disable HA
|
||||
using (var dlg = new ThreeButtonDialog(
|
||||
new ThreeButtonDialog.Details(
|
||||
@ -649,35 +666,12 @@ namespace XenAdmin.TabPages
|
||||
action.RunAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the appropriate dialog (HA wizard if HA is disabled for the pool, or VM restart priority editor otherwise).
|
||||
/// </summary>
|
||||
/// <param name="pool">Must not be null.</param>
|
||||
internal static void EditHA(Pool pool)
|
||||
{
|
||||
// Do nothing if there is an HA action in progress
|
||||
if (HelpersGUI.FindActiveHaAction(pool.Connection) != null)
|
||||
{
|
||||
log.Debug("Not opening HA dialog: an HA action is in progress");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pool.Connection.IsConnected)
|
||||
{
|
||||
log.Debug("Not opening HA dialog: the connection to the pool is now closed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pool.ha_enabled)
|
||||
{
|
||||
// Show VM restart priority editor
|
||||
Program.MainWindow.ShowPerConnectionWizard(pool.Connection, new EditVmHaPrioritiesDialog(pool));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show wizard to enable HA
|
||||
Program.MainWindow.ShowPerConnectionWizard(pool.Connection, new HAWizard(pool));
|
||||
}
|
||||
var cmd = new HACommand(Program.MainWindow, pool);
|
||||
if (cmd.CanExecute())
|
||||
cmd.Execute();
|
||||
}
|
||||
|
||||
private void SetNetworkHBInitDelay()
|
||||
|
@ -194,6 +194,9 @@ namespace XenAdmin.Wizards.HAWizard_Pages
|
||||
|
||||
private void DeregisterEvents()
|
||||
{
|
||||
if (connection == null)
|
||||
return;
|
||||
|
||||
// Remove listeners
|
||||
connection.Cache.DeregisterCollectionChanged<VM>(VM_CollectionChangedWithInvoke);
|
||||
|
||||
|
27
XenModel/Messages.Designer.cs
generated
27
XenModel/Messages.Designer.cs
generated
@ -7491,6 +7491,15 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Configure HA.
|
||||
/// </summary>
|
||||
public static string CONFIGURE_HA {
|
||||
get {
|
||||
return ResourceManager.GetString("CONFIGURE_HA", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to &Configure HA....
|
||||
/// </summary>
|
||||
@ -17012,6 +17021,15 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cannot configure HA for pool '{0}' because an HA Statefile VDI could not be found in the pool..
|
||||
/// </summary>
|
||||
public static string HA_CONFIGURE_NO_STATEFILE {
|
||||
get {
|
||||
return ResourceManager.GetString("HA_CONFIGURE_NO_STATEFILE", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Configure HA now....
|
||||
/// </summary>
|
||||
@ -17102,6 +17120,15 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cannot disable HA for pool '{0}' because an HA Statefile VDI could not be found in the pool..
|
||||
/// </summary>
|
||||
public static string HA_DISABLE_NO_STATEFILE {
|
||||
get {
|
||||
return ResourceManager.GetString("HA_DISABLE_NO_STATEFILE", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Are you sure you want to disable HA for pool '{0}'?.
|
||||
/// </summary>
|
||||
|
@ -2706,6 +2706,9 @@ Do you want to assign it to the schedule '{2}' instead?</value>
|
||||
<data name="COMPRESSING_FILES" xml:space="preserve">
|
||||
<value>Compressing appliance files...</value>
|
||||
</data>
|
||||
<data name="CONFIGURE_HA" xml:space="preserve">
|
||||
<value>Configure HA</value>
|
||||
</data>
|
||||
<data name="CONFIGURE_HA_ELLIPSIS" xml:space="preserve">
|
||||
<value>&Configure HA...</value>
|
||||
</data>
|
||||
@ -5976,6 +5979,9 @@ not currently live:
|
||||
<data name="HA_CONFIGURE_NOW" xml:space="preserve">
|
||||
<value>Configure HA now...</value>
|
||||
</data>
|
||||
<data name="HA_CONFIGURE_NO_STATEFILE" xml:space="preserve">
|
||||
<value>Cannot configure HA for pool '{0}' because an HA Statefile VDI could not be found in the pool.</value>
|
||||
</data>
|
||||
<data name="HA_CONFIRM_FORCESHUTDOWN_VM" xml:space="preserve">
|
||||
<value>The selected VM is currently protected by HA. Are you sure you want to force the shut down of this VM? This operation will cancel all running tasks for the VM and can result in data loss.</value>
|
||||
</data>
|
||||
@ -5997,6 +6003,9 @@ not currently live:
|
||||
<data name="HA_CURRENT_CAPACITY" xml:space="preserve">
|
||||
<value>Current failure capacity:</value>
|
||||
</data>
|
||||
<data name="HA_DISABLE_NO_STATEFILE" xml:space="preserve">
|
||||
<value>Cannot disable HA for pool '{0}' because an HA Statefile VDI could not be found in the pool.</value>
|
||||
</data>
|
||||
<data name="HA_DISABLE_QUERY" xml:space="preserve">
|
||||
<value>Are you sure you want to disable HA for pool '{0}'?</value>
|
||||
</data>
|
||||
|
Loading…
Reference in New Issue
Block a user