Add PyMI as requirement
Since PyMI requires the MI API, available only since Windows 8 / Windows Server 2012 or as an addon on some previous versions, we need to ensure that we fall back to the legacy WMI module if PyMI cannot be loaded. Partially-Implements: blueprint json-network-config Change-Id: Ibded4cee3d3d7dc39e53bca12e015c9ef83c7f3d
This commit is contained in:
parent
fe9aa8247d
commit
148855f74e
@ -34,7 +34,6 @@ import win32process
|
||||
import win32security
|
||||
import win32service
|
||||
import winerror
|
||||
import wmi
|
||||
|
||||
from cloudbaseinit import exception
|
||||
from cloudbaseinit.osutils import base
|
||||
@ -42,7 +41,9 @@ from cloudbaseinit.utils.windows import disk
|
||||
from cloudbaseinit.utils.windows import network
|
||||
from cloudbaseinit.utils.windows import privilege
|
||||
from cloudbaseinit.utils.windows import timezone
|
||||
from cloudbaseinit.utils.windows import wmi_loader
|
||||
|
||||
wmi = wmi_loader.wmi()
|
||||
|
||||
LOG = oslo_logging.getLogger(__name__)
|
||||
AF_INET6 = 23
|
||||
|
@ -33,7 +33,7 @@ class BootConfigTest(unittest.TestCase):
|
||||
self._wmi_mock = mock.MagicMock()
|
||||
self._module_patcher = mock.patch.dict(
|
||||
'sys.modules', {
|
||||
'wmi': self._wmi_mock})
|
||||
"wmi": self._wmi_mock})
|
||||
self.snatcher = testutils.LogSnatcher(MODPATH)
|
||||
self._module_patcher.start()
|
||||
self.bootconfig = importlib.import_module(MODPATH)
|
||||
|
67
cloudbaseinit/tests/utils/windows/test_wmi_loader.py
Normal file
67
cloudbaseinit/tests/utils/windows/test_wmi_loader.py
Normal file
@ -0,0 +1,67 @@
|
||||
# Copyright 2018 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 importlib
|
||||
import os
|
||||
import unittest
|
||||
|
||||
try:
|
||||
import unittest.mock as mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
from cloudbaseinit import exception
|
||||
|
||||
MODPATH = "cloudbaseinit.utils.windows.wmi_loader"
|
||||
|
||||
|
||||
class WMILoaderTests(unittest.TestCase):
|
||||
def test_load_pymi(self):
|
||||
with mock.patch.dict('sys.modules', {'wmi': mock.sentinel.wmi}):
|
||||
wmi_loader = importlib.import_module(MODPATH)
|
||||
self.assertEqual(mock.sentinel.wmi, wmi_loader.wmi())
|
||||
|
||||
@mock.patch('imp.load_source')
|
||||
@mock.patch('os.path.isfile')
|
||||
def test_load_legacy_wmi(self, mock_isfile, mock_load_source):
|
||||
mock_isfile.return_value = True
|
||||
|
||||
mock_site = mock.MagicMock()
|
||||
fake_site_path = "fake_site_path"
|
||||
mock_site.getsitepackages.return_value = [fake_site_path]
|
||||
mock_load_source.return_value = mock.sentinel.wmi
|
||||
|
||||
with mock.patch.dict('sys.modules', {'wmi': None, 'site': mock_site}):
|
||||
wmi_loader = importlib.import_module(MODPATH)
|
||||
self.assertEqual(mock.sentinel.wmi, wmi_loader.wmi())
|
||||
|
||||
fake_wmi_path = os.path.join(fake_site_path, "wmi.py")
|
||||
mock_isfile.assert_called_once_with(fake_wmi_path)
|
||||
mock_load_source.assert_called_once_with("wmi", fake_wmi_path)
|
||||
|
||||
@mock.patch('os.path.isfile')
|
||||
def test_load_legacy_wmi_fail(self, mock_isfile):
|
||||
mock_isfile.return_value = False
|
||||
|
||||
mock_site = mock.MagicMock()
|
||||
fake_site_path = "fake_site_path"
|
||||
mock_site.getsitepackages.return_value = [fake_site_path]
|
||||
|
||||
with mock.patch.dict('sys.modules', {'wmi': None, 'site': mock_site}):
|
||||
wmi_loader = importlib.import_module(MODPATH)
|
||||
self.assertRaises(
|
||||
exception.ItemNotFoundException, wmi_loader.wmi)
|
||||
|
||||
fake_wmi_path = os.path.join(fake_site_path, "wmi.py")
|
||||
mock_isfile.assert_called_once_with(fake_wmi_path)
|
@ -13,11 +13,13 @@
|
||||
# under the License.
|
||||
|
||||
from oslo_log import log as oslo_logging
|
||||
import wmi
|
||||
|
||||
from cloudbaseinit import constant
|
||||
from cloudbaseinit import exception
|
||||
from cloudbaseinit.osutils import factory as osutils_factory
|
||||
from cloudbaseinit.utils.windows import wmi_loader
|
||||
|
||||
wmi = wmi_loader.wmi()
|
||||
|
||||
LOG = oslo_logging.getLogger(__name__)
|
||||
|
||||
|
@ -14,14 +14,15 @@
|
||||
|
||||
import os
|
||||
|
||||
import wmi
|
||||
|
||||
from oslo_log import log as oslo_logging
|
||||
|
||||
from cloudbaseinit import constant
|
||||
from cloudbaseinit import exception
|
||||
from cloudbaseinit.osutils import factory as osutils_factory
|
||||
from cloudbaseinit.utils.windows import productkeys
|
||||
from cloudbaseinit.utils.windows import wmi_loader
|
||||
|
||||
wmi = wmi_loader.wmi()
|
||||
|
||||
LOG = oslo_logging.getLogger(__name__)
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import wmi
|
||||
|
||||
from oslo_log import log as oslo_logging
|
||||
from six.moves import winreg
|
||||
|
||||
from cloudbaseinit import exception
|
||||
from cloudbaseinit.utils.windows import wmi_loader
|
||||
|
||||
wmi = wmi_loader.wmi()
|
||||
LOG = oslo_logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
# under the License.
|
||||
|
||||
import ctypes
|
||||
import wmi
|
||||
|
||||
from oslo_log import log as oslo_logging
|
||||
from six.moves import winreg
|
||||
@ -21,6 +20,9 @@ from six.moves import winreg
|
||||
from cloudbaseinit import exception
|
||||
from cloudbaseinit.utils.windows import kernel32
|
||||
from cloudbaseinit.utils.windows.storage import base
|
||||
from cloudbaseinit.utils.windows import wmi_loader
|
||||
|
||||
wmi = wmi_loader.wmi()
|
||||
|
||||
LOG = oslo_logging.getLogger(__name__)
|
||||
|
||||
|
44
cloudbaseinit/utils/windows/wmi_loader.py
Normal file
44
cloudbaseinit/utils/windows/wmi_loader.py
Normal file
@ -0,0 +1,44 @@
|
||||
# Copyright 2018 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 imp
|
||||
import os
|
||||
import site
|
||||
|
||||
from oslo_log import log as oslo_logging
|
||||
|
||||
from cloudbaseinit import exception
|
||||
|
||||
LOG = oslo_logging.getLogger(__name__)
|
||||
|
||||
|
||||
def wmi():
|
||||
try:
|
||||
# PyMI depends on the MI API, not available by default on systems older
|
||||
# than Windows 8 / Windows Server 2012
|
||||
import wmi
|
||||
return wmi
|
||||
except ImportError:
|
||||
LOG.debug("Couldn't load PyMI module, using legacy WMI")
|
||||
|
||||
wmi_path = None
|
||||
for packages_path in site.getsitepackages():
|
||||
path = os.path.join(packages_path, "wmi.py")
|
||||
if os.path.isfile(path):
|
||||
wmi_path = path
|
||||
break
|
||||
if wmi_path is None:
|
||||
raise exception.ItemNotFoundException("wmi module not found")
|
||||
|
||||
return imp.load_source("wmi", wmi_path)
|
@ -14,5 +14,6 @@ requests
|
||||
untangle==1.1.1
|
||||
pywin32;sys_platform=="win32"
|
||||
comtypes;sys_platform=="win32"
|
||||
pymi;sys_platform=="win32"
|
||||
wmi;sys_platform=="win32"
|
||||
tzlocal;sys_platform=="win32"
|
||||
|
Loading…
x
Reference in New Issue
Block a user