VMware: Early fail spawn if memory is not multiple of 4.
If instance memory is not multiple of 4, creating instance on ESXi fails with error "['GenericVmConfigFault'] VimFaultException: Memory (RAM) size is invalid.". However this is after instance is built and tried to launch on ESXi. Add check in prepare_for_spawn to trigger failure early and avoid further steps i.e. build as well as launch. Closes-Bug: #1966987 Change-Id: I7ed8ac986283cd455e54e3f18ab955f43b3248d0
This commit is contained in:
parent
a1f006d799
commit
08e8bdf271
@ -2711,6 +2711,7 @@ class ComputeManager(manager.Manager):
|
||||
with excutils.save_and_reraise_exception():
|
||||
self._build_resources_cleanup(instance, network_info)
|
||||
except (exception.UnexpectedTaskStateError,
|
||||
exception.InstanceUnacceptable,
|
||||
exception.OverQuota, exception.InvalidBDM) as e:
|
||||
self._build_resources_cleanup(instance, network_info)
|
||||
raise exception.BuildAbortException(instance_uuid=instance.uuid,
|
||||
|
@ -166,7 +166,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
"projectid:fake_project\n"
|
||||
"projectname:None\n"
|
||||
"flavor:name:m1.micro\n"
|
||||
"flavor:memory_mb:6\n"
|
||||
"flavor:memory_mb:8\n"
|
||||
"flavor:vcpus:28\n"
|
||||
"flavor:ephemeral_gb:8128\n"
|
||||
"flavor:root_gb:496\n"
|
||||
@ -1138,6 +1138,14 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
mock_attach_cdrom_to_vm.assert_called_once_with(
|
||||
vm_ref, self._instance, self._ds.ref, str(upload_iso_path))
|
||||
|
||||
def test_prepare_for_spawn_invalid_ram(self):
|
||||
instance = self._instance.obj_clone()
|
||||
flavor = objects.Flavor(vcpus=1, memory_mb=6, ephemeral_gb=1,
|
||||
swap=1024, extra_specs={})
|
||||
instance.flavor = flavor
|
||||
self.assertRaises(exception.InstanceUnacceptable,
|
||||
self._vmops.prepare_for_spawn, instance)
|
||||
|
||||
@mock.patch('nova.image.glance.API.get')
|
||||
@mock.patch.object(vmops.LOG, 'debug')
|
||||
@mock.patch.object(vmops.VMwareVMOps, '_fetch_image_if_missing')
|
||||
@ -2176,7 +2184,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
def _validate_flavor_extra_specs(self, flavor_extra_specs, expected):
|
||||
# Validate that the extra specs are parsed correctly
|
||||
flavor = objects.Flavor(name='my-flavor',
|
||||
memory_mb=6,
|
||||
memory_mb=8,
|
||||
vcpus=28,
|
||||
root_gb=496,
|
||||
ephemeral_gb=8128,
|
||||
@ -2227,7 +2235,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
flavor_extra_specs = {'quota:cpu_limit': 7,
|
||||
'quota:cpu_reservation': 6}
|
||||
flavor = objects.Flavor(name='my-flavor',
|
||||
memory_mb=6,
|
||||
memory_mb=8,
|
||||
vcpus=28,
|
||||
root_gb=496,
|
||||
ephemeral_gb=8128,
|
||||
@ -2280,7 +2288,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
'quota:cpu_reservation': 6,
|
||||
'hw_video:ram_max_mb': 100}
|
||||
flavor = objects.Flavor(name='my-flavor',
|
||||
memory_mb=6,
|
||||
memory_mb=8,
|
||||
vcpus=28,
|
||||
root_gb=496,
|
||||
ephemeral_gb=8128,
|
||||
@ -2692,7 +2700,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
|
||||
def test_get_storage_policy_none(self):
|
||||
flavor = objects.Flavor(name='m1.small',
|
||||
memory_mb=6,
|
||||
memory_mb=8,
|
||||
vcpus=28,
|
||||
root_gb=496,
|
||||
ephemeral_gb=8128,
|
||||
@ -2706,7 +2714,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
def test_get_storage_policy_extra_specs(self):
|
||||
extra_specs = {'vmware:storage_policy': 'flavor-policy'}
|
||||
flavor = objects.Flavor(name='m1.small',
|
||||
memory_mb=6,
|
||||
memory_mb=8,
|
||||
vcpus=28,
|
||||
root_gb=496,
|
||||
ephemeral_gb=8128,
|
||||
@ -2781,7 +2789,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
def test_get_instance_metadata(self):
|
||||
flavor = objects.Flavor(id=7,
|
||||
name='m1.small',
|
||||
memory_mb=6,
|
||||
memory_mb=8,
|
||||
vcpus=28,
|
||||
root_gb=496,
|
||||
ephemeral_gb=8128,
|
||||
@ -2796,7 +2804,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
"projectid:fake_project\n"
|
||||
"projectname:None\n"
|
||||
"flavor:name:m1.small\n"
|
||||
"flavor:memory_mb:6\n"
|
||||
"flavor:memory_mb:8\n"
|
||||
"flavor:vcpus:28\n"
|
||||
"flavor:ephemeral_gb:8128\n"
|
||||
"flavor:root_gb:496\n"
|
||||
@ -2913,7 +2921,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
||||
def test_get_cores_per_socket(self):
|
||||
extra_specs = {'hw:cpu_sockets': 7}
|
||||
flavor = objects.Flavor(name='m1.small',
|
||||
memory_mb=6,
|
||||
memory_mb=8,
|
||||
vcpus=28,
|
||||
root_gb=496,
|
||||
ephemeral_gb=8128,
|
||||
|
@ -519,6 +519,10 @@ class VMwareVCDriver(driver.ComputeDriver):
|
||||
# where cpu traits are added. In the vmware world, this is where we
|
||||
# would add nested providers representing tenant VDC and similar.
|
||||
|
||||
def prepare_for_spawn(self, instance):
|
||||
"""Perform pre-checks for spawn."""
|
||||
self._vmops.prepare_for_spawn(instance)
|
||||
|
||||
def spawn(self, context, instance, image_meta, injected_files,
|
||||
admin_password, allocations, network_info=None,
|
||||
block_device_info=None, power_on=True, accel_info=None):
|
||||
|
@ -729,6 +729,12 @@ class VMwareVMOps(object):
|
||||
if new_size is not None:
|
||||
vi.ii.file_size = new_size
|
||||
|
||||
def prepare_for_spawn(self, instance):
|
||||
if (int(instance.flavor.memory_mb) % 4 != 0):
|
||||
reason = _("Memory size is not multiple of 4")
|
||||
raise exception.InstanceUnacceptable(instance_id=instance.uuid,
|
||||
reason=reason)
|
||||
|
||||
def spawn(self, context, instance, image_meta, injected_files,
|
||||
admin_password, network_info, block_device_info=None):
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
For the VMware ESXi, VM memory should be multiple of 4. Otherwise creating
|
||||
instance on ESXi fails with error "VimFaultException: Memory (RAM) size is
|
||||
invalid.". Instances will now fail to spawn if flavor memory is not a
|
||||
multiple of 4.
|
Loading…
Reference in New Issue
Block a user