diff options
author | Ghe Rivero <ghe.rivero@hp.com> | 2014-02-10 22:39:28 +0000 |
---|---|---|
committer | Michael Davies <michael@the-davies.net> | 2014-02-27 11:39:57 +1030 |
commit | ccb4267f4245c3e659cf818c093f7200baeaec62 (patch) | |
tree | e1823555257ab35aa34cdd11bcd808f3f8774bdc /ironic | |
parent | bdd96dcd3b37f3ee7de744f44be092d5f91b32da (diff) | |
download | ironic-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.py | 2 | ||||
-rw-r--r-- | ironic/drivers/modules/ipminative.py | 38 | ||||
-rw-r--r-- | ironic/tests/drivers/test_ipminative.py | 37 |
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) |