Merge "refactors vmops' create_instance"

This commit is contained in:
Jenkins 2017-02-07 12:31:04 +00:00 committed by Gerrit Code Review
commit da73f59389
2 changed files with 126 additions and 107 deletions

View File

@ -363,28 +363,7 @@ class VMOps(object):
memory_per_numa_node, cpus_per_numa_node = (
self._get_instance_vnuma_config(instance, image_meta))
if memory_per_numa_node:
LOG.debug("Instance requires vNUMA topology. Host's NUMA spanning "
"has to be disabled in order for the instance to "
"benefit from it.", instance=instance)
if CONF.hyperv.dynamic_memory_ratio > 1.0:
LOG.warning(_LW(
"Instance vNUMA topology requested, but dynamic memory "
"ratio is higher than 1.0 in nova.conf. Ignoring dynamic "
"memory ratio option."), instance=instance)
dynamic_memory_ratio = 1.0
vnuma_enabled = True
else:
dynamic_memory_ratio = CONF.hyperv.dynamic_memory_ratio
vnuma_enabled = False
if instance.pci_requests.requests:
# NOTE(claudiub): if the instance requires PCI devices, its
# host shutdown action MUST be shutdown.
host_shutdown_action = os_win_const.HOST_SHUTDOWN_ACTION_SHUTDOWN
else:
host_shutdown_action = None
vnuma_enabled = bool(memory_per_numa_node)
self._vmutils.create_vm(instance_name,
vnuma_enabled,
@ -392,17 +371,6 @@ class VMOps(object):
instance_path,
[instance.uuid])
self._vmutils.update_vm(instance_name,
instance.flavor.memory_mb,
memory_per_numa_node,
instance.flavor.vcpus,
cpus_per_numa_node,
CONF.hyperv.limit_cpu_features,
dynamic_memory_ratio,
host_shutdown_action=host_shutdown_action)
self._configure_remotefx(instance, vm_gen)
self._vmutils.create_scsi_controller(instance_name)
self._attach_root_device(instance_name, root_device)
self._attach_ephemerals(instance_name, block_device_info['ephemerals'])
@ -421,8 +389,6 @@ class VMOps(object):
if CONF.hyperv.enable_instance_metrics_collection:
self._metricsutils.enable_vm_metrics_collection(instance_name)
self._set_instance_disk_qos_specs(instance)
if secure_boot_enabled:
certificate_required = self._requires_certificate(image_meta)
self._vmutils.enable_secure_boot(
@ -431,6 +397,37 @@ class VMOps(object):
self._configure_secure_vm(context, instance, image_meta,
secure_boot_enabled)
self.update_vm_resources(instance, vm_gen, image_meta)
def update_vm_resources(self, instance, vm_gen, image_meta,
is_planned_vm=False):
"""Updates the VM's reconfigurable resources."""
memory_per_numa_node, cpus_per_numa_node = (
self._get_instance_vnuma_config(instance, image_meta))
vnuma_enabled = bool(memory_per_numa_node)
dynamic_memory_ratio = self._get_instance_dynamic_memory_ratio(
instance, vnuma_enabled)
if instance.pci_requests.requests:
# NOTE(claudiub): if the instance requires PCI devices, its
# host shutdown action MUST be shutdown.
host_shutdown_action = os_win_const.HOST_SHUTDOWN_ACTION_SHUTDOWN
else:
host_shutdown_action = None
self._vmutils.update_vm(instance.name,
instance.flavor.memory_mb,
memory_per_numa_node,
instance.flavor.vcpus,
cpus_per_numa_node,
CONF.hyperv.limit_cpu_features,
dynamic_memory_ratio,
host_shutdown_action=host_shutdown_action,
is_planned_vm=is_planned_vm)
self._configure_remotefx(instance, vm_gen)
self._set_instance_disk_qos_specs(instance)
self._attach_pci_devices(instance)
def _attach_pci_devices(self, instance):
@ -483,6 +480,20 @@ class VMOps(object):
return memory_per_numa_node, cpus_per_numa_node
def _get_instance_dynamic_memory_ratio(self, instance, vnuma_enabled):
dynamic_memory_ratio = CONF.hyperv.dynamic_memory_ratio
if vnuma_enabled:
LOG.debug("Instance requires vNUMA topology. Host's NUMA spanning "
"has to be disabled in order for the instance to "
"benefit from it.", instance=instance)
if CONF.hyperv.dynamic_memory_ratio > 1.0:
LOG.warning(_LW(
"Instance vNUMA topology requested, but dynamic memory "
"ratio is higher than 1.0 in nova.conf. Ignoring dynamic "
"memory ratio option."), instance=instance)
dynamic_memory_ratio = 1.0
return dynamic_memory_ratio
def _configure_remotefx(self, instance, vm_gen):
extra_specs = instance.flavor.extra_specs
remotefx_max_resolution = extra_specs.get(

View File

@ -14,14 +14,13 @@
import os
import ddt
from eventlet import timeout as etimeout
import mock
from nova.compute import vm_states
from nova import exception
from nova import objects
from nova.objects import fields
from nova.objects import flavor as flavor_obj
from nova.tests.unit.objects import test_flavor
from nova.tests.unit.objects import test_virtual_interface
from nova.virt import hardware
from os_win import constants as os_win_const
@ -42,6 +41,7 @@ from hyperv.tests.unit import test_base
CONF = cfg.CONF
@ddt.ddt
class VMOpsTestCase(test_base.HyperVBaseTestCase):
"""Unit tests for the Hyper-V VMOps class."""
@ -566,37 +566,27 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
self.assertEqual([], events)
mock_is_neutron.assert_called_once_with()
@mock.patch.object(vmops.VMOps, '_attach_pci_devices')
@mock.patch.object(vmops.VMOps, 'update_vm_resources')
@mock.patch.object(vmops.VMOps, '_configure_secure_vm')
@mock.patch.object(vmops.VMOps, '_requires_secure_boot')
@mock.patch.object(vmops.VMOps, '_requires_certificate')
@mock.patch.object(vmops.VMOps, '_get_instance_vnuma_config')
@mock.patch.object(vmops.volumeops.VolumeOps, 'attach_volumes')
@mock.patch.object(vmops.VMOps, '_set_instance_disk_qos_specs')
@mock.patch.object(vmops.VMOps, '_attach_root_device')
@mock.patch.object(vmops.VMOps, '_get_image_serial_port_settings')
@mock.patch.object(vmops.VMOps, '_create_vm_com_port_pipes')
@mock.patch.object(vmops.VMOps, '_attach_ephemerals')
@mock.patch.object(vmops.VMOps, '_configure_remotefx')
def _test_create_instance(self, mock_configure_remotefx,
mock_attach_ephemerals,
mock_create_pipes,
mock_get_port_settings,
mock_attach_root_device,
mock_set_qos_specs,
mock_attach_volumes,
mock_get_vnuma_config,
mock_requires_certificate,
mock_requires_secure_boot,
mock_configure_secure_vm,
mock_attach_pci_devices,
enable_instance_metrics,
vm_gen=constants.VM_GEN_1,
vnuma_enabled=False,
pci_requests=None,
requires_sec_boot=True):
self.flags(dynamic_memory_ratio=2.0, group='hyperv')
self.flags(enable_instance_metrics_collection=enable_instance_metrics,
def test_create_instance(self, mock_attach_ephemerals,
mock_create_pipes,
mock_get_port_settings,
mock_attach_root_device,
mock_attach_volumes,
mock_get_vnuma_config,
mock_requires_certificate,
mock_requires_secure_boot,
mock_configure_secure_vm,
mock_update_vm_resources):
self.flags(enable_instance_metrics_collection=True,
group='hyperv')
root_device_info = mock.sentinel.ROOT_DEV_INFO
block_device_info = {'root_disk': root_device_info, 'ephemerals': [],
@ -605,46 +595,23 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
'address': mock.sentinel.ADDRESS}
mock_instance = fake_instance.fake_instance_obj(self.context)
instance_path = os.path.join(CONF.instances_path, mock_instance.name)
mock_requires_secure_boot.return_value = True
flavor = flavor_obj.Flavor(**test_flavor.fake_flavor)
mock_instance.flavor = flavor
instance_pci_requests = objects.InstancePCIRequests(
requests=pci_requests or [], instance_uuid=mock_instance.uuid)
mock_instance.pci_requests = instance_pci_requests
host_shutdown_action = (os_win_const.HOST_SHUTDOWN_ACTION_SHUTDOWN
if pci_requests else None)
if vnuma_enabled:
mock_get_vnuma_config.return_value = (
mock.sentinel.mem_per_numa, mock.sentinel.cpus_per_numa)
cpus_per_numa = mock.sentinel.cpus_per_numa
mem_per_numa = mock.sentinel.mem_per_numa
dynamic_memory_ratio = 1.0
else:
mock_get_vnuma_config.return_value = (None, None)
mem_per_numa, cpus_per_numa = (None, None)
dynamic_memory_ratio = CONF.hyperv.dynamic_memory_ratio
mock_get_vnuma_config.return_value = (mock.sentinel.mem_per_numa_node,
mock.sentinel.vnuma_cpus)
self._vmops.create_instance(context=self.context,
instance=mock_instance,
network_info=[fake_network_info],
block_device_info=block_device_info,
vm_gen=vm_gen,
vm_gen=mock.sentinel.vm_gen,
image_meta=mock.sentinel.image_meta)
mock_get_vnuma_config.assert_called_once_with(mock_instance,
mock.sentinel.image_meta)
self._vmops._vmutils.create_vm.assert_called_once_with(
mock_instance.name, vnuma_enabled, vm_gen,
mock_instance.name, True, mock.sentinel.vm_gen,
instance_path, [mock_instance.uuid])
self._vmops._vmutils.update_vm.assert_called_once_with(
mock_instance.name, mock_instance.flavor.memory_mb, mem_per_numa,
mock_instance.flavor.vcpus, cpus_per_numa,
CONF.hyperv.limit_cpu_features, dynamic_memory_ratio,
host_shutdown_action=host_shutdown_action)
mock_configure_remotefx.assert_called_once_with(mock_instance, vm_gen)
mock_create_scsi_ctrl = self._vmops._vmutils.create_scsi_controller
mock_create_scsi_ctrl.assert_called_once_with(mock_instance.name)
@ -662,11 +629,9 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
self._vmops._vmutils.create_nic.assert_called_once_with(
mock_instance.name, mock.sentinel.ID, mock.sentinel.ADDRESS)
mock_enable = self._vmops._metricsutils.enable_vm_metrics_collection
if enable_instance_metrics:
mock_enable.assert_called_once_with(mock_instance.name)
mock_set_qos_specs.assert_called_once_with(mock_instance)
mock_enable.assert_called_once_with(mock_instance.name)
mock_requires_secure_boot.assert_called_once_with(
mock_instance, mock.sentinel.image_meta, vm_gen)
mock_instance, mock.sentinel.image_meta, mock.sentinel.vm_gen)
mock_requires_certificate.assert_called_once_with(
mock.sentinel.image_meta)
enable_secure_boot = self._vmops._vmutils.enable_secure_boot
@ -674,30 +639,61 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
mock_instance.name,
msft_ca_required=mock_requires_certificate.return_value)
mock_configure_secure_vm.assert_called_once_with(self.context,
mock_instance, mock.sentinel.image_meta, requires_sec_boot)
mock_instance, mock.sentinel.image_meta,
mock_requires_secure_boot.return_value)
mock_update_vm_resources.assert_called_once_with(
mock_instance, mock.sentinel.vm_gen, mock.sentinel.image_meta)
@mock.patch.object(vmops.VMOps, '_attach_pci_devices')
@mock.patch.object(vmops.VMOps, '_set_instance_disk_qos_specs')
@mock.patch.object(vmops.VMOps, '_configure_remotefx')
@mock.patch.object(vmops.VMOps, '_get_instance_dynamic_memory_ratio')
@mock.patch.object(vmops.VMOps, '_get_instance_vnuma_config')
def _check_update_vm_resources(self, mock_get_vnuma_config,
mock_get_dynamic_memory_ratio,
mock_configure_remotefx,
mock_set_qos_specs,
mock_attach_pci_devices,
pci_requests=None):
mock_get_vnuma_config.return_value = (mock.sentinel.mem_per_numa_node,
mock.sentinel.vnuma_cpus)
dynamic_memory_ratio = mock_get_dynamic_memory_ratio.return_value
mock_instance = fake_instance.fake_instance_obj(self.context)
instance_pci_requests = objects.InstancePCIRequests(
requests=pci_requests or [], instance_uuid=mock_instance.uuid)
mock_instance.pci_requests = instance_pci_requests
host_shutdown_action = (os_win_const.HOST_SHUTDOWN_ACTION_SHUTDOWN
if pci_requests else None)
self._vmops.update_vm_resources(mock_instance, mock.sentinel.vm_gen,
mock.sentinel.image_meta,
mock.sentinel.is_planned_vm)
mock_get_vnuma_config.assert_called_once_with(mock_instance,
mock.sentinel.image_meta)
mock_get_dynamic_memory_ratio.assert_called_once_with(
mock_instance, True)
self._vmops._vmutils.update_vm.assert_called_once_with(
mock_instance.name, mock_instance.flavor.memory_mb,
mock.sentinel.mem_per_numa_node, mock_instance.flavor.vcpus,
mock.sentinel.vnuma_cpus, CONF.hyperv.limit_cpu_features,
dynamic_memory_ratio, host_shutdown_action=host_shutdown_action,
is_planned_vm=mock.sentinel.is_planned_vm)
mock_configure_remotefx.assert_called_once_with(mock_instance,
mock.sentinel.vm_gen)
mock_set_qos_specs.assert_called_once_with(mock_instance)
mock_attach_pci_devices.assert_called_once_with(mock_instance)
def test_create_instance(self):
self._test_create_instance(enable_instance_metrics=True)
def test_update_vm_resources(self):
self._check_update_vm_resources()
def test_create_instance_enable_instance_metrics_false(self):
self._test_create_instance(enable_instance_metrics=False)
def test_create_instance_gen2(self):
self._test_create_instance(enable_instance_metrics=False,
vm_gen=constants.VM_GEN_2)
def test_create_instance_vnuma_enabled(self):
self._test_create_instance(enable_instance_metrics=False,
vnuma_enabled=True)
def test_create_instance_pci_requested(self):
def test_update_vm_resources_pci_requested(self):
vendor_id = 'fake_vendor_id'
product_id = 'fake_product_id'
spec = {'vendor_id': vendor_id, 'product_id': product_id}
request = objects.InstancePCIRequest(count=1, spec=[spec])
self._test_create_instance(enable_instance_metrics=False,
pci_requests=[request])
self._check_update_vm_resources(pci_requests=[request])
def test_attach_pci_devices(self):
mock_instance = fake_instance.fake_instance_obj(self.context)
@ -765,6 +761,18 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
def test_get_instance_vnuma_config_no_topology(self):
self._check_get_instance_vnuma_config()
@ddt.data(True, False)
def test_get_instance_dynamic_memory_ratio(self, vnuma_enabled):
expected_dyn_memory_ratio = 2.0
self.flags(dynamic_memory_ratio=expected_dyn_memory_ratio,
group='hyperv')
if vnuma_enabled:
expected_dyn_memory_ratio = 1.0
response = self._vmops._get_instance_dynamic_memory_ratio(
mock.sentinel.instance, vnuma_enabled)
self.assertEqual(expected_dyn_memory_ratio, response)
@mock.patch.object(vmops.volumeops.VolumeOps, 'attach_volume')
def test_attach_root_device_volume(self, mock_attach_volume):
mock_instance = fake_instance.fake_instance_obj(self.context)