mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge remote-tracking branch 'origin/4.15'
This commit is contained in:
commit
49acd1dec7
@ -19,6 +19,8 @@
|
||||
|
||||
package org.apache.cloudstack.storage.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.agent.api.to.DiskTO;
|
||||
|
||||
public class DettachCommand extends StorageSubSystemCommand {
|
||||
@ -28,6 +30,7 @@ public class DettachCommand extends StorageSubSystemCommand {
|
||||
private String _iScsiName;
|
||||
private String _storageHost;
|
||||
private int _storagePort;
|
||||
private Map<String, String> params;
|
||||
|
||||
public DettachCommand(final DiskTO disk, final String vmName) {
|
||||
super();
|
||||
@ -35,6 +38,13 @@ public class DettachCommand extends StorageSubSystemCommand {
|
||||
this.vmName = vmName;
|
||||
}
|
||||
|
||||
public DettachCommand(final DiskTO disk, final String vmName, Map<String, String> params) {
|
||||
super();
|
||||
this.disk = disk;
|
||||
this.vmName = vmName;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
@ -88,6 +98,14 @@ public class DettachCommand extends StorageSubSystemCommand {
|
||||
return _storagePort;
|
||||
}
|
||||
|
||||
public Map<String, String> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, String> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExecuteInSequence(final boolean inSeq) {
|
||||
|
||||
|
||||
@ -2426,7 +2426,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
DiskDef.DiskBus busT = getDiskModelFromVMDetail(vmTO);
|
||||
|
||||
if (busT == null) {
|
||||
busT = getGuestDiskModel(vmTO.getPlatformEmulator());
|
||||
busT = getGuestDiskModel(vmTO.getPlatformEmulator(), isUefiEnabled);
|
||||
}
|
||||
|
||||
// If we're using virtio scsi, then we need to add a virtual scsi controller
|
||||
@ -2521,7 +2521,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
}
|
||||
});
|
||||
|
||||
if (MapUtils.isNotEmpty(details) && details.containsKey(GuestDef.BootType.UEFI.toString())) {
|
||||
boolean isUefiEnabled = MapUtils.isNotEmpty(details) && details.containsKey(GuestDef.BootType.UEFI.toString());
|
||||
if (isUefiEnabled) {
|
||||
isSecureBoot = isSecureMode(details.get(GuestDef.BootType.UEFI.toString()));
|
||||
}
|
||||
if (vmSpec.getOs().toLowerCase().contains("window")) {
|
||||
@ -2589,7 +2590,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
// if params contains a rootDiskController key, use its value (this is what other HVs are doing)
|
||||
DiskDef.DiskBus diskBusType = getDiskModelFromVMDetail(vmSpec);
|
||||
if (diskBusType == null) {
|
||||
diskBusType = getGuestDiskModel(vmSpec.getPlatformEmulator());
|
||||
diskBusType = getGuestDiskModel(vmSpec.getPlatformEmulator(), isUefiEnabled);
|
||||
}
|
||||
|
||||
DiskDef.DiskBus diskBusTypeData = getDataDiskModelFromVMDetail(vmSpec);
|
||||
@ -2600,16 +2601,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
final DiskDef disk = new DiskDef();
|
||||
int devId = volume.getDiskSeq().intValue();
|
||||
if (volume.getType() == Volume.Type.ISO) {
|
||||
if (volPath == null) {
|
||||
if (isSecureBoot) {
|
||||
disk.defISODisk(null, devId,isSecureBoot,isWindowsTemplate);
|
||||
} else {
|
||||
/* Add iso as placeholder */
|
||||
disk.defISODisk(null, devId);
|
||||
}
|
||||
} else {
|
||||
disk.defISODisk(volPath, devId);
|
||||
}
|
||||
|
||||
disk.defISODisk(volPath, devId, isUefiEnabled);
|
||||
|
||||
if (_guestCpuArch != null && _guestCpuArch.equals("aarch64")) {
|
||||
disk.setBusType(DiskDef.DiskBus.SCSI);
|
||||
}
|
||||
@ -2636,14 +2630,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
disk.defNetworkBasedDisk(glusterVolume + path.replace(mountpoint, ""), pool.getSourceHost(), pool.getSourcePort(), null,
|
||||
null, devId, diskBusType, DiskProtocol.GLUSTER, DiskDef.DiskFmtType.QCOW2);
|
||||
} else if (pool.getType() == StoragePoolType.CLVM || physicalDisk.getFormat() == PhysicalDiskFormat.RAW) {
|
||||
if (volume.getType() == Volume.Type.DATADISK) {
|
||||
if (volume.getType() == Volume.Type.DATADISK && !(isWindowsTemplate && isUefiEnabled)) {
|
||||
disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData);
|
||||
}
|
||||
else {
|
||||
disk.defBlockBasedDisk(physicalDisk.getPath(), devId, diskBusType);
|
||||
}
|
||||
} else {
|
||||
if (volume.getType() == Volume.Type.DATADISK) {
|
||||
if (volume.getType() == Volume.Type.DATADISK && !(isWindowsTemplate && isUefiEnabled)) {
|
||||
disk.defFileBasedDisk(physicalDisk.getPath(), devId, diskBusTypeData, DiskDef.DiskFmtType.QCOW2);
|
||||
} else {
|
||||
if (isSecureBoot) {
|
||||
@ -3429,7 +3423,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
}
|
||||
|
||||
boolean isGuestPVEnabled(final String guestOSName) {
|
||||
DiskDef.DiskBus db = getGuestDiskModel(guestOSName);
|
||||
DiskDef.DiskBus db = getGuestDiskModel(guestOSName, false);
|
||||
return db != DiskDef.DiskBus.IDE;
|
||||
}
|
||||
|
||||
@ -3483,7 +3477,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
return null;
|
||||
}
|
||||
|
||||
private DiskDef.DiskBus getGuestDiskModel(final String platformEmulator) {
|
||||
private DiskDef.DiskBus getGuestDiskModel(final String platformEmulator, boolean isUefiEnabled) {
|
||||
if (_guestCpuArch != null && _guestCpuArch.equals("aarch64")) {
|
||||
return DiskDef.DiskBus.SCSI;
|
||||
}
|
||||
@ -3492,6 +3486,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
return DiskDef.DiskBus.IDE;
|
||||
} else if (platformEmulator.startsWith("Other PV Virtio-SCSI")) {
|
||||
return DiskDef.DiskBus.SCSI;
|
||||
} else if (isUefiEnabled && platformEmulator.startsWith("Windows")) {
|
||||
return DiskDef.DiskBus.SATA;
|
||||
} else if (platformEmulator.contains("Ubuntu") ||
|
||||
platformEmulator.startsWith("Fedora") ||
|
||||
platformEmulator.startsWith("CentOS") ||
|
||||
|
||||
@ -716,16 +716,14 @@ public class LibvirtVMDef {
|
||||
} else if (bus == DiskBus.VIRTIO) {
|
||||
return "vd" + getDevLabelSuffix(devId);
|
||||
} else if (bus == DiskBus.SATA){
|
||||
if (!forIso) {
|
||||
return "sda";
|
||||
}
|
||||
return "sd" + getDevLabelSuffix(devId);
|
||||
}
|
||||
if (forIso) {
|
||||
devId --;
|
||||
} else if(devId >= 2) {
|
||||
devId += 2;
|
||||
}
|
||||
return (DiskBus.SATA == bus) ? "sdb" : "hd" + getDevLabelSuffix(devId);
|
||||
return "hd" + getDevLabelSuffix(devId);
|
||||
|
||||
}
|
||||
|
||||
@ -784,6 +782,16 @@ public class LibvirtVMDef {
|
||||
_bus = DiskBus.IDE;
|
||||
}
|
||||
|
||||
public void defISODisk(String volPath, boolean isUefiEnabled) {
|
||||
_diskType = DiskType.FILE;
|
||||
_deviceType = DeviceType.CDROM;
|
||||
_sourcePath = volPath;
|
||||
_bus = isUefiEnabled ? DiskBus.SATA : DiskBus.IDE;
|
||||
_diskLabel = getDevLabel(3, _bus, true);
|
||||
_diskFmtType = DiskFmtType.RAW;
|
||||
_diskCacheMode = DiskCacheMode.NONE;
|
||||
}
|
||||
|
||||
public void defISODisk(String volPath, Integer devId) {
|
||||
if (devId == null) {
|
||||
defISODisk(volPath);
|
||||
@ -798,20 +806,15 @@ public class LibvirtVMDef {
|
||||
}
|
||||
}
|
||||
|
||||
public void defISODisk(String volPath, Integer devId,boolean isSecure, boolean isWindowOs) {
|
||||
public void defISODisk(String volPath, Integer devId,boolean isSecure) {
|
||||
if (!isSecure) {
|
||||
defISODisk(volPath, devId);
|
||||
} else {
|
||||
_diskType = DiskType.FILE;
|
||||
_deviceType = DeviceType.CDROM;
|
||||
_sourcePath = volPath;
|
||||
if (isWindowOs) {
|
||||
_diskLabel = getDevLabel(devId, DiskBus.SATA, true);
|
||||
_bus = DiskBus.SATA;
|
||||
} else {
|
||||
_diskLabel = getDevLabel(devId, DiskBus.SCSI, true);
|
||||
_bus = DiskBus.SCSI;
|
||||
}
|
||||
_diskLabel = getDevLabel(devId, DiskBus.SATA, true);
|
||||
_bus = DiskBus.SATA;
|
||||
_diskFmtType = DiskFmtType.RAW;
|
||||
_diskCacheMode = DiskCacheMode.NONE;
|
||||
|
||||
|
||||
@ -67,6 +67,7 @@ import org.apache.cloudstack.utils.qemu.QemuImg;
|
||||
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
|
||||
import org.apache.cloudstack.utils.qemu.QemuImgException;
|
||||
import org.apache.cloudstack.utils.qemu.QemuImgFile;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libvirt.Connect;
|
||||
@ -1081,9 +1082,10 @@ public class KVMStorageProcessor implements StorageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach) throws LibvirtException, URISyntaxException,
|
||||
protected synchronized String attachOrDetachISO(final Connect conn, final String vmName, String isoPath, final boolean isAttach, Map<String, String> params) throws LibvirtException, URISyntaxException,
|
||||
InternalErrorException {
|
||||
String isoXml = null;
|
||||
boolean isUefiEnabled = MapUtils.isNotEmpty(params) && params.containsKey("UEFI");
|
||||
if (isoPath != null && isAttach) {
|
||||
final int index = isoPath.lastIndexOf("/");
|
||||
final String path = isoPath.substring(0, index);
|
||||
@ -1093,11 +1095,11 @@ public class KVMStorageProcessor implements StorageProcessor {
|
||||
isoPath = isoVol.getPath();
|
||||
|
||||
final DiskDef iso = new DiskDef();
|
||||
iso.defISODisk(isoPath);
|
||||
iso.defISODisk(isoPath, isUefiEnabled);
|
||||
isoXml = iso.toString();
|
||||
} else {
|
||||
final DiskDef iso = new DiskDef();
|
||||
iso.defISODisk(null);
|
||||
iso.defISODisk(null, isUefiEnabled);
|
||||
isoXml = iso.toString();
|
||||
}
|
||||
|
||||
@ -1123,7 +1125,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
||||
try {
|
||||
String dataStoreUrl = getDataStoreUrlFromStore(store);
|
||||
final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
|
||||
attachOrDetachISO(conn, cmd.getVmName(), dataStoreUrl + File.separator + isoTO.getPath(), true);
|
||||
attachOrDetachISO(conn, cmd.getVmName(), dataStoreUrl + File.separator + isoTO.getPath(), true, cmd.getControllerInfo());
|
||||
} catch (final LibvirtException e) {
|
||||
return new Answer(cmd, false, e.toString());
|
||||
} catch (final URISyntaxException e) {
|
||||
@ -1146,7 +1148,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
||||
try {
|
||||
String dataStoreUrl = getDataStoreUrlFromStore(store);
|
||||
final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
|
||||
attachOrDetachISO(conn, cmd.getVmName(), dataStoreUrl + File.separator + isoTO.getPath(), false);
|
||||
attachOrDetachISO(conn, cmd.getVmName(), dataStoreUrl + File.separator + isoTO.getPath(), false, cmd.getParams());
|
||||
} catch (final LibvirtException e) {
|
||||
return new Answer(cmd, false, e.toString());
|
||||
} catch (final URISyntaxException e) {
|
||||
|
||||
2
pom.xml
2
pom.xml
@ -112,7 +112,7 @@
|
||||
<cs.selenium.server.version>1.0-20081010.060147</cs.selenium.server.version>
|
||||
<cs.selenium-java-client-driver.version>1.0.1</cs.selenium-java-client-driver.version>
|
||||
<cs.testng.version>7.1.0</cs.testng.version>
|
||||
<cs.wiremock.version>2.11.0</cs.wiremock.version>
|
||||
<cs.wiremock.version>2.27.2</cs.wiremock.version>
|
||||
<cs.xercesImpl.version>2.12.0</cs.xercesImpl.version>
|
||||
|
||||
<!-- Dependencies versions -->
|
||||
|
||||
@ -112,6 +112,7 @@ import com.cloud.agent.api.to.DataTO;
|
||||
import com.cloud.agent.api.to.DatadiskTO;
|
||||
import com.cloud.agent.api.to.DiskTO;
|
||||
import com.cloud.agent.api.to.NfsTO;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.api.ApiResponseHelper;
|
||||
import com.cloud.api.query.dao.UserVmJoinDao;
|
||||
@ -136,6 +137,8 @@ import com.cloud.exception.StorageUnavailableException;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.HypervisorGuru;
|
||||
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
@ -199,6 +202,7 @@ import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
@ -283,6 +287,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
MessageBus _messageBus;
|
||||
@Inject
|
||||
private VMTemplateDetailsDao _tmpltDetailsDao;
|
||||
@Inject
|
||||
private HypervisorGuruManager _hvGuruMgr;
|
||||
|
||||
private boolean _disableExtraction = false;
|
||||
private List<TemplateAdapter> _adapters;
|
||||
@ -1289,11 +1295,16 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
||||
|
||||
DataTO isoTO = tmplt.getTO();
|
||||
DiskTO disk = new DiskTO(isoTO, null, null, Volume.Type.ISO);
|
||||
|
||||
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
|
||||
VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
|
||||
VirtualMachineTO vmTO = hvGuru.implement(profile);
|
||||
|
||||
Command cmd = null;
|
||||
if (attach) {
|
||||
cmd = new AttachCommand(disk, vmName);
|
||||
cmd = new AttachCommand(disk, vmName, vmTO.getDetails());
|
||||
} else {
|
||||
cmd = new DettachCommand(disk, vmName);
|
||||
cmd = new DettachCommand(disk, vmName, vmTO.getDetails());
|
||||
}
|
||||
Answer a = _agentMgr.easySend(vm.getHostId(), cmd);
|
||||
return (a != null && a.getResult());
|
||||
|
||||
@ -30,6 +30,7 @@ import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.TemplateProfile;
|
||||
import com.cloud.projects.ProjectManager;
|
||||
@ -180,6 +181,8 @@ public class TemplateManagerImplTest {
|
||||
@Inject
|
||||
private VMTemplateDao _tmpltDao;
|
||||
|
||||
@Inject
|
||||
HypervisorGuruManager _hvGuruMgr;
|
||||
|
||||
public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
|
||||
AtomicInteger ai = new AtomicInteger(0);
|
||||
@ -697,6 +700,11 @@ public class TemplateManagerImplTest {
|
||||
return Mockito.mock(VMTemplateDetailsDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HypervisorGuruManager hypervisorGuruManager() {
|
||||
return Mockito.mock(HypervisorGuruManager.class);
|
||||
}
|
||||
|
||||
public static class Library implements TypeFilter {
|
||||
@Override
|
||||
public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
|
||||
|
||||
235
test/integration/smoke/test_deploy_vm_iso_uefi.py
Normal file
235
test/integration/smoke/test_deploy_vm_iso_uefi.py
Normal file
@ -0,0 +1,235 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
""" Deploy VM from ISO with UEFI
|
||||
"""
|
||||
# Import Local Modules
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
|
||||
from marvin.lib.utils import cleanup_resources
|
||||
from marvin.lib.base import (Account,
|
||||
VirtualMachine,
|
||||
ServiceOffering,
|
||||
Iso,
|
||||
DiskOffering,
|
||||
Host,
|
||||
)
|
||||
from marvin.lib.common import (get_zone,
|
||||
get_domain,
|
||||
list_hosts,
|
||||
)
|
||||
from marvin.codes import PASS
|
||||
from marvin.sshClient import SshClient
|
||||
import xml.etree.ElementTree as ET
|
||||
from lxml import etree
|
||||
|
||||
class TestDeployVMFromISOWithUefi(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestDeployVMFromISOWithUefi, cls).getClsTestClient()
|
||||
cls.apiclient = cls.testClient.getApiClient()
|
||||
|
||||
cls.hypervisor = cls.testClient.getHypervisorInfo()
|
||||
|
||||
if cls.hypervisor != 'kvm':
|
||||
raise unittest.SkipTest("Those tests can be run only for KVM hypervisor")
|
||||
|
||||
cls.testdata = cls.testClient.getParsedTestDataConfig()
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.apiclient)
|
||||
cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||
|
||||
hosts = list_hosts(cls.apiclient, zoneid = cls.zone.id, type="Routing")
|
||||
|
||||
if not cls.isUefiEnabledOnAtLeastOnHost(hosts):
|
||||
raise unittest.SkipTest("At least one host should support UEFI")
|
||||
|
||||
cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__
|
||||
|
||||
# Create service, disk offerings etc
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.apiclient,
|
||||
cls.testdata["service_offering"]
|
||||
)
|
||||
|
||||
cls.disk_offering = DiskOffering.create(
|
||||
cls.apiclient,
|
||||
cls.testdata["disk_offering"]
|
||||
)
|
||||
|
||||
cls.testdata["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.testdata["iso1"]["zoneid"] = cls.zone.id
|
||||
cls.testdata["iso3"]["zoneid"] = cls.zone.id
|
||||
cls.account = Account.create(
|
||||
cls.apiclient,
|
||||
cls.testdata["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
cls._cleanup = [cls.account, cls.service_offering, cls.disk_offering]
|
||||
|
||||
cls.centos_iso = Iso.create(
|
||||
cls.apiclient,
|
||||
cls.testdata["iso1"],
|
||||
account=cls.account.name,
|
||||
domainid=cls.account.domainid,
|
||||
zoneid=cls.zone.id
|
||||
)
|
||||
try:
|
||||
# Download the ISO
|
||||
cls.centos_iso.download(cls.apiclient)
|
||||
except Exception as e:
|
||||
raise Exception("Exception while downloading ISO %s: %s"
|
||||
% (cls.centos_iso.id, e))
|
||||
|
||||
cls.windows_iso = Iso.create(
|
||||
cls.apiclient,
|
||||
cls.testdata["iso3"],
|
||||
account=cls.account.name,
|
||||
domainid=cls.account.domainid,
|
||||
zoneid=cls.zone.id
|
||||
)
|
||||
try:
|
||||
# Download the ISO
|
||||
cls.windows_iso.download(cls.apiclient)
|
||||
except Exception as e:
|
||||
raise Exception("Exception while downloading ISO %s: %s"
|
||||
% (cls.windows_iso.id, e))
|
||||
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cleanup_resources(cls.apiclient, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
def setUp(self):
|
||||
self.hypervisor = self.testClient.getHypervisorInfo()
|
||||
if self.hypervisor != 'kvm':
|
||||
raise self.skipTest("Skipping test case for non-kvm hypervisor")
|
||||
return
|
||||
|
||||
|
||||
@attr(tags=["advanced", "eip", "advancedns", "basic", "sg"], required_hardware="true")
|
||||
def test_01_deploy_vm_from_iso_uefi_secure(self):
|
||||
"""Test Deploy CentOS Virtual Machine from ISO with UEFI Secure
|
||||
"""
|
||||
|
||||
self.deployVmAndTestUefi(self.centos_iso, 'Secure', 'yes')
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "eip", "advancedns", "basic", "sg"], required_hardware="true")
|
||||
def test_02_deploy_vm_from_iso_uefi_legacy(self):
|
||||
"""Test Deploy CentOS Virtual Machine from ISO with UEFI Legacy mode
|
||||
"""
|
||||
self.deployVmAndTestUefi(self.centos_iso, 'Legacy', 'no')
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "eip", "advancedns", "basic", "sg"], required_hardware="true")
|
||||
def test_03_deploy_windows_vm_from_iso_uefi_legacy(self):
|
||||
"""Test Deploy Windows Virtual Machine from ISO with UEFI Legacy mode
|
||||
"""
|
||||
self.deployVmAndTestUefi(self.windows_iso, 'Legacy', 'no')
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "eip", "advancedns", "basic", "sg"], required_hardware="true")
|
||||
def test_04_deploy_windows_vm_from_iso_uefi_secure(self):
|
||||
"""Test Deploy Windows Virtual Machine from ISO with UEFI Secure mode
|
||||
"""
|
||||
self.deployVmAndTestUefi(self.windows_iso, 'Secure', 'yes')
|
||||
|
||||
return
|
||||
|
||||
def getVirshXML(self, host, instancename):
|
||||
self.assertIsNotNone(host, "Host should not be None")
|
||||
|
||||
self.assertIsNotNone(instancename, "Instance name should not be None")
|
||||
|
||||
sshc = SshClient(
|
||||
host=host.ipaddress,
|
||||
port=22,
|
||||
user=self.hostConfig['username'],
|
||||
passwd=self.hostConfig['password'])
|
||||
|
||||
virsh_cmd = 'virsh dumpxml %s' % instancename
|
||||
xml_res = sshc.execute(virsh_cmd)
|
||||
xml_as_str = ''.join(xml_res)
|
||||
parser = etree.XMLParser(remove_blank_text=True)
|
||||
return ET.fromstring(xml_as_str, parser=parser)
|
||||
|
||||
def checkBootTypeAndMode(self, root, bootmodesecure, isWindowsIso):
|
||||
|
||||
machine = root.find(".os/type").get("machine")
|
||||
|
||||
self.assertEqual(("q35" in machine), True, "The virtual machine is not with UEFI boot type")
|
||||
|
||||
bootmode = root.find(".os/loader").get("secure")
|
||||
|
||||
self.assertEqual((bootmode == bootmodesecure), True, "The VM is not in the right boot mode")
|
||||
|
||||
if isWindowsIso:
|
||||
disks = root.findall("devices/disk")
|
||||
for disk in disks:
|
||||
bus = disk.find("target").get("bus")
|
||||
self.debug("bus is %s" % bus)
|
||||
self.assertEqual(bus == 'sata', True, "All disks of the VM should be with bus SATA")
|
||||
|
||||
def deployVmAndTestUefi(self, iso, bootmode, bootmodesecure):
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.testdata["virtual_machine"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
templateid=iso.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
diskofferingid=self.disk_offering.id,
|
||||
hypervisor=self.hypervisor,
|
||||
boottype='UEFI',
|
||||
bootmode=bootmode,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
|
||||
response = self.virtual_machine.getState(
|
||||
self.apiclient,
|
||||
VirtualMachine.RUNNING)
|
||||
self.assertEqual(response[0], PASS, response[1])
|
||||
|
||||
hosts = Host.list(self.apiclient, id=self.virtual_machine.hostid)
|
||||
if len(hosts) != 1:
|
||||
assert False, "Could not find host with id " + self.virtual_machine.hostid
|
||||
|
||||
host = hosts[0]
|
||||
|
||||
isWindowsIso = False
|
||||
if "Windows" in iso.ostypename:
|
||||
isWindowsIso = True
|
||||
|
||||
instancename = self.virtual_machine.instancename
|
||||
virshxml = self.getVirshXML(host, instancename)
|
||||
self.checkBootTypeAndMode(virshxml, bootmodesecure, isWindowsIso)
|
||||
|
||||
@classmethod
|
||||
def isUefiEnabledOnAtLeastOnHost(cls, hosts):
|
||||
for h in hosts:
|
||||
if h.ueficapability:
|
||||
return True
|
||||
return False
|
||||
@ -940,6 +940,16 @@ test_data = {
|
||||
"ostype": "CentOS 5.6 (64-bit)",
|
||||
"mode": 'HTTP_DOWNLOAD',
|
||||
},
|
||||
"iso3": {
|
||||
"displaytext": "Test ISO 3",
|
||||
"name": "ISO 3",
|
||||
"url": "http://people.apache.org/~tsp/dummy.iso",
|
||||
"isextractable": True,
|
||||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"ostype": "Windows Server 2012 (64-bit)",
|
||||
"mode": 'HTTP_DOWNLOAD',
|
||||
},
|
||||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"isextractable": True,
|
||||
|
||||
@ -522,7 +522,7 @@ class VirtualMachine:
|
||||
method='GET', hypervisor=None, customcpunumber=None,
|
||||
customcpuspeed=None, custommemory=None, rootdisksize=None,
|
||||
rootdiskcontroller=None, vpcid=None, macaddress=None, datadisktemplate_diskoffering_list={},
|
||||
properties=None, nicnetworklist=None):
|
||||
properties=None, nicnetworklist=None, bootmode=None, boottype=None):
|
||||
"""Create the instance"""
|
||||
|
||||
cmd = deployVirtualMachine.deployVirtualMachineCmd()
|
||||
@ -657,6 +657,12 @@ class VirtualMachine:
|
||||
if nicnetworklist:
|
||||
cmd.nicnetworklist = nicnetworklist
|
||||
|
||||
if bootmode:
|
||||
cmd.bootmode = bootmode
|
||||
|
||||
if boottype:
|
||||
cmd.boottype = boottype
|
||||
|
||||
virtual_machine = apiclient.deployVirtualMachine(cmd, method=method)
|
||||
|
||||
if 'password' in virtual_machine.__dict__.keys():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user