Merge "Support agent_ilo driver to perform cleaning"
This commit is contained in:
commit
8579486784
@ -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
|
||||
#
|
||||
|
@ -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):
|
||||
|
||||
|
@ -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):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user