summaryrefslogtreecommitdiff
path: root/ironic
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-06-12 12:35:07 +0000
committerGerrit Code Review <review@openstack.org>2015-06-12 12:35:07 +0000
commit39c7e610825cd09d75879be45b4d8420e8b01fe6 (patch)
treee29da97bfdc3466da1955a753ac7f4ce8bfc45c6 /ironic
parent7916ff927a64ca0e951e991943f53276b1f9a1f0 (diff)
parentf66d9d37c0faee3e2dd690deeb92a3d5c85b5d5b (diff)
downloadironic-39c7e610825cd09d75879be45b4d8420e8b01fe6.tar.gz
Merge "Add vendor-passthru to attach and boot an ISO"
Diffstat (limited to 'ironic')
-rw-r--r--ironic/drivers/modules/ilo/deploy.py38
-rw-r--r--ironic/tests/drivers/ilo/test_deploy.py62
2 files changed, 100 insertions, 0 deletions
diff --git a/ironic/drivers/modules/ilo/deploy.py b/ironic/drivers/modules/ilo/deploy.py
index cc37db595..f7f221894 100644
--- a/ironic/drivers/modules/ilo/deploy.py
+++ b/ironic/drivers/modules/ilo/deploy.py
@@ -730,6 +730,44 @@ class VendorPassthru(agent_base_vendor.BaseAgentVendor):
iscsi_deploy.get_deploy_info(task.node, **kwargs)
elif method == 'pass_bootloader_install_info':
iscsi_deploy.validate_pass_bootloader_info_input(task, kwargs)
+ elif method == 'boot_into_iso':
+ self._validate_boot_into_iso(task, kwargs)
+
+ def _validate_boot_into_iso(self, task, kwargs):
+ """Validates if attach_iso can be called and if inputs are proper."""
+ if not (task.node.provision_state == states.MANAGEABLE or
+ task.node.maintenance is True):
+ msg = (_("The requested action 'boot_into_iso' can be performed "
+ "only when node %(node_uuid)s is in %(state)s state or "
+ "in 'maintenance' mode") %
+ {'node_uuid': task.node.uuid,
+ 'state': states.MANAGEABLE})
+ raise exception.InvalidStateRequested(msg)
+ d_info = {'boot_iso_href': kwargs.get('boot_iso_href')}
+ error_msg = _("Error validating input for boot_into_iso vendor "
+ "passthru. Some parameters were not provided: ")
+ deploy_utils.check_for_missing_params(d_info, error_msg)
+ iscsi_deploy.validate_image_properties(
+ task.context, {'image_source': kwargs.get('boot_iso_href')}, [])
+
+ @base.passthru(['POST'])
+ @task_manager.require_exclusive_lock
+ def boot_into_iso(self, task, **kwargs):
+ """Attaches an ISO image in glance and reboots bare metal.
+
+ This method accepts an ISO image href (a Glance UUID or an HTTP(S) URL)
+ attaches it as virtual media and then reboots the node. This is
+ useful for debugging purposes. This can be invoked only when the node
+ is in manage state.
+
+ :param task: A TaskManager object.
+ :param kwargs: The arguments sent with vendor passthru. The expected
+ kwargs are::
+
+ 'boot_iso_href': href of the image to be booted. This can be
+ a Glance UUID or an HTTP(S) URL.
+ """
+ _reboot_into(task, kwargs['boot_iso_href'], ramdisk_options=None)
def _configure_vmedia_boot(self, task, root_uuid):
"""Configure vmedia boot for the node."""
diff --git a/ironic/tests/drivers/ilo/test_deploy.py b/ironic/tests/drivers/ilo/test_deploy.py
index be0d5937f..af0f839f5 100644
--- a/ironic/tests/drivers/ilo/test_deploy.py
+++ b/ironic/tests/drivers/ilo/test_deploy.py
@@ -1239,6 +1239,68 @@ class VendorPassthruTestCase(db_base.DbTestCase):
reboot_and_finish_deploy_mock.assert_called_once_with(
mock.ANY, task)
+ @mock.patch.object(ilo_deploy, '_reboot_into', spec_set=True,
+ autospec=True)
+ def test_boot_into_iso(self, reboot_into_mock):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ task.driver.vendor.boot_into_iso(task, boot_iso_href='foo')
+ reboot_into_mock.assert_called_once_with(task, 'foo',
+ ramdisk_options=None)
+
+ @mock.patch.object(ilo_deploy.VendorPassthru, '_validate_boot_into_iso',
+ spec_set=True, autospec=True)
+ def test_validate_boot_into_iso(self, validate_boot_into_iso_mock):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ vendor = ilo_deploy.VendorPassthru()
+ vendor.validate(task, method='boot_into_iso', foo='bar')
+ validate_boot_into_iso_mock.assert_called_once_with(
+ vendor, task, {'foo': 'bar'})
+
+ def test__validate_boot_into_iso_invalid_state(self):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ task.node.provision_state = states.AVAILABLE
+ self.assertRaises(
+ exception.InvalidStateRequested,
+ task.driver.vendor._validate_boot_into_iso,
+ task, {})
+
+ def test__validate_boot_into_iso_missing_boot_iso_href(self):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ task.node.provision_state = states.MANAGEABLE
+ self.assertRaises(
+ exception.MissingParameterValue,
+ task.driver.vendor._validate_boot_into_iso,
+ task, {})
+
+ @mock.patch.object(iscsi_deploy, 'validate_image_properties',
+ spec_set=True, autospec=True)
+ def test__validate_boot_into_iso_manage(self, validate_image_prop_mock):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ info = {'boot_iso_href': 'foo'}
+ task.node.provision_state = states.MANAGEABLE
+ task.driver.vendor._validate_boot_into_iso(
+ task, info)
+ validate_image_prop_mock.assert_called_once_with(
+ task.context, {'image_source': 'foo'}, [])
+
+ @mock.patch.object(iscsi_deploy, 'validate_image_properties',
+ spec_set=True, autospec=True)
+ def test__validate_boot_into_iso_maintenance(
+ self, validate_image_prop_mock):
+ with task_manager.acquire(self.context, self.node.uuid,
+ shared=False) as task:
+ info = {'boot_iso_href': 'foo'}
+ task.node.maintenance = True
+ task.driver.vendor._validate_boot_into_iso(
+ task, info)
+ validate_image_prop_mock.assert_called_once_with(
+ task.context, {'image_source': 'foo'}, [])
+
class IloPXEDeployTestCase(db_base.DbTestCase):