Fixes Hyper-V driver WMI issue on 2008 R2
Trying to assign properties on default Hyper-V resource setting data WMI objects results in an exceptions before Hyper-V 2012. Cloning the objects before assigning them solves the issue. A similar approach was previous already implemented and has been incorrectly removed during a refactoring. Co-Authored-By: Robert Tingirica <rtingirica@cloudbasesolutions.com> Change-Id: If119154f8b4756be9f98c8acd376003c52eff44f Closes-Bug: #1356884
This commit is contained in:
parent
d9d04933a4
commit
b208f249d9
|
@ -666,3 +666,37 @@ class VMUtilsTestCase(test.NoDBTestCase):
|
|||
self._vmutils._conn.Msvm_VirtualSystemSettingData.assert_called_with(
|
||||
['ElementName'],
|
||||
SettingType=self._vmutils._VIRTUAL_SYSTEM_CURRENT_SETTINGS)
|
||||
|
||||
@mock.patch.object(vmutils.VMUtils, "_clone_wmi_obj")
|
||||
def _test_check_clone_wmi_obj(self, mock_clone_wmi_obj, clone_objects):
|
||||
mock_obj = mock.MagicMock()
|
||||
self._vmutils._clone_wmi_objs = clone_objects
|
||||
|
||||
response = self._vmutils._check_clone_wmi_obj(class_name="fakeClass",
|
||||
obj=mock_obj)
|
||||
if not clone_objects:
|
||||
self.assertEqual(mock_obj, response)
|
||||
else:
|
||||
mock_clone_wmi_obj.assert_called_once_with("fakeClass", mock_obj)
|
||||
self.assertEqual(mock_clone_wmi_obj.return_value, response)
|
||||
|
||||
def test_check_clone_wmi_obj_true(self):
|
||||
self._test_check_clone_wmi_obj(clone_objects=True)
|
||||
|
||||
def test_check_clone_wmi_obj_false(self):
|
||||
self._test_check_clone_wmi_obj(clone_objects=False)
|
||||
|
||||
def test_clone_wmi_obj(self):
|
||||
mock_obj = mock.MagicMock()
|
||||
mock_value = mock.MagicMock()
|
||||
mock_value.Value = mock.sentinel.fake_value
|
||||
mock_obj._properties = [mock.sentinel.property]
|
||||
mock_obj.Properties_.Item.return_value = mock_value
|
||||
|
||||
response = self._vmutils._clone_wmi_obj(
|
||||
class_name="FakeClass", obj=mock_obj)
|
||||
|
||||
compare = self._vmutils._conn.FakeClass.new()
|
||||
self.assertEqual(mock.sentinel.fake_value,
|
||||
compare.Properties_.Item().Value)
|
||||
self.assertEqual(compare, response)
|
||||
|
|
|
@ -31,6 +31,7 @@ from nova import exception
|
|||
from nova.i18n import _, _LW
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.virt.hyperv import constants
|
||||
from nova.virt.hyperv import hostutils
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -99,6 +100,13 @@ class VMUtils(object):
|
|||
self._init_hyperv_wmi_conn(host)
|
||||
self._conn_cimv2 = wmi.WMI(moniker='//%s/root/cimv2' % host)
|
||||
|
||||
# On version of Hyper-V prior to 2012 trying to directly set properties
|
||||
# in default setting data WMI objects results in an exception
|
||||
self._clone_wmi_objs = False
|
||||
if sys.platform == 'win32':
|
||||
hostutls = hostutils.HostUtils()
|
||||
self._clone_wmi_objs = not hostutls.check_min_windows_version(6, 2)
|
||||
|
||||
def _init_hyperv_wmi_conn(self, host):
|
||||
self._conn = wmi.WMI(moniker='//%s/root/virtualization' % host)
|
||||
|
||||
|
@ -320,19 +328,36 @@ class VMUtils(object):
|
|||
return volumes
|
||||
|
||||
def _get_new_setting_data(self, class_name):
|
||||
return self._conn.query("SELECT * FROM %s WHERE InstanceID "
|
||||
obj = self._conn.query("SELECT * FROM %s WHERE InstanceID "
|
||||
"LIKE '%%\\Default'" % class_name)[0]
|
||||
return self._check_clone_wmi_obj(class_name, obj)
|
||||
|
||||
def _get_new_resource_setting_data(self, resource_sub_type,
|
||||
class_name=None):
|
||||
if class_name is None:
|
||||
class_name = self._RESOURCE_ALLOC_SETTING_DATA_CLASS
|
||||
return self._conn.query("SELECT * FROM %(class_name)s "
|
||||
obj = self._conn.query("SELECT * FROM %(class_name)s "
|
||||
"WHERE ResourceSubType = "
|
||||
"'%(res_sub_type)s' AND "
|
||||
"InstanceID LIKE '%%\\Default'" %
|
||||
{"class_name": class_name,
|
||||
"res_sub_type": resource_sub_type})[0]
|
||||
return self._check_clone_wmi_obj(class_name, obj)
|
||||
|
||||
def _check_clone_wmi_obj(self, class_name, obj):
|
||||
if self._clone_wmi_objs:
|
||||
return self._clone_wmi_obj(class_name, obj)
|
||||
else:
|
||||
return obj
|
||||
|
||||
def _clone_wmi_obj(self, class_name, obj):
|
||||
wmi_class = getattr(self._conn, class_name)
|
||||
new_obj = wmi_class.new()
|
||||
# Copy the properties from the original.
|
||||
for prop in obj._properties:
|
||||
value = obj.Properties_.Item(prop).Value
|
||||
new_obj.Properties_.Item(prop).Value = value
|
||||
return new_obj
|
||||
|
||||
def attach_ide_drive(self, vm_name, path, ctrller_addr, drive_addr,
|
||||
drive_type=constants.IDE_DISK):
|
||||
|
|
Loading…
Reference in New Issue