From 73cabcd64167ca4da1f822a047d68b03c1abc479 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 31 Aug 2021 16:10:12 +0530 Subject: [PATCH] xcp-ng: allow passing vm boot options (#5335) * xenserver: honor vm boot details Signed-off-by: Abhishek Kumar * ui: allow boot option selection for xenserver Signed-off-by: Abhishek Kumar * fix Signed-off-by: Abhishek Kumar * fix case Signed-off-by: Abhishek Kumar * fix Signed-off-by: Abhishek Kumar * host uefi capability Signed-off-by: Abhishek Kumar * change Signed-off-by: Abhishek Kumar * add detail only if uefi supported Signed-off-by: Abhishek Kumar * update host detail Signed-off-by: Abhishek Kumar * fix version comparison Signed-off-by: Abhishek Kumar --- plugins/hypervisors/xenserver/pom.xml | 5 ++++ .../discoverer/XcpServerDiscoverer.java | 15 ++++++++++++ .../resource/CitrixResourceBase.java | 24 +++++++++++++++++++ .../discoverer/XcpServerDiscovererTest.java | 22 +++++++++++++++++ .../allocator/impl/FirstFitAllocator.java | 2 +- ui/src/views/compute/DeployVM.vue | 3 +-- 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/xenserver/pom.xml b/plugins/hypervisors/xenserver/pom.xml index 694ebfbaaea..7a2015ac1e5 100644 --- a/plugins/hypervisors/xenserver/pom.xml +++ b/plugins/hypervisors/xenserver/pom.xml @@ -48,5 +48,10 @@ xen-api ${cs.xapi.version} + + org.apache.maven + maven-artifact + 3.6.3 + diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java index c2a0969c9d3..bbf3686750d 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscoverer.java @@ -31,7 +31,9 @@ import javax.naming.ConfigurationException; import javax.persistence.EntityExistsException; import org.apache.cloudstack.hypervisor.xenserver.XenserverConfigs; +import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; +import org.apache.maven.artifact.versioning.ComparableVersion; import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.AgentManager; @@ -122,6 +124,16 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L private String xenServerIsoName = TemplateManager.XS_TOOLS_ISO; private String xenServerIsoDisplayText = "XenServer Tools Installer ISO (xen-pv-drv-iso)"; + public final static String MIN_UEFI_SUPPORTED_VERSION = "8.2"; + + public static boolean isUefiSupported(String hostProductVersion) { + if (StringUtils.isEmpty(hostProductVersion)) { + return false; + } + ComparableVersion version = new ComparableVersion(hostProductVersion); + return version.compareTo(new ComparableVersion(MIN_UEFI_SUPPORTED_VERSION)) >= 0; + } + protected XcpServerDiscoverer() { } @@ -309,6 +321,9 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L details.put("username", username); params.put("username", username); details.put("password", password); + if (isUefiSupported(prodVersion)) { + details.put(com.cloud.host.Host.HOST_UEFI_ENABLE, Boolean.TRUE.toString()); + } params.put("password", password); params.put("zone", Long.toString(dcId)); params.put("guid", record.uuid); diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index f6d95ecbda5..b63480f5cf4 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.hypervisor.xenserver.resource; +import static com.cloud.hypervisor.xenserver.discoverer.XcpServerDiscoverer.isUefiSupported; import static com.cloud.utils.NumbersUtil.toHumanReadableSize; import java.io.BufferedReader; @@ -51,6 +52,7 @@ import javax.naming.ConfigurationException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.diagnostics.CopyToSecondaryStorageAnswer; import org.apache.cloudstack.diagnostics.CopyToSecondaryStorageCommand; import org.apache.cloudstack.diagnostics.DiagnosticsService; @@ -1438,6 +1440,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (final Exception e) { throw new CloudRuntimeException("Unable to finalize VM MetaData: " + vmSpec); } + try { + setVmBootDetails(vm, conn, vmSpec.getBootType(), vmSpec.getBootMode()); + } catch (final XenAPIException | XmlRpcException e) { + throw new CloudRuntimeException(String.format("Unable to handle VM boot options: %s", vmSpec), e); + } return vm; } @@ -1784,6 +1791,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } details.put("product_brand", productBrand); details.put("product_version", _host.getProductVersion()); + if (isUefiSupported(_host.getProductVersion())) { + details.put(com.cloud.host.Host.HOST_UEFI_ENABLE, Boolean.TRUE.toString()); + } if (hr.softwareVersion.get("product_version_text_short") != null) { details.put("product_version_text_short", hr.softwareVersion.get("product_version_text_short")); cmd.setHypervisorVersion(hr.softwareVersion.get("product_version_text_short")); @@ -1942,6 +1952,20 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } + protected void setVmBootDetails(final VM vm, final Connection conn, String bootType, String bootMode) throws XenAPIException, XmlRpcException { + if (!ApiConstants.BootType.UEFI.toString().equals(bootType)) { + bootType = ApiConstants.BootType.BIOS.toString(); + } + Boolean isSecure = bootType.equals(ApiConstants.BootType.UEFI.toString()) && + ApiConstants.BootMode.SECURE.toString().equals(bootMode); + final Map bootParams = vm.getHVMBootParams(conn); + bootParams.replace("firmware", bootType.toLowerCase()); + vm.setHVMBootParams(conn, bootParams); + final Map platform = vm.getPlatform(conn); + platform.put("secureboot", isSecure.toString()); + vm.setPlatform(conn, platform); + } + /** * This method just creates a XenServer network following the tunnel network * naming convention diff --git a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscovererTest.java b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscovererTest.java index f8188afd682..26c2e6da625 100644 --- a/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscovererTest.java +++ b/plugins/hypervisors/xenserver/src/test/java/com/cloud/hypervisor/xenserver/discoverer/XcpServerDiscovererTest.java @@ -17,6 +17,7 @@ package com.cloud.hypervisor.xenserver.discoverer; +import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InOrder; @@ -70,4 +71,25 @@ public class XcpServerDiscovererTest { inOrder.verify(vmTemplateVOMock).setDisplayText("XenServer Tools Installer ISO (xen-pv-drv-iso)"); inOrder.verify(vmTemplateDao).update(1L, vmTemplateVOMock); } + + @Test + public void uefiSupportedVersionTest() { + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("8.2")); + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("8.2.0")); + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("8.2.1")); + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("9")); + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("9.1")); + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("9.1.0")); + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("10")); + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("10.1")); + Assert.assertTrue(XcpServerDiscoverer.isUefiSupported("10.1.0")); + Assert.assertFalse(XcpServerDiscoverer.isUefiSupported(null)); + Assert.assertFalse(XcpServerDiscoverer.isUefiSupported("")); + Assert.assertFalse(XcpServerDiscoverer.isUefiSupported("abc")); + Assert.assertFalse(XcpServerDiscoverer.isUefiSupported("0")); + Assert.assertFalse(XcpServerDiscoverer.isUefiSupported("7.4")); + Assert.assertFalse(XcpServerDiscoverer.isUefiSupported("8")); + Assert.assertFalse(XcpServerDiscoverer.isUefiSupported("8.1")); + Assert.assertFalse(XcpServerDiscoverer.isUefiSupported("8.1.0")); + } } diff --git a/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java b/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java index 01f7689fea2..df6ea74881e 100644 --- a/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java +++ b/server/src/main/java/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java @@ -123,7 +123,7 @@ public class FirstFitAllocator extends AdapterBase implements HostAllocator { isVMDeployedWithUefi = true; } } - s_logger.info(" Guest VM is requested with Cusotm[UEFI] Boot Type "+ isVMDeployedWithUefi); + s_logger.info(" Guest VM is requested with Custom[UEFI] Boot Type "+ isVMDeployedWithUefi); if (type == Host.Type.Storage) { diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index b1c24ccdd40..cd91ce263d6 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -491,10 +491,9 @@
+ v-if="vm.templateid && ['KVM', 'VMware', 'XenServer'].includes(hypervisor) && !template.deployasis">