mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
vmware: Fix VMware OVF properties copy from template (#4738)
* Fix VMware OVF properties copy from template * Fix vapp marvin test * Remove unused code * Fix check for deploy as is details * Access class fields
This commit is contained in:
parent
a64ad9d9b7
commit
9cf1e0e869
@ -59,6 +59,7 @@ import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
|||||||
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
||||||
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.collections.MapUtils;
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.lang.math.NumberUtils;
|
import org.apache.commons.lang.math.NumberUtils;
|
||||||
@ -2336,7 +2337,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
configBasicExtraOption(extraOptions, vmSpec);
|
configBasicExtraOption(extraOptions, vmSpec);
|
||||||
|
|
||||||
if (deployAsIs) {
|
if (deployAsIs) {
|
||||||
setDeployAsIsProperties(vmMo, deployAsIsInfo, vmConfigSpec);
|
setDeployAsIsProperties(vmMo, deployAsIsInfo, vmConfigSpec, hyperHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid);
|
configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid);
|
||||||
@ -2563,12 +2564,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
* Set OVF properties (if available)
|
* Set OVF properties (if available)
|
||||||
*/
|
*/
|
||||||
private void setDeployAsIsProperties(VirtualMachineMO vmMo, DeployAsIsInfoTO deployAsIsInfo,
|
private void setDeployAsIsProperties(VirtualMachineMO vmMo, DeployAsIsInfoTO deployAsIsInfo,
|
||||||
VirtualMachineConfigSpec vmConfigSpec) throws Exception {
|
VirtualMachineConfigSpec vmConfigSpec, VmwareHypervisorHost hyperHost) throws Exception {
|
||||||
if (deployAsIsInfo != null) {
|
if (deployAsIsInfo != null && MapUtils.isNotEmpty(deployAsIsInfo.getProperties())) {
|
||||||
Map<String, String> properties = deployAsIsInfo.getProperties();
|
Map<String, String> properties = deployAsIsInfo.getProperties();
|
||||||
VmConfigInfo vAppConfig = vmMo.getConfigInfo().getVAppConfig();
|
VmConfigInfo vAppConfig = vmMo.getConfigInfo().getVAppConfig();
|
||||||
s_logger.info("Copying OVF properties to the values the user provided");
|
s_logger.info("Copying OVF properties to the values the user provided");
|
||||||
setVAppPropertiesToConfigSpec(vAppConfig, properties, vmConfigSpec);
|
setVAppPropertiesToConfigSpec(vAppConfig, properties, vmConfigSpec, hyperHost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2660,13 +2661,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
/**
|
/**
|
||||||
* Set the ovf section spec from existing vApp configuration
|
* Set the ovf section spec from existing vApp configuration
|
||||||
*/
|
*/
|
||||||
protected List<VAppOvfSectionSpec> copyVAppConfigOvfSectionFromOVF(VmConfigInfo vAppConfig) {
|
protected List<VAppOvfSectionSpec> copyVAppConfigOvfSectionFromOVF(VmConfigInfo vAppConfig, boolean useEdit) {
|
||||||
List<VAppOvfSectionInfo> ovfSection = vAppConfig.getOvfSection();
|
List<VAppOvfSectionInfo> ovfSection = vAppConfig.getOvfSection();
|
||||||
List<VAppOvfSectionSpec> specs = new ArrayList<>();
|
List<VAppOvfSectionSpec> specs = new ArrayList<>();
|
||||||
for (VAppOvfSectionInfo info : ovfSection) {
|
for (VAppOvfSectionInfo info : ovfSection) {
|
||||||
VAppOvfSectionSpec spec = new VAppOvfSectionSpec();
|
VAppOvfSectionSpec spec = new VAppOvfSectionSpec();
|
||||||
spec.setInfo(info);
|
spec.setInfo(info);
|
||||||
spec.setOperation(ArrayUpdateOperation.ADD);
|
spec.setOperation(useEdit ? ArrayUpdateOperation.EDIT : ArrayUpdateOperation.ADD);
|
||||||
specs.add(spec);
|
specs.add(spec);
|
||||||
}
|
}
|
||||||
return specs;
|
return specs;
|
||||||
@ -2694,7 +2695,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
/**
|
/**
|
||||||
* Set the properties section from existing vApp configuration and values set on ovfProperties
|
* Set the properties section from existing vApp configuration and values set on ovfProperties
|
||||||
*/
|
*/
|
||||||
protected List<VAppPropertySpec> copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, Map<String, String> ovfProperties) {
|
protected List<VAppPropertySpec> copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, Map<String, String> ovfProperties,
|
||||||
|
boolean useEdit) {
|
||||||
List<VAppPropertyInfo> productFromOvf = vAppConfig.getProperty();
|
List<VAppPropertyInfo> productFromOvf = vAppConfig.getProperty();
|
||||||
List<VAppPropertySpec> specs = new ArrayList<>();
|
List<VAppPropertySpec> specs = new ArrayList<>();
|
||||||
for (VAppPropertyInfo info : productFromOvf) {
|
for (VAppPropertyInfo info : productFromOvf) {
|
||||||
@ -2702,9 +2704,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
if (ovfProperties.containsKey(info.getId())) {
|
if (ovfProperties.containsKey(info.getId())) {
|
||||||
String value = ovfProperties.get(info.getId());
|
String value = ovfProperties.get(info.getId());
|
||||||
info.setValue(value);
|
info.setValue(value);
|
||||||
|
s_logger.info("Setting OVF property ID = " + info.getId() + " VALUE = " + value);
|
||||||
}
|
}
|
||||||
spec.setInfo(info);
|
spec.setInfo(info);
|
||||||
spec.setOperation(ArrayUpdateOperation.ADD);
|
spec.setOperation(useEdit ? ArrayUpdateOperation.EDIT : ArrayUpdateOperation.ADD);
|
||||||
specs.add(spec);
|
specs.add(spec);
|
||||||
}
|
}
|
||||||
return specs;
|
return specs;
|
||||||
@ -2713,13 +2716,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
/**
|
/**
|
||||||
* Set the product section spec from existing vApp configuration
|
* Set the product section spec from existing vApp configuration
|
||||||
*/
|
*/
|
||||||
protected List<VAppProductSpec> copyVAppConfigProductSectionFromOVF(VmConfigInfo vAppConfig) {
|
protected List<VAppProductSpec> copyVAppConfigProductSectionFromOVF(VmConfigInfo vAppConfig, boolean useEdit) {
|
||||||
List<VAppProductInfo> productFromOvf = vAppConfig.getProduct();
|
List<VAppProductInfo> productFromOvf = vAppConfig.getProduct();
|
||||||
List<VAppProductSpec> specs = new ArrayList<>();
|
List<VAppProductSpec> specs = new ArrayList<>();
|
||||||
for (VAppProductInfo info : productFromOvf) {
|
for (VAppProductInfo info : productFromOvf) {
|
||||||
VAppProductSpec spec = new VAppProductSpec();
|
VAppProductSpec spec = new VAppProductSpec();
|
||||||
spec.setInfo(info);
|
spec.setInfo(info);
|
||||||
spec.setOperation(ArrayUpdateOperation.ADD);
|
s_logger.info("Procuct info KEY " + info.getKey());
|
||||||
|
spec.setOperation(useEdit ? ArrayUpdateOperation.EDIT : ArrayUpdateOperation.ADD);
|
||||||
specs.add(spec);
|
specs.add(spec);
|
||||||
}
|
}
|
||||||
return specs;
|
return specs;
|
||||||
@ -2731,16 +2735,19 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||||||
*/
|
*/
|
||||||
protected void setVAppPropertiesToConfigSpec(VmConfigInfo vAppConfig,
|
protected void setVAppPropertiesToConfigSpec(VmConfigInfo vAppConfig,
|
||||||
Map<String, String> ovfProperties,
|
Map<String, String> ovfProperties,
|
||||||
VirtualMachineConfigSpec vmConfig) throws Exception {
|
VirtualMachineConfigSpec vmConfig, VmwareHypervisorHost hyperHost) throws Exception {
|
||||||
VmConfigSpec vmConfigSpec = new VmConfigSpec();
|
VmConfigSpec vmConfigSpec = new VmConfigSpec();
|
||||||
vmConfigSpec.getEula().addAll(vAppConfig.getEula());
|
vmConfigSpec.getEula().addAll(vAppConfig.getEula());
|
||||||
vmConfigSpec.setInstallBootStopDelay(vAppConfig.getInstallBootStopDelay());
|
vmConfigSpec.setInstallBootStopDelay(vAppConfig.getInstallBootStopDelay());
|
||||||
vmConfigSpec.setInstallBootRequired(vAppConfig.isInstallBootRequired());
|
vmConfigSpec.setInstallBootRequired(vAppConfig.isInstallBootRequired());
|
||||||
vmConfigSpec.setIpAssignment(vAppConfig.getIpAssignment());
|
vmConfigSpec.setIpAssignment(vAppConfig.getIpAssignment());
|
||||||
vmConfigSpec.getOvfEnvironmentTransport().addAll(vAppConfig.getOvfEnvironmentTransport());
|
vmConfigSpec.getOvfEnvironmentTransport().addAll(vAppConfig.getOvfEnvironmentTransport());
|
||||||
vmConfigSpec.getProduct().addAll(copyVAppConfigProductSectionFromOVF(vAppConfig));
|
|
||||||
vmConfigSpec.getProperty().addAll(copyVAppConfigPropertySectionFromOVF(vAppConfig, ovfProperties));
|
// For backward compatibility, prior to Vmware 6.5 use EDIT operation instead of ADD
|
||||||
vmConfigSpec.getOvfSection().addAll(copyVAppConfigOvfSectionFromOVF(vAppConfig));
|
boolean useEditOperation = hyperHost.getContext().getServiceContent().getAbout().getApiVersion().compareTo("6.5") < 1;
|
||||||
|
vmConfigSpec.getProduct().addAll(copyVAppConfigProductSectionFromOVF(vAppConfig, useEditOperation));
|
||||||
|
vmConfigSpec.getProperty().addAll(copyVAppConfigPropertySectionFromOVF(vAppConfig, ovfProperties, useEditOperation));
|
||||||
|
vmConfigSpec.getOvfSection().addAll(copyVAppConfigOvfSectionFromOVF(vAppConfig, useEditOperation));
|
||||||
vmConfig.setVAppConfig(vmConfigSpec);
|
vmConfig.setVAppConfig(vmConfigSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,6 @@ from operator import itemgetter
|
|||||||
|
|
||||||
_multiprocess_shared_ = True
|
_multiprocess_shared_ = True
|
||||||
|
|
||||||
|
|
||||||
class TestDeployVM(cloudstackTestCase):
|
class TestDeployVM(cloudstackTestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -1750,9 +1749,6 @@ class TestVAppsVM(cloudstackTestCase):
|
|||||||
cls.l2_network_offering
|
cls.l2_network_offering
|
||||||
]
|
]
|
||||||
|
|
||||||
# Uncomment when tests are finished, to cleanup the test templates
|
|
||||||
for template in cls.templates:
|
|
||||||
cls._cleanup.append(template)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
@ -1774,21 +1770,21 @@ class TestVAppsVM(cloudstackTestCase):
|
|||||||
def get_ova_parsed_information_from_template(self, template):
|
def get_ova_parsed_information_from_template(self, template):
|
||||||
if not template:
|
if not template:
|
||||||
return None
|
return None
|
||||||
details = template.details.__dict__
|
details = template.deployasisdetails.__dict__
|
||||||
configurations = []
|
configurations = []
|
||||||
disks = []
|
disks = []
|
||||||
isos = []
|
isos = []
|
||||||
networks = []
|
networks = []
|
||||||
for propKey in details:
|
for propKey in details:
|
||||||
if propKey.startswith('ACS-configuration'):
|
if propKey.startswith('configuration'):
|
||||||
configurations.append(json.loads(details[propKey]))
|
configurations.append(json.loads(details[propKey]))
|
||||||
elif propKey.startswith('ACS-disk'):
|
elif propKey.startswith('disk'):
|
||||||
detail = json.loads(details[propKey])
|
detail = json.loads(details[propKey])
|
||||||
if detail['isIso'] == True:
|
if detail['isIso'] == True:
|
||||||
isos.append(detail)
|
isos.append(detail)
|
||||||
else:
|
else:
|
||||||
disks.append(detail)
|
disks.append(detail)
|
||||||
elif propKey.startswith('ACS-network'):
|
elif propKey.startswith('network'):
|
||||||
networks.append(json.loads(details[propKey]))
|
networks.append(json.loads(details[propKey]))
|
||||||
|
|
||||||
return configurations, disks, isos, networks
|
return configurations, disks, isos, networks
|
||||||
@ -1818,32 +1814,6 @@ class TestVAppsVM(cloudstackTestCase):
|
|||||||
msg="VM NIC(InstanceID: {}) network mismatch, expected = {}, result = {}".format(nic_network["nic"], nic_network["network"], nic.networkid)
|
msg="VM NIC(InstanceID: {}) network mismatch, expected = {}, result = {}".format(nic_network["nic"], nic_network["network"], nic.networkid)
|
||||||
)
|
)
|
||||||
|
|
||||||
def verify_disks(self, template_disks, vm_id):
|
|
||||||
cmd = listVolumes.listVolumesCmd()
|
|
||||||
cmd.virtualmachineid = vm_id
|
|
||||||
cmd.listall = True
|
|
||||||
vm_volumes = self.apiclient.listVolumes(cmd)
|
|
||||||
self.assertEqual(
|
|
||||||
isinstance(vm_volumes, list),
|
|
||||||
True,
|
|
||||||
"Check listVolumes response returns a valid list"
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
len(template_disks),
|
|
||||||
len(vm_volumes),
|
|
||||||
msg="VM volumes count is different, expected = {}, result = {}".format(len(template_disks), len(vm_volumes))
|
|
||||||
)
|
|
||||||
template_disks.sort(key=itemgetter('diskNumber'))
|
|
||||||
vm_volumes.sort(key=itemgetter('deviceid'))
|
|
||||||
for j in range(len(vm_volumes)):
|
|
||||||
volume = vm_volumes[j]
|
|
||||||
disk = template_disks[j]
|
|
||||||
self.assertEqual(
|
|
||||||
volume.size,
|
|
||||||
disk["virtualSize"],
|
|
||||||
msg="VM Volume(diskNumber: {}) network mismatch, expected = {}, result = {}".format(disk["diskNumber"], disk["virtualSize"], volume.size)
|
|
||||||
)
|
|
||||||
|
|
||||||
@attr(tags=["advanced", "advancedns", "smoke", "sg", "dev"], required_hardware="false")
|
@attr(tags=["advanced", "advancedns", "smoke", "sg", "dev"], required_hardware="false")
|
||||||
@skipTestIf("hypervisorNotSupported")
|
@skipTestIf("hypervisorNotSupported")
|
||||||
def test_01_vapps_vm_cycle(self):
|
def test_01_vapps_vm_cycle(self):
|
||||||
@ -1944,8 +1914,6 @@ class TestVAppsVM(cloudstackTestCase):
|
|||||||
|
|
||||||
# Verify nics
|
# Verify nics
|
||||||
self.verify_nics(nicnetworklist, vm.id)
|
self.verify_nics(nicnetworklist, vm.id)
|
||||||
# Verify disks
|
|
||||||
self.verify_disks(disks, vm.id)
|
|
||||||
# Verify properties
|
# Verify properties
|
||||||
original_properties = vm_service['properties']
|
original_properties = vm_service['properties']
|
||||||
vm_properties = get_vm_vapp_configs(self.apiclient, self.config, self.zone, vm.instancename)
|
vm_properties = get_vm_vapp_configs(self.apiclient, self.config, self.zone, vm.instancename)
|
||||||
|
|||||||
@ -429,21 +429,21 @@ def get_test_ovf_templates(apiclient, zone_id=None, test_ovf_templates=None, hyp
|
|||||||
template = Template.register(apiclient, test_template, zoneid=zone_id, hypervisor=hypervisor.lower(), randomize_name=False)
|
template = Template.register(apiclient, test_template, zoneid=zone_id, hypervisor=hypervisor.lower(), randomize_name=False)
|
||||||
template.download(apiclient)
|
template.download(apiclient)
|
||||||
retries = 3
|
retries = 3
|
||||||
while (template.details == None or len(template.details.__dict__) == 0) and retries > 0:
|
while (not hasattr(template, 'deployasisdetails') or len(template.deployasisdetails.__dict__) == 0) and retries > 0:
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
template_list = Template.list(apiclient, id=template.id, zoneid=zone_id, templatefilter='all')
|
template_list = Template.list(apiclient, id=template.id, zoneid=zone_id, templatefilter='all')
|
||||||
if isinstance(template_list, list):
|
if isinstance(template_list, list):
|
||||||
template = Template(template_list[0].__dict__)
|
template = Template(template_list[0].__dict__)
|
||||||
retries = retries - 1
|
retries = retries - 1
|
||||||
if template.details == None or len(template.details.__dict__) == 0:
|
if not hasattr(template, 'deployasisdetails') or len(template.deployasisdetails.__dict__) == 0:
|
||||||
template.delete(apiclient)
|
template.delete(apiclient)
|
||||||
else:
|
else:
|
||||||
result.append(template)
|
result.append(template)
|
||||||
|
|
||||||
if templates:
|
if templates:
|
||||||
for template in templates:
|
for template in templates:
|
||||||
if template.isready and template.ispublic and template.details != None and len(template.details.__dict__) > 0:
|
if template.isready and template.ispublic and template.deployasisdetails and len(template.deployasisdetails.__dict__) > 0:
|
||||||
result.append(template.__dict__)
|
result.append(template)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user