summaryrefslogtreecommitdiff
path: root/ironic
diff options
context:
space:
mode:
authorGhe Rivero <ghe.rivero@hp.com>2014-02-10 22:39:28 +0000
committerMichael Davies <michael@the-davies.net>2014-02-27 11:39:57 +1030
commitccb4267f4245c3e659cf818c093f7200baeaec62 (patch)
treee1823555257ab35aa34cdd11bcd808f3f8774bdc /ironic
parentbdd96dcd3b37f3ee7de744f44be092d5f91b32da (diff)
downloadironic-ccb4267f4245c3e659cf818c093f7200baeaec62.tar.gz
Move ipminative _set_boot_device to VendorPassthru
_set_boot_device must be exposed via vendor_passthru, allowing operators to manually change it, and force to boot from net when performing a pxe deploy. Until now, it was just a private method of the power driver. Change-Id: Iac3a7183db4c3486bd6a2aa1ba36bf33e11722a9 Partial-Bug: #1264596
Diffstat (limited to 'ironic')
-rw-r--r--ironic/drivers/fake.py2
-rw-r--r--ironic/drivers/modules/ipminative.py38
-rw-r--r--ironic/tests/drivers/test_ipminative.py37
3 files changed, 74 insertions, 3 deletions
diff --git a/ironic/drivers/fake.py b/ironic/drivers/fake.py
index ab3f3404c..ec8d55346 100644
--- a/ironic/drivers/fake.py
+++ b/ironic/drivers/fake.py
@@ -71,4 +71,4 @@ class FakeIPMINativeDriver(base.BaseDriver):
def __init__(self):
self.power = ipminative.NativeIPMIPower()
self.deploy = fake.FakeDeploy()
- self.vendor = self.power
+ self.vendor = ipminative.VendorPassthru()
diff --git a/ironic/drivers/modules/ipminative.py b/ironic/drivers/modules/ipminative.py
index 801b4a5a7..f4b28bb3f 100644
--- a/ironic/drivers/modules/ipminative.py
+++ b/ironic/drivers/modules/ipminative.py
@@ -263,6 +263,9 @@ class NativeIPMIPower(base.PowerInterface):
driver_info = _parse_driver_info(node)
_reboot(driver_info)
+
+class VendorPassthru(base.VendorInterface):
+
@task_manager.require_exclusive_lock
def _set_boot_device(self, task, node, device, persistent=False):
"""Set the boot device for a node.
@@ -292,3 +295,38 @@ class NativeIPMIPower(base.PowerInterface):
"with the following error: %(error)s")
% {'node_id': driver_info['uuid'], 'error': str(e)})
raise exception.IPMIFailure(cmd=str(e))
+
+ def validate(self, node, **kwargs):
+ """Validate vendor-specific actions.
+ :param node: The node
+ :param kwargs: the keyword arguments supplied
+
+ :raises: InvalidParameterValue if an invalid boot device is specified,
+ required ipmi credentials are missing or and invalid method
+ is requested to the driver.
+ """
+ method = kwargs['method']
+ if method == 'set_boot_device':
+ device = kwargs.get('device', None)
+ if device not in ipmi_command.boot_devices:
+ raise exception.InvalidParameterValue(_(
+ "Invalid boot device %s specified.") % device)
+ else:
+ raise exception.InvalidParameterValue(_(
+ "Unsupported method (%s) passed to IPMINative driver.")
+ % method)
+ _parse_driver_info(node)
+ return True
+
+ def vendor_passthru(self, task, node, **kwargs):
+ """Receive requests for vendor-specific actions.
+ :param task: a TaskManager instance.
+ :param node: The node
+ :param kwargs: the keyword arguments supplied
+ """
+ method = kwargs['method']
+ if method == 'set_boot_device':
+ return self._set_boot_device(
+ task, node,
+ kwargs.get('device'),
+ kwargs.get('persistent', False))
diff --git a/ironic/tests/drivers/test_ipminative.py b/ironic/tests/drivers/test_ipminative.py
index dcb9fd9f4..32d4fbfcf 100644
--- a/ironic/tests/drivers/test_ipminative.py
+++ b/ironic/tests/drivers/test_ipminative.py
@@ -206,7 +206,7 @@ class IPMINativeDriverTestCase(db_base.DbTestCase):
with task_manager.acquire(self.context,
[self.node['uuid']]) as task:
- self.driver.power._set_boot_device(task,
+ self.driver.vendor._set_boot_device(task,
self.node,
'pxe')
ipmicmd.set_bootdev.assert_called_once_with('pxe')
@@ -214,7 +214,7 @@ class IPMINativeDriverTestCase(db_base.DbTestCase):
def test_set_boot_device_bad_device(self):
with task_manager.acquire(self.context, [self.node['uuid']]) as task:
self.assertRaises(exception.InvalidParameterValue,
- self.driver.power._set_boot_device,
+ self.driver.vendor._set_boot_device,
task,
self.node,
'fake-device')
@@ -241,3 +241,36 @@ class IPMINativeDriverTestCase(db_base.DbTestCase):
task,
self.node)
ipmicmd.set_power.assert_called_once_with('boot', 500)
+
+ def test_vendor_passthru_validate__set_boot_device_good(self):
+ self.driver.vendor.validate(self.node,
+ method='set_boot_device',
+ device='pxe')
+
+ def test_vendor_passthru_validate__set_boot_device_fail(self):
+ self.assertRaises(exception.InvalidParameterValue,
+ self.driver.vendor.validate,
+ self.node, method='set_boot_device',
+ device='fake')
+
+ def test_vendor_passthru_validate__set_boot_device_fail_no_device(self):
+ self.assertRaises(exception.InvalidParameterValue,
+ self.driver.vendor.validate,
+ self.node, method='set_boot_device')
+
+ def test_vendor_passthru_validate_method_notmatch(self):
+ self.assertRaises(exception.InvalidParameterValue,
+ self.driver.vendor.validate,
+ self.node, method='fake_method')
+
+ def test_vendor_passthru_call__set_boot_device(self):
+ with task_manager.acquire(self.context, [self.node['uuid']],
+ shared=False) as task:
+ with mock.patch.object(ipminative.VendorPassthru,
+ '_set_boot_device') as boot_mock:
+ self.driver.vendor.vendor_passthru(task,
+ self.node,
+ method='set_boot_device',
+ device='pxe')
+ boot_mock.assert_called_once_with(task, self.node,
+ 'pxe', False)