Merge pull request #3137 from danilo-delbusso/dev/snapshot-crash-CA-375803

CA-375803: Catch exceptions when creating a new template from snapshot
This commit is contained in:
Konstantina Chremmou 2023-05-05 14:56:46 +01:00 committed by GitHub
commit 801125f448
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 96 additions and 109 deletions

View File

@ -136,11 +136,9 @@ namespace XenAdmin.Commands
{
sender.Completed -= Action_Completed;
var action = sender as CreateFolderAction;
if (action != null && action.Succeeded)
if (sender is CreateFolderAction action && action.Succeeded)
{
if (FoldersCreated != null)
FoldersCreated(action.NewPaths);
FoldersCreated?.Invoke(action.NewPaths);
Program.MainWindow.TrySelectNewNode(delegate(object o)
{

View File

@ -30,6 +30,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;
using XenAPI;
using XenAdmin.Actions;
@ -45,6 +46,8 @@ namespace XenAdmin.Commands
/// </summary>
internal class NewTemplateFromSnapshotCommand : Command
{
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod()?.DeclaringType);
/// <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.
@ -65,15 +68,16 @@ namespace XenAdmin.Commands
protected override void RunCore(SelectedItemCollection selection)
{
VM snapshot = (VM)selection[0].XenObject;
var snapshot = (VM)selection[0].XenObject;
// Generate list of all taken VM/snapshot/template names
List<string> takenNames = new List<VM>(snapshot.Connection.Cache.VMs).ConvertAll(v => v.Name());
var takenNames = new List<VM>(snapshot.Connection.Cache.VMs).ConvertAll(v => v.Name());
// Generate a unique suggested name for the new template
string defaultName = Helpers.MakeUniqueName(String.Format(Messages.TEMPLATE_FROM_SNAPSHOT_DEFAULT_NAME, snapshot.Name()), takenNames);
var defaultName = Helpers.MakeUniqueName(string.Format(Messages.TEMPLATE_FROM_SNAPSHOT_DEFAULT_NAME, snapshot.Name()), takenNames);
using (var dialog = new InputPromptDialog {
using (var dialog = new InputPromptDialog
{
Text = Messages.SAVE_AS_TEMPLATE,
PromptText = Messages.NEW_TEMPLATE_PROMPT,
InputText = defaultName,
@ -82,21 +86,21 @@ namespace XenAdmin.Commands
{
if (dialog.ShowDialog(Parent) == DialogResult.OK)
{
// TODO: work out what the new description should be
var action = new VMCloneAction(snapshot, dialog.InputText, "");
var action = new VMCloneAction(snapshot, dialog.InputText, string.Format(Messages.TEMPLATE_FROM_SNAPSHOT_DEFAULT_DESCRIPTION, BrandManager.BrandConsole, snapshot.Name()));
action.Completed += action_Completed;
action.RunAsync();
}
}
}
void action_Completed(ActionBase sender)
private static void action_Completed(ActionBase sender)
{
AsyncAction action = (AsyncAction)sender;
if (!sender.Succeeded || !(sender is AsyncAction action))
return;
var vm = action.Connection.Resolve(new XenRef<VM>(action.Result));
if (vm != null)
new SetVMOtherConfigAction(vm.Connection, vm, "instant", "true").RunAsync();
}
protected override bool CanRunCore(SelectedItemCollection selection)
@ -104,12 +108,6 @@ namespace XenAdmin.Commands
return selection.ContainsOneItemOfType<VM>() && selection.AtLeastOneXenObjectCan<VM>(v => v.is_a_snapshot);
}
public override string MenuText
{
get
{
return Messages.CREATE_TEMPLATE_FROM_SNAPSHOT_MENU_ITEM;
}
}
public override string MenuText => Messages.CREATE_TEMPLATE_FROM_SNAPSHOT_MENU_ITEM;
}
}

View File

@ -142,12 +142,9 @@ namespace XenAdmin.Commands
private void RestoreAction_Completed(ActionBase sender)
{
HostBackupRestoreAction action = (HostBackupRestoreAction)sender;
if (!action.Succeeded)
if (!(sender is HostBackupRestoreAction action) || !action.Succeeded)
{
// Do nothing - failure will be reflected in the logs tab.
return;
return;
}
MainWindowCommandInterface.Invoke(delegate

View File

@ -594,40 +594,36 @@ namespace XenAdmin.Controls.Wlb
/// </summary>
protected void OptRecRetrieveAction_Completed(ActionBase sender)
{
AsyncAction action = (AsyncAction)sender;
if (action.IsCompleted)
if (!(sender is WlbRetrieveRecommendationsAction asyncAction))
return;
asyncAction.Completed -= OptRecRetrieveAction_Completed;
_recommendations = asyncAction.Recommendations;
if (_recommendations != null && IsGoodRecommendation(_recommendations) && _xenObject.Connection == asyncAction.Connection)
{
action.Completed -= OptRecRetrieveAction_Completed;
if (action is WlbRetrieveRecommendationsAction thisAction)
Program.Invoke(this, delegate ()
{
_recommendations = thisAction.Recommendations;
if (_recommendations != null && IsGoodRecommendation(_recommendations) && _xenObject.Connection == action.Connection)
{
Program.Invoke(this, delegate()
{
PopulateData(_recommendations);
PopulateData(_recommendations);
// In case optimizePoolListView is empty
if (optimizePoolListView.Items.Count == 0)
{
statusLabel.Text = Messages.WLB_OPT_POOL_NO_RECOMMENDATION;
EnableControls(true, false);
}
else
EnableControls(false, true);
});
// In case optimizePoolListView is empty
if (optimizePoolListView.Items.Count == 0)
{
statusLabel.Text = Messages.WLB_OPT_POOL_NO_RECOMMENDATION;
EnableControls(true, false);
}
else
{
Program.Invoke(this, delegate()
{
statusLabel.Text = Messages.WLB_OPT_POOL_NO_RECOMMENDATION;
EnableControls(true, false);
});
}
}
EnableControls(false, true);
});
}
else
{
Program.Invoke(this, delegate ()
{
statusLabel.Text = Messages.WLB_OPT_POOL_NO_RECOMMENDATION;
EnableControls(true, false);
});
}
}

View File

@ -94,7 +94,7 @@ namespace XenAdmin.Dialogs
{
Exception delegateException = null;
log.Debug("Testing logging in with the new credentials");
DelegatedAsyncAction loginAction = new DelegatedAsyncAction(connection,
var loginAction = new DelegatedAsyncAction(connection,
Messages.AUTHORIZING_USER,
Messages.CREDENTIALS_CHECKING,
Messages.CREDENTIALS_CHECK_COMPLETE,
@ -108,7 +108,7 @@ namespace XenAdmin.Dialogs
{
delegateException = ex;
}
});
}, true);
using (var dlg = new ActionProgressDialog(loginAction, ProgressBarStyle.Marquee) {ShowTryAgainMessage = false})
dlg.ShowDialog(this);

View File

@ -208,13 +208,9 @@ namespace XenAdmin.Dialogs.ScheduledSnapshots
{
sender.Completed -= action_Completed;
var action = sender as GetServerLocalTimeAction;
if (action == null)
if (!(sender is GetServerLocalTimeAction action) || !action.Succeeded)
return;
if (!action.Succeeded)
return;
Program.Invoke(Program.MainWindow, () =>
{
try

View File

@ -154,8 +154,7 @@ namespace XenAdmin.SettingsPanels
private void action_Completed(ActionBase sender)
{
var action = (AsyncAction) sender;
if (!action.Succeeded)
if (!(sender is AsyncAction action) || !action.Succeeded)
commonNetwork = null;
Program.Invoke(ParentForm, delegate

View File

@ -99,8 +99,7 @@ namespace XenAdmin.TabPages
private void action_Completed(ActionBase sender)
{
var action = sender as RunContainerPluginAction;
if (action == null || action.Container != container)
if (!(sender is RunContainerPluginAction action) || action.Container != container)
return;
Program.Invoke(Program.MainWindow, () =>
{

View File

@ -110,8 +110,7 @@ namespace XenAdmin.TabPages
private void action_Completed(ActionBase sender)
{
var action = sender as RunContainerPluginAction;
if (action == null || action.Container != container)
if (!(sender is RunContainerPluginAction action) || action.Container != container)
return;
Program.Invoke(Program.MainWindow, () =>
{

View File

@ -140,8 +140,7 @@ namespace XenAdmin.TabPages
private void action_Changed(ActionBase sender)
{
var asyncAction = sender as AsyncAction;
if (asyncAction != null)
if (sender is AsyncAction asyncAction)
asyncAction.RecomputeCanCancel();
Program.Invoke(Program.MainWindow, () =>

View File

@ -214,43 +214,41 @@ namespace XenAdmin.TabPages
protected void action_Completed(ActionBase sender)
{
// This seems to be called off the event thread
AsyncAction action = (AsyncAction)sender;
if (action.IsCompleted)
if (!(sender is AsyncAction action) || !action.IsCompleted)
return;
action.Completed -= action_Completed;
if (action is EnableWLBAction || action is RetrieveWlbConfigurationAction || action is DisableWLBAction)
{
action.Completed -= action_Completed;
if (action is EnableWLBAction || action is RetrieveWlbConfigurationAction || action is DisableWLBAction)
if (action is EnableWLBAction)
{
if (action is EnableWLBAction)
EnableWLBAction thisAction = (EnableWLBAction)action;
_wlbPoolConfiguration = new WlbPoolConfiguration(thisAction.WlbConfiguration);
}
else if (action is RetrieveWlbConfigurationAction)
{
RetrieveWlbConfigurationAction thisAction = (RetrieveWlbConfigurationAction)action;
if (thisAction.Succeeded)
{
EnableWLBAction thisAction = (EnableWLBAction)action;
_wlbPoolConfiguration = new WlbPoolConfiguration(thisAction.WlbConfiguration);
}
else if (action is RetrieveWlbConfigurationAction)
else
{
RetrieveWlbConfigurationAction thisAction = (RetrieveWlbConfigurationAction)action;
if (thisAction.Succeeded)
{
_wlbPoolConfiguration = new WlbPoolConfiguration(thisAction.WlbConfiguration);
}
else
{
//_statusError = thisAction.Exception.Message;
_wlbPoolConfiguration = null;
}
//_statusError = thisAction.Exception.Message;
_wlbPoolConfiguration = null;
}
else if (action is DisableWLBAction)
{
}
Program.Invoke(Program.MainWindow, delegate()
{
if (_pool != null && _pool.Connection == action.Connection)
{
RefreshControls();
}
});
}
else if (action is DisableWLBAction)
{
}
Program.Invoke(Program.MainWindow, delegate()
{
if (_pool != null && _pool.Connection == action.Connection)
{
RefreshControls();
}
});
}
}

View File

@ -491,19 +491,15 @@ namespace XenAdmin.Wizards.DRWizards
Thread.Sleep(1000);
Program.Invoke(Program.MainWindow, RefreshRechecks);
var drTaskCreateAction = sender as DrTaskCreateAction;
if (drTaskCreateAction != null && drTaskCreateAction.Succeeded)
if (sender is DrTaskCreateAction drTaskCreateAction && drTaskCreateAction.Succeeded)
{
if (NewDrTaskIntroduced != null)
NewDrTaskIntroduced(drTaskCreateAction.Result);
NewDrTaskIntroduced?.Invoke(drTaskCreateAction.Result);
return;
}
var srIntroduceAction = sender as SrIntroduceAction;
if (srIntroduceAction != null && srIntroduceAction.Succeeded)
if (sender is SrIntroduceAction srIntroduceAction && srIntroduceAction.Succeeded)
{
if (SrIntroduced != null)
SrIntroduced(new XenRef<SR>(srIntroduceAction.Result));
SrIntroduced?.Invoke(new XenRef<SR>(srIntroduceAction.Result));
}
}

View File

@ -25742,7 +25742,7 @@ namespace XenAdmin {
}
/// <summary>
/// Looks up a localized string similar to Enter &amp;name for new template:.
/// Looks up a localized string similar to Enter a &amp;name for the new template:.
/// </summary>
public static string NEW_TEMPLATE_PROMPT {
get {
@ -35767,6 +35767,15 @@ namespace XenAdmin {
}
}
/// <summary>
/// Looks up a localized string similar to Template generated by {0} from snapshot &apos;{1}&apos;.
/// </summary>
public static string TEMPLATE_FROM_SNAPSHOT_DEFAULT_DESCRIPTION {
get {
return ResourceManager.GetString("TEMPLATE_FROM_SNAPSHOT_DEFAULT_DESCRIPTION", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Template from snapshot &apos;{0}&apos;.
/// </summary>

View File

@ -8970,7 +8970,7 @@ It is strongly recommended that you Cancel and apply the latest version of the p
<value>Edit tags...</value>
</data>
<data name="NEW_TEMPLATE_PROMPT" xml:space="preserve">
<value>Enter &amp;name for new template:</value>
<value>Enter a &amp;name for the new template:</value>
</data>
<data name="NEW_UPDATE_AVAILABLE" xml:space="preserve">
<value>New Update Available - {0}</value>
@ -12385,6 +12385,9 @@ Do you want to connect to the pool coordinator '{1}'?</value>
<data name="TEMPLATE" xml:space="preserve">
<value>Template</value>
</data>
<data name="TEMPLATE_FROM_SNAPSHOT_DEFAULT_DESCRIPTION" xml:space="preserve">
<value>Template generated by {0} from snapshot '{1}'</value>
</data>
<data name="TEMPLATE_FROM_SNAPSHOT_DEFAULT_NAME" xml:space="preserve">
<value>Template from snapshot '{0}'</value>
</data>