Creates baseutils module

Creates BaseUtils class, which contains the _get_wmi_obj and
_get_wmi_conn methods, commonly used in most of the utils
classes.

Caches the WMI connections, as they do not have to be unique.

Sets the WMI _conn object, the Msvm_VirtualSystemManagementService
as object attributes, as they are constantly used and there is no
need to instantiate them every time.

Partial-Bug: #1505196

Change-Id: Ieee7b9e587424f2a95aee85389adfaabf4032779
This commit is contained in:
Claudiu Belu 2016-01-15 15:52:43 +02:00
parent d39e537ae6
commit accb5214e5
19 changed files with 240 additions and 211 deletions

View File

@ -37,11 +37,12 @@ class LiveMigrationUtilsTestCase(test_base.OsWinBaseTestCase):
def setUp(self):
super(LiveMigrationUtilsTestCase, self).setUp()
self.liveutils = livemigrationutils.LiveMigrationUtils()
self._conn = mock.MagicMock()
self.liveutils._conn = self._conn
self.liveutils._vmutils = mock.MagicMock()
self.liveutils._iscsi_initiator = mock.MagicMock()
self.liveutils._jobutils = mock.Mock()
self._conn = mock.MagicMock()
self.liveutils._get_conn_v2 = mock.MagicMock(return_value=self._conn)
self.liveutils._conn_v2 = self._conn

View File

@ -74,14 +74,6 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase):
self._vmutils._metricsutils = mock.MagicMock()
self._vmutils._pathutils = mock.MagicMock()
def test_vs_man_svc(self):
expected = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
self.assertEqual(expected, self._vmutils._vs_man_svc)
def test_vs_man_svc_cached(self):
self._vmutils._vs_man_svc_attr = mock.sentinel.fake_svc
self.assertEqual(mock.sentinel.fake_svc, self._vmutils._vs_man_svc)
def test_get_vm_summary_info(self):
self._lookup_vm()
@ -453,14 +445,14 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase):
mock_get_new_rsd.return_value, mock_vm)
@mock.patch.object(vmutils.VMUtils, '_get_new_resource_setting_data')
@mock.patch.object(vmutils, 'wmi', create=True)
def _test_attach_volume_to_controller(self, mock_wmi, mock_get_new_rsd,
disk_serial=None):
@mock.patch.object(vmutils.VMUtils, '_get_wmi_obj')
def _test_attach_volume_to_controller(self, mock_get_wmi_obj,
mock_get_new_rsd, disk_serial=None):
mock_vm = self._lookup_vm()
mock_diskdrive = mock.MagicMock()
jobutils = self._vmutils._jobutils
jobutils.add_virt_resource.return_value = [mock_diskdrive]
mock_wmi.WMI.return_value = mock_diskdrive
mock_get_wmi_obj.return_value = mock_diskdrive
self._vmutils.attach_volume_to_controller(
self._FAKE_VM_NAME, self._FAKE_CTRL_PATH, self._FAKE_CTRL_ADDR,
@ -542,9 +534,9 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase):
result = self._vmutils.get_vm_physical_disk_mapping(self._FAKE_VM_NAME)
self.assertEqual(expected_mapping, result)
@mock.patch.object(vmutils, 'wmi', create=True)
def test_set_disk_host_res(self, mock_wmi):
mock_diskdrive = mock_wmi.WMI.return_value
@mock.patch.object(vmutils.VMUtils, '_get_wmi_obj')
def test_set_disk_host_res(self, mock_get_wmi_obj):
mock_diskdrive = mock_get_wmi_obj.return_value
self._vmutils.set_disk_host_res(self._FAKE_RES_PATH,
self._FAKE_MOUNTED_DISK_PATH)
@ -552,7 +544,7 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase):
self._vmutils._jobutils.modify_virt_resource.assert_called_once_with(
mock_diskdrive)
mock_wmi.WMI.assert_called_once_with(moniker=self._FAKE_RES_PATH)
mock_get_wmi_obj.assert_called_once_with(self._FAKE_RES_PATH)
self.assertEqual(mock_diskdrive.HostResource,
[self._FAKE_MOUNTED_DISK_PATH])
@ -578,8 +570,7 @@ class VMUtilsTestCase(test_base.OsWinBaseTestCase):
mock.sentinel.fake_new_mounted_disk_path,
mock_rasds[0].HostResource[0])
@mock.patch.object(vmutils, 'wmi', create=True)
def test_take_vm_snapshot(self, mock_wmi):
def test_take_vm_snapshot(self):
self._lookup_vm()
mock_svc = self._get_snapshot_service()

View File

@ -30,7 +30,12 @@ class MetricsUtilsTestCase(base.BaseTestCase):
def setUp(self, mock_cache_metrics_defs):
super(MetricsUtilsTestCase, self).setUp()
self.utils = metricsutils.MetricsUtils()
self.utils._conn_obj = mock.MagicMock()
self.utils._conn = mock.MagicMock()
def test_cache_metrics_defs_no_conn(self):
self.utils._conn = None
self.utils._cache_metrics_defs()
self.assertEqual({}, self.utils._metrics_defs)
@mock.patch.object(metricsutils.MetricsUtils, '_enable_metrics')
@mock.patch.object(metricsutils.MetricsUtils, '_get_vm_resources')

View File

@ -0,0 +1,84 @@
# Copyright 2016 Cloudbase Solutions Srl
#
# 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.
import mock
from os_win.tests import test_base
from os_win.utils import baseutils
class BaseUtilsTestCase(test_base.OsWinBaseTestCase):
"""Unit tests for the os-win BaseUtils class."""
def setUp(self):
super(BaseUtilsTestCase, self).setUp()
self.utils = baseutils.BaseUtils()
self.utils._conn = mock.MagicMock()
@mock.patch.object(baseutils, 'wmi', create=True)
def test_get_wmi_obj(self, mock_wmi):
result = self.utils._get_wmi_obj(mock.sentinel.moniker)
self.assertEqual(mock_wmi.WMI.return_value, result)
mock_wmi.WMI.assert_called_once_with(moniker=mock.sentinel.moniker)
@mock.patch.object(baseutils.BaseUtils, '_get_wmi_obj')
@mock.patch.object(baseutils, 'sys')
def _check_get_wmi_conn(self, mock_sys, mock_get_wmi_obj, **kwargs):
mock_sys.platform = 'win32'
result = self.utils._get_wmi_conn(mock.sentinel.moniker, **kwargs)
self.assertEqual(mock_get_wmi_obj.return_value, result)
mock_get_wmi_obj.assert_called_once_with(mock.sentinel.moniker,
**kwargs)
def test_get_wmi_conn_kwargs(self):
self.utils._WMI_CONS.clear()
self._check_get_wmi_conn(privileges=mock.sentinel.privileges)
self.assertNotIn(mock.sentinel.moniker, baseutils.BaseUtils._WMI_CONS)
def test_get_wmi_conn(self):
self._check_get_wmi_conn()
self.assertIn(mock.sentinel.moniker, baseutils.BaseUtils._WMI_CONS)
@mock.patch.object(baseutils.BaseUtils, '_get_wmi_obj')
@mock.patch.object(baseutils, 'sys')
def test_get_wmi_conn_cached(self, mock_sys, mock_get_wmi_obj):
mock_sys.platform = 'win32'
baseutils.BaseUtils._WMI_CONS[mock.sentinel.moniker] = (
mock.sentinel.conn)
result = self.utils._get_wmi_conn(mock.sentinel.moniker)
self.assertEqual(mock.sentinel.conn, result)
self.assertFalse(mock_get_wmi_obj.called)
@mock.patch.object(baseutils, 'sys')
def test_get_wmi_conn_linux(self, mock_sys):
mock_sys.platform = 'linux'
result = self.utils._get_wmi_conn(mock.sentinel.moniker)
self.assertIsNone(result)
class BaseUtilsVirtTestCase(test_base.OsWinBaseTestCase):
"""Unit tests for the os-win BaseUtilsVirt class."""
def setUp(self):
super(BaseUtilsVirtTestCase, self).setUp()
self.utils = baseutils.BaseUtilsVirt()
self.utils._conn = mock.MagicMock()
def test_vs_man_svc(self):
expected = self.utils._conn.Msvm_VirtualSystemManagementService()[0]
self.assertEqual(expected, self.utils._vs_man_svc)

View File

@ -47,35 +47,10 @@ class HostUtilsTestCase(base.BaseTestCase):
def setUp(self):
self._hostutils = hostutils.HostUtils()
self._hostutils._conn_cimv2 = mock.MagicMock()
self._hostutils._virt_v2 = mock.MagicMock()
self._hostutils._conn = mock.MagicMock()
super(HostUtilsTestCase, self).setUp()
@mock.patch.object(hostutils, 'wmi', create=True)
def test_init_wmi_virt_conn(self, mock_wmi):
self._hostutils._init_wmi_virt_conn()
self.assertEqual(mock_wmi.WMI.return_value, self._hostutils._virt_v2)
mock_wmi.WMI.assert_called_once_with(
moniker='//./root/virtualization/v2')
@mock.patch.object(hostutils, 'wmi', create=True)
def test_init_wmi_virt_conn_exception(self, mock_wmi):
self._hostutils._virt_v2 = None
mock_wmi.WMI.side_effect = Exception
self._hostutils._init_wmi_virt_conn()
self.assertIsNone(self._hostutils._virt_v2)
def test_conn_virt(self):
self._hostutils._virt_v2 = mock.sentinel.conn
self.assertEqual(mock.sentinel.conn, self._hostutils._conn_virt)
def test_conn_virt_uninitialized(self):
self._hostutils._virt_v2 = None
self.assertRaises(exceptions.HyperVException,
getattr, self._hostutils, '_conn_virt')
@mock.patch('os_win.utils.hostutils.ctypes')
def test_get_host_tick_count64(self, mock_ctypes):
tick_count64 = "100"
@ -193,7 +168,7 @@ class HostUtilsTestCase(base.BaseTestCase):
def _check_get_numa_nodes_missing_info(self):
numa_node = mock.MagicMock()
self._hostutils._conn_virt.Msvm_NumaNode.return_value = [
self._hostutils._conn.Msvm_NumaNode.return_value = [
numa_node, numa_node]
nodes_info = self._hostutils.get_numa_nodes()
@ -218,7 +193,7 @@ class HostUtilsTestCase(base.BaseTestCase):
host_cpu = mock.MagicMock(DeviceID=self._DEVICE_ID)
mock_get_cpu_info.return_value = [host_cpu]
numa_node = mock.MagicMock(NodeID=self._NODE_ID)
self._hostutils._conn_virt.Msvm_NumaNode.return_value = [
self._hostutils._conn.Msvm_NumaNode.return_value = [
numa_node, numa_node]
nodes_info = self._hostutils.get_numa_nodes()
@ -276,7 +251,7 @@ class HostUtilsTestCase(base.BaseTestCase):
fake_gpu.DriverVersion = mock.sentinel.Fake_gpu_driver_version
mock_phys_3d_proc = (
self._hostutils._conn_virt.Msvm_Physical3dGraphicsProcessor)
self._hostutils._conn.Msvm_Physical3dGraphicsProcessor)
mock_phys_3d_proc.return_value = [fake_gpu]
return_gpus = self._hostutils.get_remotefx_gpu_info()
@ -292,7 +267,7 @@ class HostUtilsTestCase(base.BaseTestCase):
def _set_verify_host_remotefx_capability_mocks(self, isGpuCapable=True,
isSlatCapable=True):
s3d_video_pool = self._hostutils._conn_virt.Msvm_Synth3dVideoPool()[0]
s3d_video_pool = self._hostutils._conn.Msvm_Synth3dVideoPool()[0]
s3d_video_pool.IsGpuCapable = isGpuCapable
s3d_video_pool.IsSlatCapable = isSlatCapable

View File

@ -37,14 +37,6 @@ class JobUtilsTestCase(base.BaseTestCase):
self.jobutils = jobutils.JobUtils()
self.jobutils._conn = mock.MagicMock()
def test_vs_man_svc(self):
expected = self.jobutils._conn.Msvm_VirtualSystemManagementService()[0]
self.assertEqual(expected, self.jobutils._vs_man_svc)
def test_vs_man_svc_cached(self):
self.jobutils._vs_man_svc_attr = mock.sentinel.fake_svc
self.assertEqual(mock.sentinel.fake_svc, self.jobutils._vs_man_svc)
@mock.patch.object(jobutils.JobUtils, '_wait_for_job')
def test_check_ret_val_started(self, mock_wait_for_job):
self.jobutils.check_ret_val(constants.WMI_JOB_STATUS_STARTED,
@ -96,8 +88,8 @@ class JobUtilsTestCase(base.BaseTestCase):
job = self.jobutils._wait_for_job(self._FAKE_JOB_PATH)
self.assertEqual(mock_job, job)
@mock.patch.object(jobutils, 'wmi', create=True)
def test_stop_jobs(self, mock_wmi):
@mock.patch.object(jobutils.JobUtils, '_get_wmi_obj')
def test_stop_jobs(self, mock_get_wmi_obj):
mock_job1 = mock.MagicMock(Cancellable=True)
mock_job2 = mock.MagicMock(Cancellable=True)
mock_job3 = mock.MagicMock(Cancellable=True)
@ -105,7 +97,7 @@ class JobUtilsTestCase(base.BaseTestCase):
mock_job2.JobState = 3
mock_job3.JobState = constants.JOB_STATE_KILLED
mock_wmi.WMI.side_effect = [mock_job1, mock_job2, mock_job3]
mock_get_wmi_obj.side_effect = [mock_job1, mock_job2, mock_job3]
mock_vm = mock.MagicMock()
mock_vm_jobs = [mock_job1, mock_job2, mock_job3]
@ -135,10 +127,10 @@ class JobUtilsTestCase(base.BaseTestCase):
mock_job.Description = self._FAKE_JOB_DESCRIPTION
mock_job.ElapsedTime = self._FAKE_ELAPSED_TIME
wmi_patcher = mock.patch.object(jobutils, 'wmi', create=True)
wmi_patcher = mock.patch.object(jobutils.JobUtils, '_get_wmi_obj')
mock_wmi = wmi_patcher.start()
self.addCleanup(wmi_patcher.stop)
mock_wmi.WMI.return_value = mock_job
mock_wmi.return_value = mock_job
return mock_job
def test_modify_virt_resource(self):

60
os_win/utils/baseutils.py Normal file
View File

@ -0,0 +1,60 @@
# Copyright 2016 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.
"""
Base WMI utility class.
"""
import sys
if sys.platform == 'win32':
import wmi
class BaseUtils(object):
_WMI_CONS = {}
def _get_wmi_obj(self, moniker, **kwargs):
return wmi.WMI(moniker=moniker, **kwargs)
def _get_wmi_conn(self, moniker, **kwargs):
if sys.platform != 'win32':
return None
if kwargs:
return self._get_wmi_obj(moniker, **kwargs)
if moniker in self._WMI_CONS:
return self._WMI_CONS[moniker]
wmi_conn = self._get_wmi_obj(moniker)
self._WMI_CONS[moniker] = wmi_conn
return wmi_conn
class BaseUtilsVirt(BaseUtils):
_wmi_namespace = '//%s/root/virtualization/v2'
def __init__(self, host='.'):
self._vs_man_svc_attr = None
self._conn = self._get_wmi_conn(self._wmi_namespace % host)
@property
def _vs_man_svc(self):
if not self._vs_man_svc_attr:
self._vs_man_svc_attr = (
self._conn.Msvm_VirtualSystemManagementService()[0])
return self._vs_man_svc_attr

View File

@ -24,6 +24,7 @@ from oslo_log import log as logging
from os_win._i18n import _, _LE
from os_win import exceptions
from os_win.utils import _wqlutils
from os_win.utils import baseutils
from os_win.utils.compute import vmutils
from os_win.utils import jobutils
from os_win.utils.storage.initiator import iscsi_wmi_utils
@ -31,19 +32,19 @@ from os_win.utils.storage.initiator import iscsi_wmi_utils
LOG = logging.getLogger(__name__)
class LiveMigrationUtils(object):
class LiveMigrationUtils(baseutils.BaseUtilsVirt):
_STORAGE_ALLOC_SETTING_DATA_CLASS = 'Msvm_StorageAllocationSettingData'
_CIM_RES_ALLOC_SETTING_DATA_CLASS = 'CIM_ResourceAllocationSettingData'
def __init__(self):
self._conn_v2 = self._get_conn_v2()
super(LiveMigrationUtils, self).__init__()
self._vmutils = vmutils.VMUtils()
self._jobutils = jobutils.JobUtils()
self._iscsi_initiator = iscsi_wmi_utils.ISCSIInitiatorWMIUtils()
def _get_conn_v2(self, host='localhost'):
try:
return wmi.WMI(moniker='//%s/root/virtualization/v2' % host)
return self._get_wmi_conn(self._wmi_namespace % host)
except wmi.x_wmi as ex:
LOG.exception(_LE('Get version 2 connection error'))
if ex.com_error.hresult == -2147217394:
@ -57,9 +58,9 @@ class LiveMigrationUtils(object):
raise exceptions.HyperVException(msg)
def check_live_migration_config(self):
migration_svc = self._conn_v2.Msvm_VirtualSystemMigrationService()[0]
migration_svc = self._conn.Msvm_VirtualSystemMigrationService()[0]
vsmssd = (
self._conn_v2.Msvm_VirtualSystemMigrationServiceSettingData()[0])
self._conn.Msvm_VirtualSystemMigrationServiceSettingData()[0])
if not vsmssd.EnableVirtualSystemMigration:
raise exceptions.HyperVException(
_('Live migration is not enabled on this host'))
@ -163,7 +164,7 @@ class LiveMigrationUtils(object):
disk_paths_remote):
updated_resource_setting_data = []
sasds = _wqlutils.get_element_associated_class(
self._conn_v2, self._CIM_RES_ALLOC_SETTING_DATA_CLASS,
self._conn, self._CIM_RES_ALLOC_SETTING_DATA_CLASS,
element_uuid=planned_vm.Name)
for sasd in sasds:
if (sasd.ResourceType == 17 and sasd.ResourceSubType ==
@ -192,7 +193,7 @@ class LiveMigrationUtils(object):
def _get_vhd_setting_data(self, vm):
new_resource_setting_data = []
sasds = _wqlutils.get_element_associated_class(
self._conn_v2, self._STORAGE_ALLOC_SETTING_DATA_CLASS,
self._conn, self._STORAGE_ALLOC_SETTING_DATA_CLASS,
element_uuid=vm.Name)
for sasd in sasds:
if (sasd.ResourceType == 31 and sasd.ResourceSubType ==
@ -230,10 +231,9 @@ class LiveMigrationUtils(object):
def live_migrate_vm(self, vm_name, dest_host):
self.check_live_migration_config()
conn_v2_local = self._conn_v2
conn_v2_remote = self._get_conn_v2(dest_host)
vm = self._get_vm(conn_v2_local, vm_name)
vm = self._get_vm(self._conn, vm_name)
rmt_ip_addr_list = self._get_ip_address_list(conn_v2_remote,
dest_host)
@ -257,7 +257,7 @@ class LiveMigrationUtils(object):
disk_paths,
dest_host)
planned_vm = self._create_planned_vm(conn_v2_remote,
conn_v2_local,
self._conn,
vm, rmt_ip_addr_list,
dest_host)
self._update_planned_vm_disk_resources(
@ -266,7 +266,7 @@ class LiveMigrationUtils(object):
planned_vm = planned_vms[0]
new_resource_setting_data = self._get_vhd_setting_data(vm)
self._live_migrate_vm(conn_v2_local, vm, planned_vm, rmt_ip_addr_list,
self._live_migrate_vm(self._conn, vm, planned_vm, rmt_ip_addr_list,
new_resource_setting_data, dest_host)
def create_planned_vm(self, vm_name, src_host, disk_path_mapping):
@ -274,22 +274,21 @@ class LiveMigrationUtils(object):
dest_host = platform.node()
vmutils_remote = vmutils.VMUtils(src_host)
conn_v2_local = self._conn_v2
conn_v2_remote = self._get_conn_v2(src_host)
vm = self._get_vm(conn_v2_remote, vm_name)
# Make sure there are no planned VMs already.
self._destroy_existing_planned_vms(conn_v2_local, vm)
self._destroy_existing_planned_vms(self._conn, vm)
ip_addr_list = self._get_ip_address_list(conn_v2_local,
ip_addr_list = self._get_ip_address_list(self._conn,
dest_host)
disk_paths = self._get_disk_data(vm_name, vmutils_remote,
disk_path_mapping)
planned_vm = self._create_planned_vm(conn_v2_local,
planned_vm = self._create_planned_vm(self._conn,
conn_v2_remote,
vm, ip_addr_list,
dest_host)
self._update_planned_vm_disk_resources(conn_v2_local, planned_vm,
self._update_planned_vm_disk_resources(self._conn, planned_vm,
vm_name, disk_paths)

View File

@ -13,17 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
import sys
if sys.platform == 'win32':
import wmi
from os_win.utils import baseutils
class RDPConsoleUtils(object):
def __init__(self):
if sys.platform == 'win32':
self._conn = wmi.WMI(moniker='//./root/virtualization/v2')
class RDPConsoleUtils(baseutils.BaseUtilsVirt):
def get_rdp_console_port(self):
rdp_setting_data = self._conn.Msvm_TerminalServiceSettingData()[0]
return rdp_setting_data.ListenerPort

View File

@ -20,12 +20,8 @@ Based on the "root/virtualization/v2" namespace available starting with
Hyper-V Server / Windows Server 2012.
"""
import sys
import uuid
if sys.platform == 'win32':
import wmi
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import uuidutils
@ -36,6 +32,7 @@ from os_win._i18n import _, _LW
from os_win import constants
from os_win import exceptions
from os_win.utils import _wqlutils
from os_win.utils import baseutils
from os_win.utils import jobutils
from os_win.utils.metrics import metricsutils
from os_win.utils import pathutils
@ -44,7 +41,7 @@ CONF = cfg.CONF
LOG = logging.getLogger(__name__)
class VMUtils(object):
class VMUtils(baseutils.BaseUtilsVirt):
# These constants can be overridden by inherited classes
_PHYS_DISK_RES_SUB_TYPE = 'Microsoft:Hyper-V:Physical Disk Drive'
@ -118,24 +115,12 @@ class VMUtils(object):
constants.HYPERV_VM_STATE_SUSPENDED: 6}
def __init__(self, host='.'):
self._vs_man_svc_attr = None
super(VMUtils, self).__init__()
self._jobutils = jobutils.JobUtils()
self._metricsutils = metricsutils.MetricsUtils()
self._pathutils = pathutils.PathUtils()
self._enabled_states_map = {v: k for k, v in
six.iteritems(self._vm_power_states_map)}
if sys.platform == 'win32':
self._init_hyperv_wmi_conn(host)
def _init_hyperv_wmi_conn(self, host):
self._conn = wmi.WMI(moniker='//%s/root/virtualization/v2' % host)
@property
def _vs_man_svc(self):
if not self._vs_man_svc_attr:
self._vs_man_svc_attr = (
self._conn.Msvm_VirtualSystemManagementService()[0])
return self._vs_man_svc_attr
def list_instance_notes(self):
instance_notes = []
@ -490,7 +475,7 @@ class VMUtils(object):
if serial:
# Apparently this can't be set when the resource is added.
diskdrive = wmi.WMI(moniker=diskdrive_path)
diskdrive = self._get_wmi_obj(diskdrive_path)
diskdrive.ElementName = serial
self._jobutils.modify_virt_resource(diskdrive)
@ -507,7 +492,7 @@ class VMUtils(object):
return disk_resource.AddressOnParent
def set_disk_host_res(self, disk_res_path, mounted_disk_path):
diskdrive = wmi.WMI(moniker=disk_res_path)
diskdrive = self._get_wmi_obj(disk_res_path)
diskdrive.HostResource = [mounted_disk_path]
self._jobutils.modify_virt_resource(diskdrive)
@ -647,9 +632,6 @@ class VMUtils(object):
(job_path, ret_val) = self._vs_man_svc.DestroySystem(vm.path_())
self._jobutils.check_ret_val(ret_val, job_path)
def _get_wmi_obj(self, path):
return wmi.WMI(moniker=path.replace('\\', '/'))
def take_vm_snapshot(self, vm_name):
vm = self._lookup_vm_check(vm_name, as_vssd=False)
vs_snap_svc = self._conn.Msvm_VirtualSystemSnapshotService()[0]

View File

@ -15,21 +15,18 @@
import ctypes
import socket
import sys
if sys.platform == 'win32':
import wmi
from oslo_log import log as logging
from os_win._i18n import _, _LW
from os_win import constants
from os_win import exceptions
from os_win.utils import baseutils
LOG = logging.getLogger(__name__)
class HostUtils(object):
class HostUtils(baseutils.BaseUtilsVirt):
_windows_version = None
@ -46,24 +43,12 @@ class HostUtils(object):
FEATURE_RDS_VIRTUALIZATION = 322
FEATURE_MPIO = 57
_wmi_cimv2_namespace = '//./root/cimv2'
def __init__(self):
self._virt_v2 = None
if sys.platform == 'win32':
self._conn_cimv2 = wmi.WMI(privileges=["Shutdown"])
self._init_wmi_virt_conn()
def _init_wmi_virt_conn(self):
try:
self._virt_v2 = wmi.WMI(moniker='//./root/virtualization/v2')
except Exception:
pass
@property
def _conn_virt(self):
if self._virt_v2:
return self._virt_v2
raise exceptions.HyperVException(
_("No connection to the 'root/virtualization/v2' WMI namespace."))
super(HostUtils, self).__init__()
self._conn_cimv2 = self._get_wmi_conn(self._wmi_cimv2_namespace,
privileges=["Shutdown"])
def get_cpus_info(self):
# NOTE(abalutoiu): Specifying exactly the fields that we need
@ -160,10 +145,10 @@ class HostUtils(object):
return len(self._conn_cimv2.Win32_ServerFeature(ID=feature_id)) > 0
def get_numa_nodes(self):
numa_nodes = self._conn_virt.Msvm_NumaNode()
numa_nodes = self._conn.Msvm_NumaNode()
nodes_info = []
system_memory = self._conn_virt.Msvm_Memory(['NumberOfBlocks'])
processors = self._conn_virt.Msvm_Processor(['DeviceID'])
system_memory = self._conn.Msvm_Memory(['NumberOfBlocks'])
processors = self._conn.Msvm_Processor(['DeviceID'])
for node in numa_nodes:
# Due to a bug in vmms, getting Msvm_Processor for the numa
@ -174,7 +159,7 @@ class HostUtils(object):
# Msvm_NumaNode and Msvm_Processor. We need to use this class to
# relate the two because using associators on Msvm_Processor
# will also result in a crash.
numa_assoc = self._conn_virt.Msvm_HostedDependency(
numa_assoc = self._conn.Msvm_HostedDependency(
Antecedent=node.path_())
numa_node_assoc_paths = [item.Dependent for item in numa_assoc]
@ -231,7 +216,7 @@ class HostUtils(object):
def get_remotefx_gpu_info(self):
gpus = []
all_gpus = self._conn_virt.Msvm_Physical3dGraphicsProcessor(
all_gpus = self._conn.Msvm_Physical3dGraphicsProcessor(
EnabledForVirtualization=True)
for gpu in all_gpus:
gpus.append({'name': gpu.Name,
@ -242,7 +227,7 @@ class HostUtils(object):
return gpus
def verify_host_remotefx_capability(self):
synth_3d_video_pool = self._conn_virt.Msvm_Synth3dVideoPool()[0]
synth_3d_video_pool = self._conn.Msvm_Synth3dVideoPool()[0]
if not synth_3d_video_pool.IsGpuCapable:
raise exceptions.HyperVRemoteFXException(
_("To enable RemoteFX on Hyper-V at least one GPU supporting "

View File

@ -18,25 +18,20 @@
Base Utility class for operations on Hyper-V.
"""
import sys
import time
if sys.platform == 'win32':
import wmi
from oslo_log import log as logging
from oslo_service import loopingcall
from os_win._i18n import _
from os_win import constants
from os_win import exceptions
from os_win.utils import baseutils
LOG = logging.getLogger(__name__)
class JobUtils(object):
_WMI_NAMESPACE = '//%s/root/virtualization/v2'
class JobUtils(baseutils.BaseUtilsVirt):
_CONCRETE_JOB_CLASS = "Msvm_ConcreteJob"
@ -47,21 +42,6 @@ class JobUtils(object):
constants.JOB_STATE_KILLED,
constants.JOB_STATE_COMPLETED_WITH_WARNINGS]
def __init__(self, host='.'):
self._vs_man_svc_attr = None
if sys.platform == 'win32':
self._init_hyperv_wmi_conn(host)
def _init_hyperv_wmi_conn(self, host):
self._conn = wmi.WMI(moniker=self._WMI_NAMESPACE % host)
@property
def _vs_man_svc(self):
if not self._vs_man_svc_attr:
self._vs_man_svc_attr = (
self._conn.Msvm_VirtualSystemManagementService()[0])
return self._vs_man_svc_attr
def check_ret_val(self, ret_val, job_path, success_values=[0]):
if ret_val in [constants.WMI_JOB_STATUS_STARTED,
constants.WMI_JOB_STATE_RUNNING]:
@ -74,11 +54,11 @@ class JobUtils(object):
"""Poll WMI job state and wait for completion."""
job_wmi_path = job_path.replace('\\', '/')
job = wmi.WMI(moniker=job_wmi_path)
job = self._get_wmi_obj(job_wmi_path)
while job.JobState == constants.WMI_JOB_STATE_RUNNING:
time.sleep(0.1)
job = wmi.WMI(moniker=job_wmi_path)
job = self._get_wmi_obj(job_wmi_path)
if job.JobState == constants.JOB_STATE_KILLED:
LOG.debug("WMI job killed with status %s.", job.JobState)
@ -122,7 +102,7 @@ class JobUtils(object):
AffectedElement=element.path_())
for job in jobs_affecting_element:
element_jobs.append(
wmi.WMI(moniker=job.AffectingElement.replace('\\', '/')))
self._get_wmi_obj(job.AffectingElement.replace('\\', '/')))
for job in element_jobs:
if job and job.Cancellable and not self._is_job_completed(job):

View File

@ -19,20 +19,16 @@ Based on the "root/virtualization/v2" namespace available starting with
Hyper-V Server / Windows Server 2012.
"""
import sys
if sys.platform == 'win32':
import wmi
from oslo_log import log as logging
from os_win._i18n import _, _LW
from os_win import exceptions
from os_win.utils import baseutils
LOG = logging.getLogger(__name__)
class MetricsUtils(object):
class MetricsUtils(baseutils.BaseUtilsVirt):
_VIRTUAL_SYSTEM_TYPE_REALIZED = 'Microsoft:Hyper-V:System:Realized'
_DVD_DISK_RES_SUB_TYPE = 'Microsoft:Hyper-V:Virtual CD/DVD Disk'
@ -56,19 +52,11 @@ class MetricsUtils(object):
_METRICS_ENABLED = 2
_wmi_namespace = '//./root/virtualization/v2'
def __init__(self, host='.'):
self._conn_obj = None
super(MetricsUtils, self).__init__(host)
self._metrics_svc_obj = None
self._cache_metrics_defs()
@property
def _conn(self):
if not self._conn_obj:
self._conn_obj = wmi.WMI(moniker=self._wmi_namespace)
return self._conn_obj
@property
def _metrics_svc(self):
if not self._metrics_svc_obj:
@ -77,6 +65,11 @@ class MetricsUtils(object):
def _cache_metrics_defs(self):
self._metrics_defs = {}
if not self._conn:
# NOTE(claudiub): self._conn is None on Linux, causing unit tests
# to fail.
return
for metrics_def in self._conn.CIM_BaseMetricDefinition():
self._metrics_defs[metrics_def.ElementName] = metrics_def

View File

@ -28,10 +28,11 @@ if sys.platform == 'win32':
from os_win._i18n import _
from os_win import exceptions
from os_win.utils import baseutils
from os_win.utils import jobutils
class NetworkUtils(object):
class NetworkUtils(baseutils.BaseUtilsVirt):
EVENT_TYPE_CREATE = "__InstanceCreationEvent"
EVENT_TYPE_DELETE = "__InstanceDeletionEvent"
@ -80,14 +81,13 @@ class NetworkUtils(object):
_VNIC_LISTENER_TIMEOUT_MS = 2000
def __init__(self):
super(NetworkUtils, self).__init__()
self._jobutils = jobutils.JobUtils()
self._switches = {}
self._switch_ports = {}
self._vlan_sds = {}
self._vsid_sds = {}
self._sg_acl_sds = {}
if sys.platform == 'win32':
self._conn = wmi.WMI(moniker='//./root/virtualization/v2')
def init_caches(self):
for vswitch in self._conn.Msvm_VirtualEthernetSwitch():
@ -426,11 +426,10 @@ class NetworkUtils(object):
return True
def _is_port_vm_started(self, port):
vs_man_svc = self._conn.Msvm_VirtualSystemManagementService()[0]
vmsettings = port.associators(
wmi_result_class=self._VIRTUAL_SYSTEM_SETTING_DATA)
# See http://msdn.microsoft.com/en-us/library/cc160706%28VS.85%29.aspx
(ret_val, summary_info) = vs_man_svc.GetSummaryInformation(
(ret_val, summary_info) = self._vs_man_svc.GetSummaryInformation(
[self._VM_SUMMARY_ENABLED_STATE],
[v.path_() for v in vmsettings])
if ret_val or not summary_info:

View File

@ -13,23 +13,18 @@
# License for the specific language governing permissions and limitations
# under the License.
import sys
from oslo_log import log as logging
from os_win._i18n import _, _LI, _LW, _LE # noqa
from os_win import constants
from os_win import exceptions
from os_win.utils import baseutils
from os_win.utils.network import networkutils
# Check needed for unit testing on Unix
if sys.platform == 'win32':
import wmi
LOG = logging.getLogger(__name__)
class NvgreUtils(object):
class NvgreUtils(baseutils.BaseUtils):
_HYPERV_VIRT_ADAPTER = 'Hyper-V Virtual Ethernet Adapter'
_IPV4_ADDRESS_FAMILY = 2
@ -45,8 +40,7 @@ class NvgreUtils(object):
super(NvgreUtils, self).__init__()
self._utils = networkutils.NetworkUtils()
self._net_if_indexes = {}
if sys.platform == 'win32':
self._scimv2 = wmi.WMI(moniker=self._STDCIMV2_NAMESPACE)
self._scimv2 = self._get_wmi_conn(moniker=self._STDCIMV2_NAMESPACE)
def create_provider_address(self, network_name, provider_vlan_id):
iface_index = self._get_network_iface_index(network_name)

View File

@ -14,25 +14,23 @@
# under the License.
import re
import sys
if sys.platform == 'win32':
import wmi
from oslo_log import log as logging
from os_win._i18n import _
from os_win import _utils
from os_win import exceptions
from os_win.utils import baseutils
LOG = logging.getLogger(__name__)
class DiskUtils(object):
class DiskUtils(baseutils.BaseUtils):
_wmi_namespace = 'root/microsoft/windows/storage'
def __init__(self):
if sys.platform == 'win32':
self._conn_storage = wmi.WMI(
moniker='root/microsoft/windows/storage')
self._conn_storage = self._get_wmi_conn(self._wmi_namespace)
# Physical device names look like \\.\PHYSICALDRIVE1
self._phys_dev_name_regex = re.compile(r'\\\\.*\\[a-zA-Z]*([\d]+)')

View File

@ -26,22 +26,21 @@ import sys
if sys.platform == 'win32':
from six.moves import winreg
import wmi
from oslo_log import log as logging
from os_win._i18n import _LI
from os_win.utils import baseutils
LOG = logging.getLogger(__name__)
class BaseISCSIInitiatorUtils(object):
class BaseISCSIInitiatorUtils(baseutils.BaseUtils):
_FILE_DEVICE_DISK = 7
def __init__(self, host='.'):
if sys.platform == 'win32':
self._conn_wmi = wmi.WMI(moniker='//%s/root/wmi' % host)
self._conn_cimv2 = wmi.WMI(moniker='//%s/root/cimv2' % host)
self._conn_wmi = self._get_wmi_conn('//%s/root/wmi' % host)
self._conn_cimv2 = self._get_wmi_conn('//%s/root/cimv2' % host)
self._drive_number_regex = re.compile(r'DeviceID=\"[^,]*\\(\d+)\"')
@abc.abstractmethod

View File

@ -44,8 +44,7 @@ class ISCSIInitiatorWMIUtils(base_iscsi_utils.BaseISCSIInitiatorUtils):
super(ISCSIInitiatorWMIUtils, self).__init__(host)
storage_namespace = '//%s/root/microsoft/windows/storage' % host
if sys.platform == 'win32':
self._conn_storage = wmi.WMI(moniker=storage_namespace)
self._conn_storage = self._get_wmi_conn(storage_namespace)
def _login_target_portal(self, target_portal):
(target_address,

View File

@ -21,6 +21,7 @@ from oslo_log import log as logging
from os_win._i18n import _, _LE
from os_win import exceptions
from os_win.utils import baseutils
from os_win.utils import win32utils
if sys.platform == 'win32':
@ -30,11 +31,10 @@ if sys.platform == 'win32':
LOG = logging.getLogger(__name__)
class SMBUtils(object):
class SMBUtils(baseutils.BaseUtils):
def __init__(self):
self._win32_utils = win32utils.Win32Utils()
if sys.platform == "win32":
self._smb_conn = wmi.WMI(moniker=r"root\Microsoft\Windows\SMB")
self._smb_conn = self._get_wmi_conn(r"root\Microsoft\Windows\SMB")
def check_smb_mapping(self, share_path, remove_unavailable_mapping=False):
mappings = self._smb_conn.Msft_SmbMapping(RemotePath=share_path)