Merge "Add support for Windows Server 2016 RemoteFx features"
This commit is contained in:
commit
11825f0474
@ -74,6 +74,8 @@ REMOTEFX_MAX_RES_1280x1024 = "1280x1024"
|
||||
REMOTEFX_MAX_RES_1600x1200 = "1600x1200"
|
||||
REMOTEFX_MAX_RES_1920x1200 = "1920x1200"
|
||||
REMOTEFX_MAX_RES_2560x1600 = "2560x1600"
|
||||
REMOTEFX_MAX_RES_3840x2160 = "3840x2160"
|
||||
|
||||
|
||||
FLAVOR_REMOTE_FX_EXTRA_SPEC_KEY = "hyperv:remotefx"
|
||||
|
||||
|
@ -393,13 +393,7 @@ class VMOps(object):
|
||||
remote_fx_config = flavor_extra_specs.get(
|
||||
constants.FLAVOR_REMOTE_FX_EXTRA_SPEC_KEY)
|
||||
if remote_fx_config:
|
||||
if vm_gen == constants.VM_GEN_2:
|
||||
reason = _("RemoteFX is not supported on generation 2 virtual "
|
||||
"machines.")
|
||||
raise exception.InstanceUnacceptable(instance_id=instance.uuid,
|
||||
reason=reason)
|
||||
else:
|
||||
self._configure_remotefx(instance, remote_fx_config)
|
||||
self._configure_remotefx(instance, vm_gen, remote_fx_config)
|
||||
|
||||
self._vmutils.create_scsi_controller(instance_name)
|
||||
|
||||
@ -570,7 +564,7 @@ class VMOps(object):
|
||||
|
||||
return memory_per_numa_node, cpus_per_numa_node
|
||||
|
||||
def _configure_remotefx(self, instance, config):
|
||||
def _configure_remotefx(self, instance, vm_gen, config):
|
||||
if not CONF.hyperv.enable_remotefx:
|
||||
reason = _("enable_remotefx configuration option needs to be set "
|
||||
"to True in order to use RemoteFX")
|
||||
@ -584,16 +578,25 @@ class VMOps(object):
|
||||
raise exception.InstanceUnacceptable(instance_id=instance.uuid,
|
||||
reason=reason)
|
||||
|
||||
if not self._vmutils.vm_gen_supports_remotefx(vm_gen):
|
||||
reason = _("RemoteFX is not supported on generation %s virtual "
|
||||
"machines on this version of Windows.") % vm_gen
|
||||
raise exception.InstanceUnacceptable(instance_id=instance.uuid,
|
||||
reason=reason)
|
||||
|
||||
instance_name = instance.name
|
||||
LOG.debug('Configuring RemoteFX for instance: %s', instance_name)
|
||||
|
||||
(remotefx_max_resolution, remotefx_monitor_count) = config.split(',')
|
||||
remotefx_monitor_count = int(remotefx_monitor_count)
|
||||
remotefx_args = config.split(',')
|
||||
remotefx_max_resolution = remotefx_args[0]
|
||||
remotefx_monitor_count = int(remotefx_args[1])
|
||||
remotefx_vram = remotefx_args[2] if len(remotefx_args) == 3 else None
|
||||
vram_bytes = int(remotefx_vram) * units.Mi if remotefx_vram else None
|
||||
|
||||
self._vmutils.enable_remotefx_video_adapter(
|
||||
instance_name,
|
||||
remotefx_monitor_count,
|
||||
remotefx_max_resolution)
|
||||
remotefx_max_resolution,
|
||||
vram_bytes)
|
||||
|
||||
def attach_config_drive(self, instance, configdrive_path, vm_gen):
|
||||
configdrive_ext = configdrive_path[(configdrive_path.rfind('.') + 1):]
|
||||
|
@ -553,6 +553,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
||||
if remotefx is True:
|
||||
mock_configure_remotefx.assert_called_once_with(
|
||||
mock_instance,
|
||||
vm_gen,
|
||||
flavor.extra_specs['hyperv:remotefx'])
|
||||
|
||||
self._vmops._vmutils.create_vm.assert_called_once_with(
|
||||
@ -1440,34 +1441,45 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
||||
def test_get_instance_vnuma_config_no_topology(self):
|
||||
self._check_get_instance_vnuma_config()
|
||||
|
||||
def _test_configure_remotefx(self, fail=False):
|
||||
self.flags(enable_remotefx=True, group='hyperv')
|
||||
def _test_configure_remotefx(self, fail=True, enable_remotefx=True):
|
||||
self.flags(enable_remotefx=enable_remotefx, group='hyperv')
|
||||
mock_instance = fake_instance.fake_instance_obj(self.context)
|
||||
|
||||
fake_resolution = "1920x1200"
|
||||
fake_monitor_count = 3
|
||||
fake_config = "%s,%s" % (fake_resolution, fake_monitor_count)
|
||||
fake_vram_mb = 64
|
||||
fake_config = "%s,%s,%s" % (
|
||||
fake_resolution, fake_monitor_count, fake_vram_mb)
|
||||
|
||||
self._vmops._vmutils.enable_remotefx_video_adapter = mock.MagicMock()
|
||||
enable_remotefx = self._vmops._vmutils.enable_remotefx_video_adapter
|
||||
self._vmops._hostutils.check_server_feature = mock.MagicMock()
|
||||
|
||||
if fail:
|
||||
self._vmops._hostutils.check_server_feature.return_value = False
|
||||
self.assertRaises(exception.InstanceUnacceptable,
|
||||
self._vmops._configure_remotefx,
|
||||
mock_instance, fake_config)
|
||||
mock_instance, mock.sentinel.vm_gen, fake_config)
|
||||
else:
|
||||
self._vmops._configure_remotefx(mock_instance, fake_config)
|
||||
self._vmops._configure_remotefx(
|
||||
mock_instance, mock.sentinel.vm_gen, fake_config)
|
||||
enable_remotefx.assert_called_once_with(mock_instance.name,
|
||||
fake_monitor_count,
|
||||
fake_resolution)
|
||||
fake_resolution,
|
||||
fake_vram_mb * units.Mi)
|
||||
|
||||
def test_configure_remotefx_exception(self):
|
||||
self._test_configure_remotefx(fail=True)
|
||||
def test_configure_remotefx_disabled(self):
|
||||
self._test_configure_remotefx(enable_remotefx=False)
|
||||
|
||||
def test_configure_remotefx_no_server_feature(self):
|
||||
self._vmops._hostutils.check_server_feature.return_value = False
|
||||
self._test_configure_remotefx()
|
||||
self._vmops._hostutils.check_server_feature.assert_called_once_with(
|
||||
self._vmops._hostutils.FEATURE_RDS_VIRTUALIZATION)
|
||||
|
||||
def test_configure_remotefx_unsupported_vm_gen(self):
|
||||
self._vmops._vmutils.vm_gen_supports_remotefx.return_value = False
|
||||
self._test_configure_remotefx()
|
||||
|
||||
def test_configure_remotefx(self):
|
||||
self._test_configure_remotefx()
|
||||
self._test_configure_remotefx(fail=False)
|
||||
|
||||
@mock.patch.object(vmops.VMOps, '_get_vm_state')
|
||||
def _test_check_hotplug_is_available(self, mock_get_vm_state, vm_gen,
|
||||
|
Loading…
Reference in New Issue
Block a user