/* 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.Text.RegularExpressions; using XenAdmin.Controls; using XenAdmin.Core; using XenAdmin.Network; using XenAdmin.Wizards.GenericPages; using XenAdmin.Wizards.ImportWizard.Filters; using XenAPI; using XenOvf; using XenOvf.Definitions; namespace XenAdmin.Wizards.ImportWizard { class ImportSelectHostPage : SelectMultipleVMDestinationPage { public EnvelopeType SelectedOvfEnvelope { private get; set; } private List vgpuSettings = new List(); private List hardwarePlatformSettings = new List(); private List vendorDeviceSettings = new List(); public event Action ConnectionSelectionChanged; #region XenTabPage overrides /// /// Gets the page's title (headline) /// public override string PageTitle { get { return Messages.IMPORT_SELECT_HOST_PAGE_TITLE; } } /// /// Gets the page's label in the (left hand side) wizard progress panel /// public override string Text { get { return Messages.NEWSR_LOCATION; } } protected override bool ImplementsIsDirty() { return true; } public override void PageLoaded(PageLoadedDirection direction) { base.PageLoaded(direction); if (direction == PageLoadedDirection.Forward) { ShowWarning(null); vgpuSettings.Clear(); hardwarePlatformSettings.Clear(); vendorDeviceSettings.Clear(); if (SelectedOvfEnvelope != null) { foreach (var vsType in ((VirtualSystemCollection_Type)SelectedOvfEnvelope.Item).Content) { var vhs = OVF.FindVirtualHardwareSectionByAffinity(SelectedOvfEnvelope, vsType.id, "xen"); var data = vhs.VirtualSystemOtherConfigurationData; if (data == null) continue; foreach (var s in data) { if (s.Name == "vgpu") vgpuSettings.Add(s); else if (s.Name == "hardware_platform_version") hardwarePlatformSettings.Add(s); else if (s.Name == "VM_has_vendor_device") vendorDeviceSettings.Add(s); } } } } PopulateComboBox(); } #endregion protected override string InstructionText { get { return Messages.IMPORT_WIZARD_DESTINATION_INSTRUCTIONS; } } protected override string TargetServerText { get { return Messages.IMPORT_WIZARD_DESTINATION_DESTINATION; } } protected override string TargetServerSelectionIntroText { get { return Messages.IMPORT_WIZARD_DESTINATION_TABLE_INTRO; } } protected override void OnChosenItemChanged() { var warnings = new List(); if (ChosenItem != null) { if (!CheckDestinationSupportsVendorDevice()) { //it shouldn't come to this as the hardware incompatibility filter //will have already caught it but just to be on the safe side if (VmMappings.Count == 1) warnings.Add(Messages.IMPORT_VM_WITH_VENDOR_DEVICE_WARNING_ONE); else if (VmMappings.Count > 1) warnings.Add(Messages.IMPORT_VM_WITH_VENDOR_DEVICE_WARNING_MANY); } if (!CheckRightGpuExists()) { if (VmMappings.Count == 1) warnings.Add(Messages.IMPORT_VM_WITH_VGPU_WARNING_ONE); else if (VmMappings.Count > 1) warnings.Add(Messages.IMPORT_VM_WITH_VGPU_WARNING_MANY); } } ShowWarning(string.Join("\n", warnings)); if (ConnectionSelectionChanged != null) ConnectionSelectionChanged(ChosenItem != null ? ChosenItem.Connection : null); } protected override DelayLoadingOptionComboBoxItem CreateDelayLoadingOptionComboBoxItem(IXenObject xenItem) { var filters = new List { new HardwareCompatibilityFilter(xenItem, hardwarePlatformSettings) }; return new DelayLoadingOptionComboBoxItem(xenItem, filters); } protected override List CreateTargetServerFilterList(IEnableableXenObjectComboBoxItem item, List vmOpaqueRefs) { var filters = new List(); if (item != null) filters.Add(new HardwareCompatibilityFilter(item.Item, hardwarePlatformSettings)); return filters; } private bool CheckRightGpuExists() { foreach (var vgpuSetting in vgpuSettings) { Match m = XenOvfTransport.Import.VGPU_REGEX.Match(vgpuSetting.Value.Value); if (!m.Success) continue; var types = m.Groups[1].Value.Split(';'); var gpuGroup = ChosenItem.Connection.Cache.GPU_groups.FirstOrDefault(g => g.GPU_types.Length == types.Length && g.GPU_types.Intersect(types).Count() == types.Length); if (gpuGroup == null) return false; string vendorName = m.Groups[2].Value; string modelName = m.Groups[3].Value; var vgpuType = ChosenItem.Connection.Cache.VGPU_types.FirstOrDefault(v => v.vendor_name == vendorName && v.model_name == modelName); if (vgpuType == null) return false; } return true; } private bool CheckDestinationSupportsVendorDevice() { var dundeeOrNewerHosts = Helpers.DundeeOrGreater(ChosenItem.Connection) ? ChosenItem.Connection.Cache.Hosts : new Host[] {}; foreach (var setting in vendorDeviceSettings) { bool hasVendorDevice; if (!bool.TryParse(setting.Value.Value, out hasVendorDevice)) continue; if (hasVendorDevice && dundeeOrNewerHosts.Length == 0) return false; } return true; } } }