From 0eed61f134f986d3e4abd4f271562b888a749777 Mon Sep 17 00:00:00 2001 From: Lin Tan Date: Fri, 15 May 2015 17:58:07 +0800 Subject: [PATCH] Reduce AMT Driver's dependence on new release of Openwsman As Openwsman>=2.4.10 is not widely supported so far, like Ubuntu. Reduce AMT Driver's dependence on the new release of Openwsman to become more user friendly. Specifically, this enables setting the boot device even with Openwsman v2.4.3 Change-Id: I52c67cd9aa3b1693375e95ee1a582a08623308a9 Close-Bug: #1454018 --- ironic/drivers/modules/amt/management.py | 75 +++++++++++++++++---- ironic/tests/drivers/amt/test_management.py | 8 +-- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/ironic/drivers/modules/amt/management.py b/ironic/drivers/modules/amt/management.py index b82f52768e..734ba917a3 100644 --- a/ironic/drivers/modules/amt/management.py +++ b/ironic/drivers/modules/amt/management.py @@ -34,6 +34,36 @@ pywsman = importutils.try_import('pywsman') LOG = logging.getLogger(__name__) +_ADDRESS = 'http://schemas.xmlsoap.org/ws/2004/08/addressing' +_ANONYMOUS = 'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous' +_WSMAN = 'http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd' + + +def _generate_change_boot_order_input(device): + """Generate Xmldoc as change_boot_order input. + + This generates a Xmldoc used as input for change_boot_order. + + :param device: the boot device. + :returns: Xmldoc. + """ + method_input = "ChangeBootOrder_INPUT" + namespace = resource_uris.CIM_BootConfigSetting + doc = pywsman.XmlDoc(method_input) + root = doc.root() + root.set_ns(namespace) + + child = root.add(namespace, 'Source', None) + child.add(_ADDRESS, 'Address', _ANONYMOUS) + + grand_child = child.add(_ADDRESS, 'ReferenceParameters', None) + grand_child.add(_WSMAN, 'ResourceURI', resource_uris.CIM_BootSourceSetting) + g_grand_child = grand_child.add(_WSMAN, 'SelectorSet', None) + g_g_grand_child = g_grand_child.add(_WSMAN, 'Selector', device) + g_g_grand_child.attr_add(_WSMAN, 'Name', 'InstanceID') + return doc + + def _set_boot_device_order(node, boot_device): """Set boot device order configuration of AMT Client. @@ -43,20 +73,17 @@ def _set_boot_device_order(node, boot_device): :raises: AMTConnectFailure """ client = amt_common.get_wsman_client(node) - source = pywsman.EndPointReference(resource_uris.CIM_BootSourceSetting, - None) device = amt_common.BOOT_DEVICES_MAPPING[boot_device] - source.add_selector('InstanceID', device) + doc = _generate_change_boot_order_input(device) method = 'ChangeBootOrder' options = pywsman.ClientOptions() options.add_selector('InstanceID', 'Intel(r) AMT: Boot Configuration 0') - options.add_property('Source', source) try: client.wsman_invoke(options, resource_uris.CIM_BootConfigSetting, - method) + method, doc) except (exception.AMTFailure, exception.AMTConnectFailure) as e: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to set boot device %(boot_device)s for " @@ -69,6 +96,32 @@ def _set_boot_device_order(node, boot_device): {'boot_device': boot_device, 'node_id': node.uuid}) +def _generate_enable_boot_config_input(): + """Generate Xmldoc as enable_boot_config input. + + This generates a Xmldoc used as input for enable_boot_config. + + :returns: Xmldoc. + """ + method_input = "SetBootConfigRole_INPUT" + namespace = resource_uris.CIM_BootService + doc = pywsman.XmlDoc(method_input) + root = doc.root() + root.set_ns(namespace) + + child = root.add(namespace, 'BootConfigSetting', None) + child.add(_ADDRESS, 'Address', _ANONYMOUS) + + grand_child = child.add(_ADDRESS, 'ReferenceParameters', None) + grand_child.add(_WSMAN, 'ResourceURI', resource_uris.CIM_BootConfigSetting) + g_grand_child = grand_child.add(_WSMAN, 'SelectorSet', None) + g_g_grand_child = g_grand_child.add(_WSMAN, 'Selector', + 'Intel(r) AMT: Boot Configuration 0') + g_g_grand_child.attr_add(_WSMAN, 'Name', 'InstanceID') + root.add(namespace, 'Role', '1') + return doc + + def _enable_boot_config(node): """Enable boot configuration of AMT Client. @@ -77,19 +130,13 @@ def _enable_boot_config(node): :raises: AMTConnectFailure """ client = amt_common.get_wsman_client(node) - config = pywsman.EndPointReference(resource_uris.CIM_BootConfigSetting, - None) - config.add_selector('InstanceID', 'Intel(r) AMT: Boot Configuration 0') - method = 'SetBootConfigRole' - + doc = _generate_enable_boot_config_input() options = pywsman.ClientOptions() options.add_selector('Name', 'Intel(r) AMT Boot Service') - - options.add_property('Role', '1') - options.add_property('BootConfigSetting', config) try: - client.wsman_invoke(options, resource_uris.CIM_BootService, method) + client.wsman_invoke(options, resource_uris.CIM_BootService, + method, doc) except (exception.AMTFailure, exception.AMTConnectFailure) as e: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to enable boot config for node " diff --git a/ironic/tests/drivers/amt/test_management.py b/ironic/tests/drivers/amt/test_management.py index 45215fe787..e18c2a5ca1 100644 --- a/ironic/tests/drivers/amt/test_management.py +++ b/ironic/tests/drivers/amt/test_management.py @@ -57,7 +57,7 @@ class AMTManagementInteralMethodsTestCase(db_base.DbTestCase): amt_mgmt._set_boot_device_order(self.node, device) mock_pywsman.invoke.assert_called_once_with(mock.ANY, - namespace, 'ChangeBootOrder') + namespace, 'ChangeBootOrder', mock.ANY) def test__set_boot_device_order_fail(self, mock_client_pywsman): namespace = resource_uris.CIM_BootConfigSetting @@ -71,7 +71,7 @@ class AMTManagementInteralMethodsTestCase(db_base.DbTestCase): self.assertRaises(exception.AMTFailure, amt_mgmt._set_boot_device_order, self.node, device) mock_pywsman.invoke.assert_called_once_with(mock.ANY, - namespace, 'ChangeBootOrder') + namespace, 'ChangeBootOrder', mock.ANY) mock_pywsman = mock_client_pywsman.Client.return_value mock_pywsman.invoke.return_value = None @@ -90,7 +90,7 @@ class AMTManagementInteralMethodsTestCase(db_base.DbTestCase): amt_mgmt._enable_boot_config(self.node) mock_pywsman.invoke.assert_called_once_with(mock.ANY, - namespace, 'SetBootConfigRole') + namespace, 'SetBootConfigRole', mock.ANY) def test__enable_boot_config_fail(self, mock_client_pywsman): namespace = resource_uris.CIM_BootService @@ -103,7 +103,7 @@ class AMTManagementInteralMethodsTestCase(db_base.DbTestCase): self.assertRaises(exception.AMTFailure, amt_mgmt._enable_boot_config, self.node) mock_pywsman.invoke.assert_called_once_with(mock.ANY, - namespace, 'SetBootConfigRole') + namespace, 'SetBootConfigRole', mock.ANY) mock_pywsman = mock_client_pywsman.Client.return_value mock_pywsman.invoke.return_value = None