Fixes Hyper-V agent force_hyperv_utils_v1 flag issue

WMI root\virtualization namespace v1 (in Hyper-V) has been removed
from Windows Server / Hyper-V Server 2012 R2.

Hyper-V compute agent now creates instances which uses
root\virtualization\v2 namespace if the agent's OS is
Windows Server / Hyper-V Server 2012 R2 or newer.

Closes-Bug: #1344036

Change-Id: I874ade4456b92a63959a765c7851bcd001befa32
This commit is contained in:
Dorin Paslaru 2014-07-18 15:43:16 +03:00
parent 7091b58790
commit 52de9395e5
5 changed files with 101 additions and 14 deletions

View File

@ -126,6 +126,8 @@ class HyperVAPIBaseTestCase(test.NoDBTestCase):
fake_get_remote_image_service)
def fake_check_min_windows_version(fake_self, major, minor):
if [major, minor] >= [6, 3]:
return False
return self._check_min_windows_version_satisfied
self.stubs.Set(hostutils.HostUtils, 'check_min_windows_version',
fake_check_min_windows_version)

View File

@ -26,8 +26,14 @@ class MigrationOpsTestCase(test.NoDBTestCase):
def setUp(self):
super(MigrationOpsTestCase, self).setUp()
self.context = 'fake-context'
self.flags(force_hyperv_utils_v1=True, group='hyperv')
self.flags(force_volumeutils_v1=True, group='hyperv')
# utilsfactory will check the host OS version via get_hostutils,
# in order to return the proper Utils Class, so it must be mocked.
patched_func = mock.patch.object(migrationops.utilsfactory,
"get_hostutils")
patched_func.start()
self.addCleanup(patched_func.stop)
self._migrationops = migrationops.MigrationOps()
def test_check_and_attach_config_drive_unknown_path(self):

View File

@ -0,0 +1,61 @@
# Copyright 2014 Cloudbase Solutions SRL
# All Rights Reserved.
#
# Licensed 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.
"""
Unit tests for the Hyper-V utils factory.
"""
import mock
from oslo.config import cfg
from nova import test
from nova.virt.hyperv import hostutils
from nova.virt.hyperv import utilsfactory
from nova.virt.hyperv import vmutils
from nova.virt.hyperv import vmutilsv2
CONF = cfg.CONF
class TestHyperVUtilsFactory(test.NoDBTestCase):
def setUp(self):
super(TestHyperVUtilsFactory, self).setUp()
def test_get_vmutils_force_v1_and_min_version(self):
self._test_returned_class(None, True, True)
def test_get_vmutils_v2(self):
self._test_returned_class(vmutilsv2.VMUtilsV2, False, True)
def test_get_vmutils_v2_r2(self):
self._test_returned_class(vmutils.VMUtils, False, False)
def test_get_vmutils_force_v1_and_not_min_version(self):
self._test_returned_class(vmutils.VMUtils, True, False)
def _test_returned_class(self, expected_class, force_v1, os_supports_v2):
CONF.set_override('force_hyperv_utils_v1', force_v1, 'hyperv')
with mock.patch.object(
hostutils.HostUtils,
'check_min_windows_version') as mock_check_min_windows_version:
mock_check_min_windows_version.return_value = os_supports_v2
if os_supports_v2 and force_v1:
self.assertRaises(vmutils.HyperVException,
utilsfactory.get_vmutils)
else:
actual_class = type(utilsfactory.get_vmutils())
self.assertEqual(actual_class, expected_class)

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
from nova import exception
from nova import test
from nova.tests import fake_instance
@ -27,8 +29,14 @@ class VMOpsTestCase(test.NoDBTestCase):
def setUp(self):
super(VMOpsTestCase, self).setUp()
self.context = 'fake-context'
self.flags(force_hyperv_utils_v1=True, group='hyperv')
self.flags(force_volumeutils_v1=True, group='hyperv')
# utilsfactory will check the host OS version via get_hostutils,
# in order to return the proper Utils Class, so it must be mocked.
patched_func = mock.patch.object(vmops.utilsfactory,
"get_hostutils")
patched_func.start()
self.addCleanup(patched_func.stop)
self._vmops = vmops.VMOps()
def test_attach_config_drive(self):

View File

@ -15,6 +15,7 @@
from oslo.config import cfg
from nova.i18n import _
from nova.openstack.common import log as logging
from nova.virt.hyperv import hostutils
from nova.virt.hyperv import livemigrationutils
@ -57,20 +58,30 @@ def _get_class(v1_class, v2_class, force_v1_flag):
return cls
def _get_virt_utils_class(v1_class, v2_class):
# The "root/virtualization" WMI namespace is no longer supported on
# Windows Server / Hyper-V Server 2012 R2 / Windows 8.1
# (kernel version 6.3) or above.
if (CONF.hyperv.force_hyperv_utils_v1 and
get_hostutils().check_min_windows_version(6, 3)):
raise vmutils.HyperVException(
_('The "force_hyperv_utils_v1" option cannot be set to "True" '
'on Windows Server / Hyper-V Server 2012 R2 or above as the WMI '
'"root/virtualization" namespace is no longer supported.'))
return _get_class(v1_class, v2_class, CONF.hyperv.force_hyperv_utils_v1)
def get_vmutils(host='.'):
return _get_class(vmutils.VMUtils, vmutilsv2.VMUtilsV2,
CONF.hyperv.force_hyperv_utils_v1)(host)
return _get_virt_utils_class(vmutils.VMUtils, vmutilsv2.VMUtilsV2)(host)
def get_vhdutils():
return _get_class(vhdutils.VHDUtils, vhdutilsv2.VHDUtilsV2,
CONF.hyperv.force_hyperv_utils_v1)()
return _get_virt_utils_class(vhdutils.VHDUtils, vhdutilsv2.VHDUtilsV2)()
def get_networkutils():
return _get_class(networkutils.NetworkUtils,
networkutilsv2.NetworkUtilsV2,
CONF.hyperv.force_hyperv_utils_v1)()
return _get_virt_utils_class(networkutils.NetworkUtils,
networkutilsv2.NetworkUtilsV2)()
def get_hostutils():
@ -91,6 +102,5 @@ def get_livemigrationutils():
def get_rdpconsoleutils():
return _get_class(rdpconsoleutils.RDPConsoleUtils,
rdpconsoleutilsv2.RDPConsoleUtilsV2,
CONF.hyperv.force_hyperv_utils_v1)()
return _get_virt_utils_class(rdpconsoleutils.RDPConsoleUtils,
rdpconsoleutilsv2.RDPConsoleUtilsV2)()