mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-23 20:36:33 +01:00
Activate the conversion VPX and get the service IP address without employing the conversion plug-in.
Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
This commit is contained in:
parent
6066de3ae2
commit
1a88c3713d
@ -39,12 +39,12 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using XenAdmin.Actions;
|
||||
using XenAdmin.Actions.Xcm;
|
||||
using XenAdmin.XCM;
|
||||
using XenAdmin.Core;
|
||||
using XenAdmin.Network;
|
||||
using XenAdmin.Wizards.ConversionWizard;
|
||||
using XenAPI;
|
||||
using XenCenterLib;
|
||||
|
||||
|
||||
namespace XenAdmin.Dialogs
|
||||
@ -62,6 +62,7 @@ namespace XenAdmin.Dialogs
|
||||
private volatile bool _updating;
|
||||
private volatile bool _updateRequired;
|
||||
private VM _conversionVm;
|
||||
private ActivateConversionVpxAction _activateAction;
|
||||
|
||||
private static readonly string[] DetailHeaders =
|
||||
{
|
||||
@ -124,8 +125,19 @@ namespace XenAdmin.Dialogs
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
{
|
||||
timerVpx.Stop();
|
||||
|
||||
if (_conversionVm != null)
|
||||
_conversionVm.PropertyChanged -= _conversionVm_PropertyChanged;
|
||||
|
||||
if (_activateAction != null)
|
||||
{
|
||||
_activateAction.Completed -= ActivateConversionVpxAction_Completed;
|
||||
_activateAction.Changed -= ActivateConversionVpxAction_Changed;
|
||||
|
||||
if (!_activateAction.IsCompleted)
|
||||
_activateAction.Cancel();
|
||||
}
|
||||
|
||||
base.OnFormClosing(e);
|
||||
}
|
||||
|
||||
@ -138,62 +150,49 @@ namespace XenAdmin.Dialogs
|
||||
statusLabel.Text = Messages.CONVERSION_INITIALIZING_VPX;
|
||||
statusLinkLabel.Reset();
|
||||
|
||||
ThreadPool.QueueUserWorkItem(obj =>
|
||||
_activateAction = new ActivateConversionVpxAction(connection);
|
||||
_activateAction.Completed += ActivateConversionVpxAction_Completed;
|
||||
_activateAction.Changed += ActivateConversionVpxAction_Changed;
|
||||
_activateAction.RunAsync();
|
||||
}
|
||||
|
||||
private void ActivateConversionVpxAction_Completed(ActionBase obj)
|
||||
{
|
||||
if (!(obj is ActivateConversionVpxAction action))
|
||||
return;
|
||||
|
||||
action.Completed -= ActivateConversionVpxAction_Completed;
|
||||
action.Changed -= ActivateConversionVpxAction_Changed;
|
||||
|
||||
Program.Invoke(this, () =>
|
||||
{
|
||||
var master = Helpers.GetMaster(connection);
|
||||
|
||||
string serviceIp = null;
|
||||
try
|
||||
if (!action.Succeeded)
|
||||
{
|
||||
serviceIp = Host.call_plugin(connection.Session, master.opaque_ref, "conversion", "main", null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error("Cannot communicate with the conversion plugin.", e);
|
||||
statusLabel.Image = Images.StaticImages._000_error_h32bit_16;
|
||||
statusLabel.Text = action.Exception.Message;
|
||||
statusLinkLabel.Reset(Messages.CONVERSION_TRY_AGAIN, ConnectToVpx);
|
||||
return;
|
||||
}
|
||||
|
||||
Program.Invoke(this, () =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(serviceIp))
|
||||
{
|
||||
statusLabel.Image = Images.StaticImages._000_error_h32bit_16;
|
||||
statusLabel.Text = Messages.CONVERSION_INITIALIZING_VPX_FAILURE;
|
||||
statusLinkLabel.Reset(Messages.CONVERSION_TRY_AGAIN, ConnectToVpx);
|
||||
return;
|
||||
}
|
||||
var useSsl = Properties.Settings.Default.ConversionClientUseSsl;
|
||||
_conversionClient = new ConversionClient(connection, action.ServiceIp, useSsl);
|
||||
|
||||
var useSsl = Properties.Settings.Default.ConversionClientUseSsl;
|
||||
_conversionClient = new ConversionClient(connection, serviceIp, useSsl);
|
||||
RegisterVM(serviceIp);
|
||||
CheckVersionCompatibility();
|
||||
});
|
||||
// if we're reconnecting the conversion VM, we need to clear the old one
|
||||
if (_conversionVm != null)
|
||||
_conversionVm.PropertyChanged -= _conversionVm_PropertyChanged;
|
||||
_conversionVm = action.ConversionVm;
|
||||
_conversionVm.PropertyChanged += _conversionVm_PropertyChanged;
|
||||
|
||||
CheckVersionCompatibility();
|
||||
});
|
||||
}
|
||||
|
||||
private void RegisterVM(string ipAddress)
|
||||
private void ActivateConversionVpxAction_Changed(ActionBase obj)
|
||||
{
|
||||
// if we're reconnecting the conversion VM, we need to clear the old one
|
||||
if (_conversionVm != null)
|
||||
{
|
||||
_conversionVm.PropertyChanged -= _conversionVm_PropertyChanged;
|
||||
_conversionVm = null;
|
||||
}
|
||||
if (!(obj is ActivateConversionVpxAction action))
|
||||
return;
|
||||
|
||||
var vifs = connection.Cache.VIFs;
|
||||
|
||||
foreach (var vif in vifs)
|
||||
{
|
||||
if (!vif.IPAddresses().Contains(ipAddress))
|
||||
continue;
|
||||
|
||||
var vm = connection.Resolve(vif.VM);
|
||||
if (!vm.IsConversionVM())
|
||||
continue;
|
||||
|
||||
_conversionVm = vm;
|
||||
_conversionVm.PropertyChanged += _conversionVm_PropertyChanged;
|
||||
break;
|
||||
}
|
||||
Program.Invoke(this, () => { statusLabel.Text = action.Description; });
|
||||
}
|
||||
|
||||
private void _conversionVm_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||
|
146
XenModel/Actions/XCM/ActivateConversionVpxAction.cs
Normal file
146
XenModel/Actions/XCM/ActivateConversionVpxAction.cs
Normal file
@ -0,0 +1,146 @@
|
||||
/* 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.Linq;
|
||||
using System.Threading;
|
||||
using XenAdmin.Network;
|
||||
using XenAPI;
|
||||
|
||||
|
||||
namespace XenAdmin.Actions.Xcm
|
||||
{
|
||||
public class ActivateConversionVpxAction : AsyncAction
|
||||
{
|
||||
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private const int TIMEOUT = 2 * 60 * 1000; //milliseconds
|
||||
private const int SLEEP = 2000; //milliseconds
|
||||
|
||||
public ActivateConversionVpxAction(IXenConnection connection)
|
||||
: base(connection, "", true)
|
||||
{
|
||||
}
|
||||
|
||||
public VM ConversionVm { get; private set; }
|
||||
public string ServiceIp { get; private set; }
|
||||
|
||||
protected override void Run()
|
||||
{
|
||||
ConversionVm = Connection.Cache.VMs.FirstOrDefault(vm => vm.IsConversionVM());
|
||||
|
||||
if (ConversionVm == null)
|
||||
throw new Exception(Messages.CONVERSION_CANNOT_FIND_VPX);
|
||||
|
||||
switch (ConversionVm.power_state)
|
||||
{
|
||||
case vm_power_state.Halted:
|
||||
case vm_power_state.Paused:
|
||||
case vm_power_state.Suspended:
|
||||
case vm_power_state.Running:
|
||||
break;
|
||||
default:
|
||||
log.Error($"The conversion VPX {ConversionVm.uuid} is in an unknown power state");
|
||||
throw new Exception(Messages.CONVERSION_VPX_UNKNOWN_POWER_STATE);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch (ConversionVm.power_state)
|
||||
{
|
||||
case vm_power_state.Halted:
|
||||
Description = Messages.CONVERSION_VPX_START;
|
||||
VM.start(Connection.Session, ConversionVm.opaque_ref, false, false);
|
||||
break;
|
||||
case vm_power_state.Paused:
|
||||
Description = Messages.CONVERSION_VPX_UNPAUSE;
|
||||
VM.unpause(Connection.Session, ConversionVm.opaque_ref);
|
||||
break;
|
||||
case vm_power_state.Suspended:
|
||||
Description = Messages.CONVERSION_VPX_RESUME;
|
||||
VM.resume(Connection.Session, ConversionVm.opaque_ref, false, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is Failure f && f.ErrorDescription.Count > 0 && f.ErrorDescription[0] == Failure.VM_BAD_POWER_STATE)
|
||||
{
|
||||
//ignore
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Error($"Failed to activate conversion VPX {ConversionVm.uuid}", e);
|
||||
throw new Exception(Messages.CONVERSION_INITIALIZING_VPX_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
Description = Messages.CONVERSION_VPX_OBTAIN_IP;
|
||||
|
||||
string ipAddress = null;
|
||||
var tries = TIMEOUT / SLEEP;
|
||||
|
||||
while (tries > 0)
|
||||
{
|
||||
if (Cancelling)
|
||||
throw new CancelledException();
|
||||
|
||||
if (Helper.IsNullOrEmptyOpaqueRef(ConversionVm.guest_metrics.opaque_ref))
|
||||
{
|
||||
ConversionVm = Connection.Resolve(new XenRef<VM>(ConversionVm.opaque_ref));
|
||||
}
|
||||
else
|
||||
{
|
||||
var metrics = Connection.Resolve(ConversionVm.guest_metrics);
|
||||
if (metrics != null)
|
||||
{
|
||||
// device 0 is the internal network for the VM; find an external one
|
||||
var vif = Connection.ResolveAll(ConversionVm.VIFs).FirstOrDefault(v => v.device != "0");
|
||||
if (vif != null && metrics.networks.TryGetValue($"{vif.device}/ip", out ipAddress))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(SLEEP);
|
||||
tries--;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ipAddress))
|
||||
{
|
||||
log.Error($"Cannot obtain an IP address for conversion VPX {ConversionVm.uuid}.");
|
||||
throw new Exception(Messages.CONVERSION_CANNOT_OBTAIN_VPX_IP);
|
||||
}
|
||||
|
||||
ServiceIp = ipAddress;
|
||||
}
|
||||
}
|
||||
}
|
63
XenModel/Messages.Designer.cs
generated
63
XenModel/Messages.Designer.cs
generated
@ -8979,6 +8979,24 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cannot find a Conversion Manager Virtual Appliance..
|
||||
/// </summary>
|
||||
public static string CONVERSION_CANNOT_FIND_VPX {
|
||||
get {
|
||||
return ResourceManager.GetString("CONVERSION_CANNOT_FIND_VPX", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cannot obtain an IP address for the Conversion Manager Virtual Appliance..
|
||||
/// </summary>
|
||||
public static string CONVERSION_CANNOT_OBTAIN_VPX_IP {
|
||||
get {
|
||||
return ResourceManager.GetString("CONVERSION_CANNOT_OBTAIN_VPX_IP", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This action will clear all the completed conversions from the Conversion Manager Virtual Appliance history.
|
||||
///
|
||||
@ -9613,6 +9631,51 @@ namespace XenAdmin {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Obtaining an IP address for the Conversion Manager Virtual Appliance....
|
||||
/// </summary>
|
||||
public static string CONVERSION_VPX_OBTAIN_IP {
|
||||
get {
|
||||
return ResourceManager.GetString("CONVERSION_VPX_OBTAIN_IP", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Resuming the Conversion Manager Virtual Appliance....
|
||||
/// </summary>
|
||||
public static string CONVERSION_VPX_RESUME {
|
||||
get {
|
||||
return ResourceManager.GetString("CONVERSION_VPX_RESUME", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Starting the Conversion Manager Virtual Appliance....
|
||||
/// </summary>
|
||||
public static string CONVERSION_VPX_START {
|
||||
get {
|
||||
return ResourceManager.GetString("CONVERSION_VPX_START", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Cannot deduce the power state of the Conversion Manager Virtual Appliance..
|
||||
/// </summary>
|
||||
public static string CONVERSION_VPX_UNKNOWN_POWER_STATE {
|
||||
get {
|
||||
return ResourceManager.GetString("CONVERSION_VPX_UNKNOWN_POWER_STATE", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Un-pausing the Conversion Manager Virtual Appliance....
|
||||
/// </summary>
|
||||
public static string CONVERSION_VPX_UNPAUSE {
|
||||
get {
|
||||
return ResourceManager.GetString("CONVERSION_VPX_UNPAUSE", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to New Conversion.
|
||||
/// </summary>
|
||||
|
@ -3256,6 +3256,12 @@ This action cannot be undone. Are you sure you want to continue?</value>
|
||||
<data name="CONVERSION_CANCEL_FAILURE" xml:space="preserve">
|
||||
<value>Cannot cancel the conversion. Please see logs for details.</value>
|
||||
</data>
|
||||
<data name="CONVERSION_CANNOT_FIND_VPX" xml:space="preserve">
|
||||
<value>Cannot find a Conversion Manager Virtual Appliance.</value>
|
||||
</data>
|
||||
<data name="CONVERSION_CANNOT_OBTAIN_VPX_IP" xml:space="preserve">
|
||||
<value>Cannot obtain an IP address for the Conversion Manager Virtual Appliance.</value>
|
||||
</data>
|
||||
<data name="CONVERSION_CONNECTING_VMWARE" xml:space="preserve">
|
||||
<value>Connecting to the VMware server...</value>
|
||||
</data>
|
||||
@ -3462,6 +3468,21 @@ This action cannot be undone. Are you sure you want to continue?</value>
|
||||
<data name="CONVERSION_VM_PAGE_TITLE" xml:space="preserve">
|
||||
<value>Select the VMs to convert</value>
|
||||
</data>
|
||||
<data name="CONVERSION_VPX_OBTAIN_IP" xml:space="preserve">
|
||||
<value>Obtaining an IP address for the Conversion Manager Virtual Appliance...</value>
|
||||
</data>
|
||||
<data name="CONVERSION_VPX_RESUME" xml:space="preserve">
|
||||
<value>Resuming the Conversion Manager Virtual Appliance...</value>
|
||||
</data>
|
||||
<data name="CONVERSION_VPX_START" xml:space="preserve">
|
||||
<value>Starting the Conversion Manager Virtual Appliance...</value>
|
||||
</data>
|
||||
<data name="CONVERSION_VPX_UNPAUSE" xml:space="preserve">
|
||||
<value>Un-pausing the Conversion Manager Virtual Appliance...</value>
|
||||
</data>
|
||||
<data name="CONVERSION_VPX_UNKNOWN_POWER_STATE" xml:space="preserve">
|
||||
<value>Cannot deduce the power state of the Conversion Manager Virtual Appliance.</value>
|
||||
</data>
|
||||
<data name="CONVERSION_WIZARD_TEXT" xml:space="preserve">
|
||||
<value>New Conversion</value>
|
||||
</data>
|
||||
|
@ -156,6 +156,7 @@
|
||||
<Compile Include="Actions\VM\VMSnapshotCreateAction.cs" />
|
||||
<Compile Include="Actions\VM\VMStartAction.cs" />
|
||||
<Compile Include="Actions\WLB\WlbRetrieveVmRecommendationsAction.cs" />
|
||||
<Compile Include="Actions\XCM\ActivateConversionVpxAction.cs" />
|
||||
<Compile Include="Actions\ZipStatusReportAction.cs" />
|
||||
<Compile Include="Alerts\Types\Alert.cs" />
|
||||
<Compile Include="XCM\ConversionClient.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user