Merge "Using non-persistent boot in PXE interface"
This commit is contained in:
commit
7a0632dd59
@ -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 '
|
||||||
|
@ -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):
|
||||||
|
@ -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,
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user