Merge "Using non-persistent boot in PXE interface"

This commit is contained in:
Jenkins 2017-07-14 13:19:16 +00:00 committed by Gerrit Code Review
commit 7a0632dd59
5 changed files with 52 additions and 15 deletions

View File

@ -129,6 +129,10 @@ def _cleaning_reboot(task):
:param task: a TaskManager instance :param task: a TaskManager instance
""" """
try: try:
# NOTE(fellypefca): Call prepare_ramdisk on ensure that the
# baremetal node boots back into the ramdisk after reboot.
deploy_opts = deploy_utils.build_agent_options(task.node)
task.driver.boot.prepare_ramdisk(task, deploy_opts)
manager_utils.node_power_action(task, states.REBOOT) manager_utils.node_power_action(task, states.REBOOT)
except Exception as e: except Exception as e:
msg = (_('Reboot requested by clean step %(step)s failed for ' msg = (_('Reboot requested by clean step %(step)s failed for '

View File

@ -32,6 +32,7 @@ from ironic.common import images
from ironic.common import pxe_utils from ironic.common import pxe_utils
from ironic.common import states from ironic.common import states
from ironic.common import utils from ironic.common import utils
from ironic.conductor import utils as manager_utils
from ironic.conf import CONF from ironic.conf import CONF
from ironic.drivers import base from ironic.drivers import base
from ironic.drivers.modules import deploy_utils from ironic.drivers.modules import deploy_utils
@ -490,7 +491,8 @@ class PXEBoot(base.BootInterface):
pxe_utils.create_pxe_config(task, pxe_options, pxe_utils.create_pxe_config(task, pxe_options,
pxe_config_template) pxe_config_template)
deploy_utils.try_set_boot_device(task, boot_devices.PXE) manager_utils.node_set_boot_device(task, boot_devices.PXE,
persistent=False)
if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift: if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
pxe_info.pop('deploy_kernel', None) pxe_info.pop('deploy_kernel', None)
@ -602,7 +604,8 @@ class PXEBoot(base.BootInterface):
# NOTE(pas-ha) do not re-set boot device on ACTIVE nodes # NOTE(pas-ha) do not re-set boot device on ACTIVE nodes
# during takeover # during takeover
if boot_device and task.node.provision_state != states.ACTIVE: if boot_device and task.node.provision_state != states.ACTIVE:
deploy_utils.try_set_boot_device(task, boot_device) manager_utils.node_set_boot_device(task, boot_device,
persistent=True)
@METRICS.timer('PXEBoot.clean_up_instance') @METRICS.timer('PXEBoot.clean_up_instance')
def clean_up_instance(self, task): def clean_up_instance(self, task):

View File

@ -755,17 +755,26 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
self.deploy.continue_cleaning(task) self.deploy.continue_cleaning(task)
notify_mock.assert_called_once_with(task) notify_mock.assert_called_once_with(task)
@mock.patch.object(deploy_utils, 'build_agent_options', autospec=True)
@mock.patch.object(pxe.PXEBoot, 'prepare_ramdisk', spec_set=True,
autospec=True)
@mock.patch.object(manager_utils, 'node_power_action', autospec=True) @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
def test__cleaning_reboot(self, mock_reboot): def test__cleaning_reboot(self, mock_reboot, mock_prepare, mock_build_opt):
with task_manager.acquire(self.context, self.node['uuid'], with task_manager.acquire(self.context, self.node['uuid'],
shared=False) as task: shared=False) as task:
agent_base_vendor._cleaning_reboot(task) agent_base_vendor._cleaning_reboot(task)
self.assertTrue(mock_build_opt.called)
self.assertTrue(mock_prepare.called)
mock_reboot.assert_called_once_with(task, states.REBOOT) mock_reboot.assert_called_once_with(task, states.REBOOT)
self.assertTrue(task.node.driver_internal_info['cleaning_reboot']) self.assertTrue(task.node.driver_internal_info['cleaning_reboot'])
@mock.patch.object(deploy_utils, 'build_agent_options', autospec=True)
@mock.patch.object(pxe.PXEBoot, 'prepare_ramdisk', spec_set=True,
autospec=True)
@mock.patch.object(manager_utils, 'cleaning_error_handler', autospec=True) @mock.patch.object(manager_utils, 'cleaning_error_handler', autospec=True)
@mock.patch.object(manager_utils, 'node_power_action', autospec=True) @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
def test__cleaning_reboot_fail(self, mock_reboot, mock_handler): def test__cleaning_reboot_fail(self, mock_reboot, mock_handler,
mock_prepare, mock_build_opt):
mock_reboot.side_effect = RuntimeError("broken") mock_reboot.side_effect = RuntimeError("broken")
with task_manager.acquire(self.context, self.node['uuid'], with task_manager.acquire(self.context, self.node['uuid'],
@ -776,10 +785,14 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
self.assertNotIn('cleaning_reboot', self.assertNotIn('cleaning_reboot',
task.node.driver_internal_info) task.node.driver_internal_info)
@mock.patch.object(deploy_utils, 'build_agent_options', autospec=True)
@mock.patch.object(pxe.PXEBoot, 'prepare_ramdisk', spec_set=True,
autospec=True)
@mock.patch.object(manager_utils, 'node_power_action', autospec=True) @mock.patch.object(manager_utils, 'node_power_action', autospec=True)
@mock.patch.object(agent_client.AgentClient, 'get_commands_status', @mock.patch.object(agent_client.AgentClient, 'get_commands_status',
autospec=True) autospec=True)
def test_continue_cleaning_reboot(self, status_mock, reboot_mock): def test_continue_cleaning_reboot(
self, status_mock, reboot_mock, mock_prepare, mock_build_opt):
# Test a successful execute clean step on the agent, with reboot # Test a successful execute clean step on the agent, with reboot
self.node.clean_step = { self.node.clean_step = {
'priority': 42, 'priority': 42,

View File

@ -32,6 +32,7 @@ from ironic.common.glance_service import base_image_service
from ironic.common import pxe_utils from ironic.common import pxe_utils
from ironic.common import states from ironic.common import states
from ironic.conductor import task_manager from ironic.conductor import task_manager
from ironic.conductor import utils as manager_utils
from ironic.drivers.modules import agent_base_vendor from ironic.drivers.modules import agent_base_vendor
from ironic.drivers.modules import deploy_utils from ironic.drivers.modules import deploy_utils
from ironic.drivers.modules import pxe from ironic.drivers.modules import pxe
@ -800,6 +801,7 @@ class PXEBootTestCase(db_base.DbTestCase):
self.assertRaises(exception.InvalidParameterValue, self.assertRaises(exception.InvalidParameterValue,
task.driver.boot.validate, task) task.driver.boot.validate, task)
@mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(dhcp_factory, 'DHCPFactory') @mock.patch.object(dhcp_factory, 'DHCPFactory')
@mock.patch.object(pxe, '_get_instance_image_info', autospec=True) @mock.patch.object(pxe, '_get_instance_image_info', autospec=True)
@mock.patch.object(pxe, '_get_deploy_image_info', autospec=True) @mock.patch.object(pxe, '_get_deploy_image_info', autospec=True)
@ -810,7 +812,9 @@ class PXEBootTestCase(db_base.DbTestCase):
mock_build_pxe, mock_cache_r_k, mock_build_pxe, mock_cache_r_k,
mock_deploy_img_info, mock_deploy_img_info,
mock_instance_img_info, mock_instance_img_info,
dhcp_factory_mock, uefi=False, dhcp_factory_mock,
set_boot_device_mock,
uefi=False,
cleaning=False, cleaning=False,
ipxe_use_swift=False, ipxe_use_swift=False,
whole_disk_image=False): whole_disk_image=False):
@ -833,6 +837,9 @@ class PXEBootTestCase(db_base.DbTestCase):
task.driver.boot.prepare_ramdisk(task, {'foo': 'bar'}) task.driver.boot.prepare_ramdisk(task, {'foo': 'bar'})
mock_deploy_img_info.assert_called_once_with(task.node) mock_deploy_img_info.assert_called_once_with(task.node)
provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts) provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
set_boot_device_mock.assert_called_once_with(task,
boot_devices.PXE,
persistent=False)
if ipxe_use_swift: if ipxe_use_swift:
if whole_disk_image: if whole_disk_image:
self.assertFalse(mock_cache_r_k.called) self.assertFalse(mock_cache_r_k.called)
@ -984,7 +991,7 @@ class PXEBootTestCase(db_base.DbTestCase):
clean_up_pxe_env_mock.assert_called_once_with(task, image_info) clean_up_pxe_env_mock.assert_called_once_with(task, image_info)
get_deploy_image_info_mock.assert_called_once_with(task.node) get_deploy_image_info_mock.assert_called_once_with(task.node)
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
@mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
@mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True) @mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True)
@ -1018,11 +1025,12 @@ class PXEBootTestCase(db_base.DbTestCase):
pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50", pxe_config_path, "30212642-09d3-467f-8e09-21685826ab50",
'bios', False, False, False) 'bios', False, False, False)
set_boot_device_mock.assert_called_once_with(task, set_boot_device_mock.assert_called_once_with(task,
boot_devices.PXE) boot_devices.PXE,
persistent=True)
@mock.patch('os.path.isfile', return_value=False) @mock.patch('os.path.isfile', return_value=False)
@mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True) @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True)
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
@mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
@mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True) @mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True)
@ -1061,7 +1069,7 @@ class PXEBootTestCase(db_base.DbTestCase):
'bios', False, False, False) 'bios', False, False, False)
self.assertFalse(set_boot_device_mock.called) self.assertFalse(set_boot_device_mock.called)
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
@mock.patch.object(dhcp_factory, 'DHCPFactory') @mock.patch.object(dhcp_factory, 'DHCPFactory')
@mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True) @mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True)
@ -1095,7 +1103,7 @@ class PXEBootTestCase(db_base.DbTestCase):
@mock.patch.object(deploy_utils, 'is_iscsi_boot', autospec=True) @mock.patch.object(deploy_utils, 'is_iscsi_boot', autospec=True)
@mock.patch.object(noop_storage.NoopStorage, 'should_write_image', @mock.patch.object(noop_storage.NoopStorage, 'should_write_image',
autospec=True) autospec=True)
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True) @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
@mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True) @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
@mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True) @mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True)
@ -1136,9 +1144,10 @@ class PXEBootTestCase(db_base.DbTestCase):
switch_pxe_config_mock.assert_called_once_with( switch_pxe_config_mock.assert_called_once_with(
pxe_config_path, None, None, False, iscsi_boot=True) pxe_config_path, None, None, False, iscsi_boot=True)
set_boot_device_mock.assert_called_once_with(task, set_boot_device_mock.assert_called_once_with(task,
boot_devices.PXE) boot_devices.PXE,
persistent=True)
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True)
def test_prepare_instance_localboot(self, clean_up_pxe_config_mock, def test_prepare_instance_localboot(self, clean_up_pxe_config_mock,
set_boot_device_mock): set_boot_device_mock):
@ -1147,9 +1156,10 @@ class PXEBootTestCase(db_base.DbTestCase):
task.driver.boot.prepare_instance(task) task.driver.boot.prepare_instance(task)
clean_up_pxe_config_mock.assert_called_once_with(task) clean_up_pxe_config_mock.assert_called_once_with(task)
set_boot_device_mock.assert_called_once_with(task, set_boot_device_mock.assert_called_once_with(task,
boot_devices.DISK) boot_devices.DISK,
persistent=True)
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True) @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
@mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True) @mock.patch.object(pxe_utils, 'clean_up_pxe_config', autospec=True)
def test_prepare_instance_localboot_active(self, clean_up_pxe_config_mock, def test_prepare_instance_localboot_active(self, clean_up_pxe_config_mock,
set_boot_device_mock): set_boot_device_mock):

View File

@ -0,0 +1,7 @@
fixes:
- |
Fixes a bug which caused boot device changes to be persistent in
places where they did not need to be during cleaning and deployment
phases, due to the default behavior of PXE interface forcing a persistent
change.
For more info, see https://bugs.launchpad.net/ironic/+bug/1701721