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 win32security
|
||||||
import win32service
|
import win32service
|
||||||
import winerror
|
import winerror
|
||||||
import wmi
|
|
||||||
|
|
||||||
from cloudbaseinit import exception
|
from cloudbaseinit import exception
|
||||||
from cloudbaseinit.osutils import base
|
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 network
|
||||||
from cloudbaseinit.utils.windows import privilege
|
from cloudbaseinit.utils.windows import privilege
|
||||||
from cloudbaseinit.utils.windows import timezone
|
from cloudbaseinit.utils.windows import timezone
|
||||||
|
from cloudbaseinit.utils.windows import wmi_loader
|
||||||
|
|
||||||
|
wmi = wmi_loader.wmi()
|
||||||
|
|
||||||
LOG = oslo_logging.getLogger(__name__)
|
LOG = oslo_logging.getLogger(__name__)
|
||||||
AF_INET6 = 23
|
AF_INET6 = 23
|
||||||
|
@ -33,7 +33,7 @@ class BootConfigTest(unittest.TestCase):
|
|||||||
self._wmi_mock = mock.MagicMock()
|
self._wmi_mock = mock.MagicMock()
|
||||||
self._module_patcher = mock.patch.dict(
|
self._module_patcher = mock.patch.dict(
|
||||||
'sys.modules', {
|
'sys.modules', {
|
||||||
'wmi': self._wmi_mock})
|
"wmi": self._wmi_mock})
|
||||||
self.snatcher = testutils.LogSnatcher(MODPATH)
|
self.snatcher = testutils.LogSnatcher(MODPATH)
|
||||||
self._module_patcher.start()
|
self._module_patcher.start()
|
||||||
self.bootconfig = importlib.import_module(MODPATH)
|
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.
|
# under the License.
|
||||||
|
|
||||||
from oslo_log import log as oslo_logging
|
from oslo_log import log as oslo_logging
|
||||||
import wmi
|
|
||||||
|
|
||||||
from cloudbaseinit import constant
|
from cloudbaseinit import constant
|
||||||
from cloudbaseinit import exception
|
from cloudbaseinit import exception
|
||||||
from cloudbaseinit.osutils import factory as osutils_factory
|
from cloudbaseinit.osutils import factory as osutils_factory
|
||||||
|
from cloudbaseinit.utils.windows import wmi_loader
|
||||||
|
|
||||||
|
wmi = wmi_loader.wmi()
|
||||||
|
|
||||||
LOG = oslo_logging.getLogger(__name__)
|
LOG = oslo_logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -14,14 +14,15 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import wmi
|
|
||||||
|
|
||||||
from oslo_log import log as oslo_logging
|
from oslo_log import log as oslo_logging
|
||||||
|
|
||||||
from cloudbaseinit import constant
|
from cloudbaseinit import constant
|
||||||
from cloudbaseinit import exception
|
from cloudbaseinit import exception
|
||||||
from cloudbaseinit.osutils import factory as osutils_factory
|
from cloudbaseinit.osutils import factory as osutils_factory
|
||||||
from cloudbaseinit.utils.windows import productkeys
|
from cloudbaseinit.utils.windows import productkeys
|
||||||
|
from cloudbaseinit.utils.windows import wmi_loader
|
||||||
|
|
||||||
|
wmi = wmi_loader.wmi()
|
||||||
|
|
||||||
LOG = oslo_logging.getLogger(__name__)
|
LOG = oslo_logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import wmi
|
|
||||||
|
|
||||||
from oslo_log import log as oslo_logging
|
from oslo_log import log as oslo_logging
|
||||||
from six.moves import winreg
|
from six.moves import winreg
|
||||||
|
|
||||||
from cloudbaseinit import exception
|
from cloudbaseinit import exception
|
||||||
|
from cloudbaseinit.utils.windows import wmi_loader
|
||||||
|
|
||||||
|
wmi = wmi_loader.wmi()
|
||||||
LOG = oslo_logging.getLogger(__name__)
|
LOG = oslo_logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import ctypes
|
import ctypes
|
||||||
import wmi
|
|
||||||
|
|
||||||
from oslo_log import log as oslo_logging
|
from oslo_log import log as oslo_logging
|
||||||
from six.moves import winreg
|
from six.moves import winreg
|
||||||
@ -21,6 +20,9 @@ from six.moves import winreg
|
|||||||
from cloudbaseinit import exception
|
from cloudbaseinit import exception
|
||||||
from cloudbaseinit.utils.windows import kernel32
|
from cloudbaseinit.utils.windows import kernel32
|
||||||
from cloudbaseinit.utils.windows.storage import base
|
from cloudbaseinit.utils.windows.storage import base
|
||||||
|
from cloudbaseinit.utils.windows import wmi_loader
|
||||||
|
|
||||||
|
wmi = wmi_loader.wmi()
|
||||||
|
|
||||||
LOG = oslo_logging.getLogger(__name__)
|
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
|
untangle==1.1.1
|
||||||
pywin32;sys_platform=="win32"
|
pywin32;sys_platform=="win32"
|
||||||
comtypes;sys_platform=="win32"
|
comtypes;sys_platform=="win32"
|
||||||
|
pymi;sys_platform=="win32"
|
||||||
wmi;sys_platform=="win32"
|
wmi;sys_platform=="win32"
|
||||||
tzlocal;sys_platform=="win32"
|
tzlocal;sys_platform=="win32"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user