2017-01-16 20:59:50 +01:00
|
|
|
|
/* Copyright (c) Citrix Systems, Inc.
|
2013-06-24 13:41:48 +02:00
|
|
|
|
* 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.IO;
|
2016-07-20 00:51:48 +02:00
|
|
|
|
using XenAdmin.Core;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
using XenAdmin.Mappings;
|
|
|
|
|
using XenAdmin.Network;
|
|
|
|
|
using XenAPI;
|
|
|
|
|
using XenOvf;
|
|
|
|
|
using XenOvf.Definitions;
|
|
|
|
|
|
2020-09-01 04:21:41 +02:00
|
|
|
|
|
|
|
|
|
namespace XenAdmin.Actions.OvfActions
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
2020-09-03 19:26:09 +02:00
|
|
|
|
public partial class ImportApplianceAction : ApplianceAction
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
|
|
|
|
#region Private fields
|
|
|
|
|
|
|
|
|
|
private readonly Package m_package;
|
2020-09-03 19:26:09 +02:00
|
|
|
|
protected readonly Dictionary<string, VmMapping> m_vmMappings;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
private readonly bool m_verifyManifest;
|
|
|
|
|
private readonly bool m_verifySignature;
|
|
|
|
|
private readonly string m_password;
|
2020-09-03 19:26:09 +02:00
|
|
|
|
private string m_encryptionClass;
|
|
|
|
|
private string m_encryptionVersion;
|
|
|
|
|
protected readonly bool m_runfixups;
|
|
|
|
|
protected readonly SR m_selectedIsoSr;
|
2020-09-25 15:39:22 +02:00
|
|
|
|
protected readonly bool _startAutomatically;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2020-08-28 14:07:57 +02:00
|
|
|
|
public ImportApplianceAction(IXenConnection connection, Package package, Dictionary<string, VmMapping> vmMappings,
|
2020-09-25 15:39:22 +02:00
|
|
|
|
bool verifyManifest, bool verifySignature, string password, bool runfixups, SR selectedIsoSr, bool startAutomatically)
|
2020-11-24 12:10:31 +01:00
|
|
|
|
: base(connection, string.Empty)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
2020-11-24 12:10:31 +01:00
|
|
|
|
m_package = package; //this is null if importing a disk Image
|
2013-06-24 13:41:48 +02:00
|
|
|
|
m_vmMappings = vmMappings;
|
|
|
|
|
m_verifyManifest = verifyManifest;
|
|
|
|
|
m_verifySignature = verifySignature;
|
|
|
|
|
m_password = password;
|
|
|
|
|
m_runfixups = runfixups;
|
|
|
|
|
m_selectedIsoSr = selectedIsoSr;
|
2020-09-25 15:39:22 +02:00
|
|
|
|
_startAutomatically = startAutomatically;
|
2020-11-24 12:10:31 +01:00
|
|
|
|
|
|
|
|
|
if (package != null)
|
|
|
|
|
Title = string.Format(Messages.IMPORT_APPLIANCE, package.Name, Helpers.GetName(connection));
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-03 19:26:09 +02:00
|
|
|
|
protected override void RunCore()
|
|
|
|
|
{
|
2020-12-06 00:52:24 +01:00
|
|
|
|
// The appliance has a signature and the user asked to verify it.
|
2020-09-03 19:26:09 +02:00
|
|
|
|
if (m_verifySignature)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
|
|
|
|
Description = Messages.VERIFYING_SIGNATURE;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
m_package.VerifySignature();
|
2020-12-06 00:52:24 +01:00
|
|
|
|
log.Info($"Verified signature for package {m_package.Name}");
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2020-12-06 00:52:24 +01:00
|
|
|
|
log.Error($"Signature verification failed for package {m_package.Name}", e);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
throw new Exception(String.Format(Messages.VERIFYING_SIGNATURE_ERROR, e.Message));
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-12-06 00:52:24 +01:00
|
|
|
|
|
|
|
|
|
// The appliance has
|
|
|
|
|
// - a signature (in which case it also has a manifest that should be verified AFTER the signature); or
|
|
|
|
|
// - a manifest without a signature
|
|
|
|
|
// and the user asked to verify it
|
|
|
|
|
|
|
|
|
|
if (m_verifySignature || m_verifyManifest)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
|
|
|
|
Description = Messages.VERIFYING_MANIFEST;
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
m_package.VerifyManifest();
|
2020-12-06 00:52:24 +01:00
|
|
|
|
log.Info($"Verified manifest for package {m_package.Name}");
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2020-12-06 00:52:24 +01:00
|
|
|
|
log.Error($"Manifest verification failed for package {m_package.Name}", e);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
throw new Exception(String.Format(Messages.VERIFYING_MANIFEST_ERROR, e.Message));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PercentComplete = 20;
|
2020-09-03 19:26:09 +02:00
|
|
|
|
Description = string.Format(Messages.IMPORT_APPLIANCE_PREPARING, m_package.Name);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
//create a copy of the OVF
|
|
|
|
|
var envelopes = new List<EnvelopeType>();
|
|
|
|
|
|
|
|
|
|
foreach (var vmMapping in m_vmMappings)
|
|
|
|
|
{
|
2020-11-23 14:48:28 +01:00
|
|
|
|
CheckForCancellation();
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
string systemid = vmMapping.Key;
|
|
|
|
|
var mapping = vmMapping.Value;
|
2019-11-25 17:07:58 +01:00
|
|
|
|
EnvelopeType[] envs = OVF.Split(m_package.OvfEnvelope, "system", new object[] {new[] {systemid}});
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
//storage
|
|
|
|
|
foreach (var kvp in mapping.Storage)
|
|
|
|
|
OVF.SetTargetSRInRASD(envs[0], systemid, kvp.Key, kvp.Value.uuid);
|
|
|
|
|
|
|
|
|
|
foreach (var kvp in mapping.StorageToAttach)
|
|
|
|
|
OVF.SetTargetVDIInRASD(envs[0], systemid, kvp.Key, kvp.Value.uuid);
|
|
|
|
|
|
|
|
|
|
//network
|
|
|
|
|
foreach (var kvp in mapping.Networks)
|
|
|
|
|
OVF.SetTargetNetworkInRASD(envs[0], systemid, kvp.Key, kvp.Value.uuid);
|
|
|
|
|
|
|
|
|
|
if (m_runfixups)
|
|
|
|
|
{
|
|
|
|
|
string cdId = OVF.SetRunOnceBootCDROMOSFixup(envs[0], systemid, Path.GetDirectoryName(m_package.PackageSourceFile));
|
|
|
|
|
OVF.SetTargetISOSRInRASD(envs[0], systemid, cdId, m_selectedIsoSr.uuid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
envelopes.Add(envs[0]);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-25 17:07:58 +01:00
|
|
|
|
EnvelopeType env = OVF.Merge(envelopes, m_package.Name);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
2020-09-25 15:39:22 +02:00
|
|
|
|
object importedObject;
|
2020-09-03 19:26:09 +02:00
|
|
|
|
try //import VMs
|
2019-11-25 17:07:58 +01:00
|
|
|
|
{
|
2020-09-29 15:28:52 +02:00
|
|
|
|
m_package.ExtractToWorkingDir(() => Cancelling);
|
2020-11-23 14:48:28 +01:00
|
|
|
|
CheckForCancellation();
|
2020-09-03 19:26:09 +02:00
|
|
|
|
OVF.ParseEncryption(env, out m_encryptionClass, out m_encryptionVersion);
|
2020-09-25 15:39:22 +02:00
|
|
|
|
importedObject = Process(env, m_package.WorkingDir, m_package.Name);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
catch (OperationCanceledException)
|
|
|
|
|
{
|
|
|
|
|
throw new CancelledException();
|
|
|
|
|
}
|
2019-11-25 17:07:58 +01:00
|
|
|
|
finally
|
|
|
|
|
{
|
2020-01-25 01:44:01 +01:00
|
|
|
|
m_package.CleanUpWorkingDir();
|
2019-11-25 17:07:58 +01:00
|
|
|
|
}
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
PercentComplete = 100;
|
|
|
|
|
Description = Messages.COMPLETED;
|
2020-09-25 15:39:22 +02:00
|
|
|
|
|
|
|
|
|
if (_startAutomatically && importedObject is XenRef<VM_appliance> applianceRef)
|
|
|
|
|
{
|
|
|
|
|
var appliance = Connection.Resolve(applianceRef);
|
|
|
|
|
if (appliance != null)
|
|
|
|
|
new StartApplianceAction(appliance, false).RunAsync();
|
|
|
|
|
}
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
2019-11-25 17:07:58 +01:00
|
|
|
|
}
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|