Merge "Support agent_ilo driver to perform cleaning"

This commit is contained in:
Jenkins 2015-03-19 20:04:36 +00:00 committed by Gerrit Code Review
commit 8579486784
3 changed files with 155 additions and 15 deletions

View File

@ -360,6 +360,7 @@
# set to 0, will not run during cleaning. (integer value)
#agent_erase_devices_priority=<None>
#
# Options defined in ironic.drivers.modules.agent_base_vendor
#
@ -850,6 +851,16 @@
#swift_object_expiry_timeout=900
#
# Options defined in ironic.drivers.modules.ilo.deploy
#
# Priority for erase devices clean step. If unset, it defaults
# to 10. If set to 0, the step will be disabled and will not
# run during cleaning. (integer value)
#clean_priority_erase_devices=<None>
#
# Options defined in ironic.drivers.modules.ilo.management
#

View File

@ -21,6 +21,7 @@ from oslo_config import cfg
from oslo_utils import excutils
from ironic.common import boot_devices
from ironic.common import dhcp_factory
from ironic.common import exception
from ironic.common.glance_service import service_utils
from ironic.common.i18n import _
@ -48,6 +49,13 @@ LOG = logging.getLogger(__name__)
CONF = cfg.CONF
clean_opts = [
cfg.IntOpt('clean_priority_erase_devices',
help='Priority for erase devices clean step. If unset, '
'it defaults to 10. If set to 0, the step will be '
'disabled and will not run during cleaning.')
]
REQUIRED_PROPERTIES = {
'ilo_deploy_iso': _("UUID (from Glance) of the deployment ISO. "
"Required.")
@ -58,6 +66,7 @@ CONF.import_opt('pxe_append_params', 'ironic.drivers.modules.iscsi_deploy',
group='pxe')
CONF.import_opt('swift_ilo_container', 'ironic.drivers.modules.ilo.common',
group='ilo')
CONF.register_opts(clean_opts, group='ilo')
def _get_boot_iso_object_name(node):
@ -257,6 +266,14 @@ def _reboot_into(task, iso, ramdisk_options):
manager_utils.node_power_action(task, states.REBOOT)
def _prepare_agent_vmedia_boot(task):
"""prepare for vmedia boot."""
deploy_ramdisk_opts = agent.build_agent_options(task.node)
deploy_iso = task.node.driver_info['ilo_deploy_iso']
_reboot_into(task, deploy_iso, deploy_ramdisk_opts)
class IloVirtualMediaIscsiDeploy(base.DeployInterface):
def get_properties(self):
@ -384,9 +401,7 @@ class IloVirtualMediaAgentDeploy(base.DeployInterface):
image.
:raises: IloOperationError, if some operation on iLO fails.
"""
deploy_ramdisk_opts = agent.build_agent_options(task.node)
deploy_iso = task.node.driver_info['ilo_deploy_iso']
_reboot_into(task, deploy_iso, deploy_ramdisk_opts)
_prepare_agent_vmedia_boot(task)
return states.DEPLOYWAIT
@ -427,6 +442,55 @@ class IloVirtualMediaAgentDeploy(base.DeployInterface):
"""
pass
def get_clean_steps(self, task):
"""Get the list of clean steps from the agent.
:param task: a TaskManager object containing the node
:returns: A list of clean step dictionaries
"""
steps = deploy_utils.agent_get_clean_steps(task)
if CONF.ilo.clean_priority_erase_devices:
for step in steps:
if (step.get('step') == 'erase_devices' and
step.get('interface') == 'deploy'):
# Override with operator set priority
step['priority'] = CONF.ilo.clean_priority_erase_devices
return steps
def execute_clean_step(self, task, step):
"""Execute a clean step asynchronously on the agent.
:param task: a TaskManager object containing the node
:param step: a clean step dictionary to execute
:returns: states.CLEANING to signify the step will be completed async
"""
return deploy_utils.agent_execute_clean_step(task, step)
def prepare_cleaning(self, task):
"""Boot into the agent to prepare for cleaning."""
# Create cleaning ports if necessary
provider = dhcp_factory.DHCPFactory().provider
# If we have left over ports from a previous cleaning, remove them
if getattr(provider, 'delete_cleaning_ports', None):
provider.delete_cleaning_ports(task)
if getattr(provider, 'create_cleaning_ports', None):
provider.create_cleaning_ports(task)
_prepare_agent_vmedia_boot(task)
# Tell the conductor we are waiting for the agent to boot.
return states.CLEANING
def tear_down_cleaning(self, task):
"""Clean up the PXE and DHCP files after cleaning."""
manager_utils.node_power_action(task, states.POWER_OFF)
# If we created cleaning ports, delete them
provider = dhcp_factory.DHCPFactory().provider
if getattr(provider, 'delete_cleaning_ports', None):
provider.delete_cleaning_ports(task)
class IloPXEDeploy(pxe.PXEDeploy):

View File

@ -253,6 +253,21 @@ class IloDeployPrivateMethodsTestCase(db_base.DbTestCase):
boot_devices.CDROM)
node_power_action_mock.assert_called_once_with(task, states.REBOOT)
@mock.patch.object(ilo_deploy, '_reboot_into')
@mock.patch.object(agent, 'build_agent_options')
def test__prepare_agent_vmedia_boot(self, build_options_mock,
reboot_into_mock):
deploy_opts = {'a': 'b'}
build_options_mock.return_value = deploy_opts
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
task.node.driver_info['ilo_deploy_iso'] = 'deploy-iso-uuid'
ilo_deploy._prepare_agent_vmedia_boot(task)
build_options_mock.assert_called_once_with(task.node)
reboot_into_mock.assert_called_once_with(task,
'deploy-iso-uuid',
deploy_opts)
class IloVirtualMediaIscsiDeployTestCase(db_base.DbTestCase):
@ -417,21 +432,12 @@ class IloVirtualMediaAgentDeployTestCase(db_base.DbTestCase):
task.driver.deploy.validate(task)
parse_driver_info_mock.assert_called_once_with(task.node)
@mock.patch.object(ilo_deploy, '_reboot_into')
@mock.patch.object(agent, 'build_agent_options')
def test_deploy(self, build_options_mock, reboot_into_mock):
@mock.patch.object(ilo_deploy, '_prepare_agent_vmedia_boot')
def test_deploy(self, vmedia_boot_mock):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
deploy_opts = {'a': 'b'}
build_options_mock.return_value = deploy_opts
task.node.driver_info['ilo_deploy_iso'] = 'deploy-iso-uuid'
returned_state = task.driver.deploy.deploy(task)
build_options_mock.assert_called_once_with(task.node)
reboot_into_mock.assert_called_once_with(task,
'deploy-iso-uuid',
deploy_opts)
vmedia_boot_mock.assert_called_once_with(task)
self.assertEqual(states.DEPLOYWAIT, returned_state)
@mock.patch.object(manager_utils, 'node_power_action')
@ -456,6 +462,65 @@ class IloVirtualMediaAgentDeployTestCase(db_base.DbTestCase):
update_boot_mode_mock.assert_called_once_with(task)
self.assertEqual(deploy_opts, task.node.instance_info)
@mock.patch('ironic.dhcp.neutron.NeutronDHCPApi.delete_cleaning_ports')
@mock.patch('ironic.dhcp.neutron.NeutronDHCPApi.create_cleaning_ports')
@mock.patch.object(ilo_deploy, '_prepare_agent_vmedia_boot')
def test_prepare_cleaning(self, vmedia_boot_mock, create_port_mock,
delete_mock):
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
returned_state = task.driver.deploy.prepare_cleaning(task)
vmedia_boot_mock.assert_called_once_with(task)
self.assertEqual(states.CLEANING, returned_state)
create_port_mock.assert_called_once_with(task)
delete_mock.assert_called_once_with(task)
@mock.patch('ironic.dhcp.neutron.NeutronDHCPApi.delete_cleaning_ports')
@mock.patch.object(manager_utils, 'node_power_action')
def test_tear_down_cleaning(self, power_mock, delete_mock):
with task_manager.acquire(
self.context, self.node['uuid'], shared=False) as task:
task.driver.deploy.tear_down_cleaning(task)
power_mock.assert_called_once_with(task, states.POWER_OFF)
delete_mock.assert_called_once_with(task)
@mock.patch.object(deploy_utils, 'agent_execute_clean_step')
def test_execute_clean_step(self, execute_mock):
with task_manager.acquire(
self.context, self.node['uuid'], shared=False) as task:
task.driver.deploy.execute_clean_step(task, 'fake-step')
execute_mock.assert_called_once_with(task, 'fake-step')
@mock.patch.object(deploy_utils, 'agent_get_clean_steps')
def test_get_clean_steps_with_conf_option(self, get_clean_step_mock):
self.config(clean_priority_erase_devices=20, group='ilo')
get_clean_step_mock.return_value = [{
'step': 'erase_devices',
'priority': 10,
'interface': 'deploy',
'reboot_requested': False
}]
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
step = task.driver.deploy.get_clean_steps(task)
get_clean_step_mock.assert_called_once_with(task)
self.assertEqual(step[0].get('priority'),
CONF.ilo.clean_priority_erase_devices)
@mock.patch.object(deploy_utils, 'agent_get_clean_steps')
def test_get_clean_steps_without_conf_option(self, get_clean_step_mock):
get_clean_step_mock.return_value = [{
'step': 'erase_devices',
'priority': 10,
'interface': 'deploy',
'reboot_requested': False
}]
with task_manager.acquire(self.context, self.node.uuid,
shared=False) as task:
step = task.driver.deploy.get_clean_steps(task)
get_clean_step_mock.assert_called_once_with(task)
self.assertEqual(step[0].get('priority'), 10)
class VendorPassthruTestCase(db_base.DbTestCase):