Pass prep_boot_part_uuid to install_bootloader for ppc64* partition images
This patch gets the PReP Boot partition UUID when performing a local boot partition image deployment on ppc64* hardware. Depends-On: I8f9748dd58146bfb2411c229b02969e0faf18222 Change-Id: I2bc9f13ec605de7b7b96d96a1a4edebee0af76dc Story: #1749057 Task: #22995
This commit is contained in:
parent
69520d2610
commit
8f89954f9a
@ -265,6 +265,7 @@ class AgentDeployMixin(agent_base_vendor.AgentDeployMixin):
|
||||
task.process_event('resume')
|
||||
node = task.node
|
||||
iwdi = task.node.driver_internal_info.get('is_whole_disk_image')
|
||||
cpu_arch = task.node.properties.get('cpu_arch')
|
||||
error = self.check_deploy_success(node)
|
||||
if error is not None:
|
||||
# TODO(jimrollenhagen) power off if using neutron dhcp to
|
||||
@ -285,6 +286,9 @@ class AgentDeployMixin(agent_base_vendor.AgentDeployMixin):
|
||||
# In case of local boot using partition image, we need both
|
||||
# 'root_uuid_or_disk_id' and 'efi_system_partition_uuid' to configure
|
||||
# bootloader for local boot.
|
||||
# NOTE(mjturek): In the case of local boot using a partition image on
|
||||
# ppc64* hardware we need to provide the 'PReP_Boot_partition_uuid' to
|
||||
# direct where the bootloader should be installed.
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
root_uuid = self._get_uuid_from_result(task, 'root_uuid')
|
||||
if root_uuid:
|
||||
@ -312,9 +316,14 @@ class AgentDeployMixin(agent_base_vendor.AgentDeployMixin):
|
||||
efi_sys_uuid = None
|
||||
if not iwdi:
|
||||
if boot_mode_utils.get_boot_mode_for_deploy(node) == 'uefi':
|
||||
efi_sys_uuid = (
|
||||
self._get_uuid_from_result(task,
|
||||
'efi_system_partition_uuid'))
|
||||
efi_sys_uuid = (self._get_uuid_from_result(task,
|
||||
'efi_system_partition_uuid'))
|
||||
|
||||
prep_boot_part_uuid = None
|
||||
if cpu_arch is not None and cpu_arch.startswith('ppc64'):
|
||||
prep_boot_part_uuid = (self._get_uuid_from_result(task,
|
||||
'PReP_Boot_partition_uuid'))
|
||||
|
||||
LOG.info('Image successfully written to node %s', node.uuid)
|
||||
|
||||
if CONF.agent.manage_agent_boot:
|
||||
@ -324,7 +333,8 @@ class AgentDeployMixin(agent_base_vendor.AgentDeployMixin):
|
||||
# be done on node during deploy stage can be performed.
|
||||
LOG.debug('Executing driver specific tasks before booting up the '
|
||||
'instance for node %s', node.uuid)
|
||||
self.prepare_instance_to_boot(task, root_uuid, efi_sys_uuid)
|
||||
self.prepare_instance_to_boot(task, root_uuid,
|
||||
efi_sys_uuid, prep_boot_part_uuid)
|
||||
else:
|
||||
manager_utils.node_set_boot_device(task, 'disk', persistent=True)
|
||||
|
||||
|
@ -666,7 +666,8 @@ class AgentDeployMixin(HeartbeatMixin):
|
||||
manager_utils.notify_conductor_resume_deploy(task)
|
||||
|
||||
@METRICS.timer('AgentDeployMixin.prepare_instance_to_boot')
|
||||
def prepare_instance_to_boot(self, task, root_uuid, efi_sys_uuid):
|
||||
def prepare_instance_to_boot(self, task, root_uuid, efi_sys_uuid,
|
||||
prep_boot_part_uuid=None):
|
||||
"""Prepares instance to boot.
|
||||
|
||||
:param task: a TaskManager object containing the node
|
||||
@ -680,7 +681,8 @@ class AgentDeployMixin(HeartbeatMixin):
|
||||
# Install the boot loader
|
||||
self.configure_local_boot(
|
||||
task, root_uuid=root_uuid,
|
||||
efi_system_part_uuid=efi_sys_uuid)
|
||||
efi_system_part_uuid=efi_sys_uuid,
|
||||
prep_boot_part_uuid=prep_boot_part_uuid)
|
||||
try:
|
||||
task.driver.boot.prepare_instance(task)
|
||||
except Exception as e:
|
||||
@ -693,7 +695,8 @@ class AgentDeployMixin(HeartbeatMixin):
|
||||
|
||||
@METRICS.timer('AgentDeployMixin.configure_local_boot')
|
||||
def configure_local_boot(self, task, root_uuid=None,
|
||||
efi_system_part_uuid=None):
|
||||
efi_system_part_uuid=None,
|
||||
prep_boot_part_uuid=None):
|
||||
"""Helper method to configure local boot on the node.
|
||||
|
||||
This method triggers bootloader installation on the node.
|
||||
@ -707,6 +710,8 @@ class AgentDeployMixin(HeartbeatMixin):
|
||||
have a bootloader installed.
|
||||
:param efi_system_part_uuid: The UUID of the efi system partition.
|
||||
This is used only in uefi boot mode.
|
||||
:param prep_boot_part_uuid: The UUID of the PReP Boot partition.
|
||||
This is used only for booting ppc64* hardware.
|
||||
:raises: InstanceDeployFailure if bootloader installation failed or
|
||||
on encountering error while setting the boot device on the node.
|
||||
"""
|
||||
@ -720,7 +725,8 @@ class AgentDeployMixin(HeartbeatMixin):
|
||||
'efi': efi_system_part_uuid})
|
||||
result = self._client.install_bootloader(
|
||||
node, root_uuid=root_uuid,
|
||||
efi_system_part_uuid=efi_system_part_uuid)
|
||||
efi_system_part_uuid=efi_system_part_uuid,
|
||||
prep_boot_part_uuid=prep_boot_part_uuid)
|
||||
if result['command_status'] == 'FAILED':
|
||||
msg = (_("Failed to install a bootloader when "
|
||||
"deploying node %(node)s. Error: %(error)s") %
|
||||
|
@ -224,7 +224,8 @@ class AgentClient(object):
|
||||
wait=True)
|
||||
|
||||
@METRICS.timer('AgentClient.install_bootloader')
|
||||
def install_bootloader(self, node, root_uuid, efi_system_part_uuid=None):
|
||||
def install_bootloader(self, node, root_uuid, efi_system_part_uuid=None,
|
||||
prep_boot_part_uuid=None):
|
||||
"""Install a boot loader on the image.
|
||||
|
||||
:param node: A node object.
|
||||
@ -232,6 +233,9 @@ class AgentClient(object):
|
||||
:param efi_system_part_uuid: The UUID of the efi system partition
|
||||
where the bootloader will be installed to, only used for uefi
|
||||
boot mode.
|
||||
:param prep_boot_part_uuid: The UUID of the PReP Boot partition where
|
||||
the bootloader will be installed to when local booting a
|
||||
partition image on a ppc64* system.
|
||||
:raises: IronicException when failed to issue the request or there was
|
||||
a malformed response from the agent.
|
||||
:raises: AgentAPIError when agent failed to execute specified command.
|
||||
@ -239,7 +243,8 @@ class AgentClient(object):
|
||||
See :func:`get_commands_status` for a command result sample.
|
||||
"""
|
||||
params = {'root_uuid': root_uuid,
|
||||
'efi_system_part_uuid': efi_system_part_uuid}
|
||||
'efi_system_part_uuid': efi_system_part_uuid,
|
||||
'prep_boot_part_uuid': prep_boot_part_uuid}
|
||||
return self._command(node=node,
|
||||
method='image.install_bootloader',
|
||||
params=params,
|
||||
|
@ -345,7 +345,8 @@ def deploy_partition_image(
|
||||
address, port, iqn, lun, image_path,
|
||||
root_mb, swap_mb, ephemeral_mb, ephemeral_format, node_uuid,
|
||||
preserve_ephemeral=False, configdrive=None,
|
||||
boot_option=None, boot_mode="bios", disk_label=None):
|
||||
boot_option=None, boot_mode="bios", disk_label=None,
|
||||
cpu_arch=""):
|
||||
"""All-in-one function to deploy a partition image to a node.
|
||||
|
||||
:param address: The iSCSI IP address.
|
||||
@ -370,6 +371,7 @@ def deploy_partition_image(
|
||||
:param disk_label: The disk label to be used when creating the
|
||||
partition table. Valid values are: "msdos", "gpt" or None; If None
|
||||
Ironic will figure it out according to the boot_mode parameter.
|
||||
:param cpu_arch: Architecture of the node being deployed to.
|
||||
:raises: InstanceDeployFailure if image virtual size is bigger than root
|
||||
partition size.
|
||||
:returns: a dictionary containing the following keys:
|
||||
@ -392,7 +394,7 @@ def deploy_partition_image(
|
||||
dev, root_mb, swap_mb, ephemeral_mb, ephemeral_format, image_path,
|
||||
node_uuid, preserve_ephemeral=preserve_ephemeral,
|
||||
configdrive=configdrive, boot_option=boot_option,
|
||||
boot_mode=boot_mode, disk_label=disk_label)
|
||||
boot_mode=boot_mode, disk_label=disk_label, cpu_arch=cpu_arch)
|
||||
|
||||
return uuid_dict_returned
|
||||
|
||||
|
@ -179,7 +179,8 @@ def get_deploy_info(node, address, iqn, port=None, lun='1'):
|
||||
'ephemeral_mb': i_info['ephemeral_mb'],
|
||||
'preserve_ephemeral': i_info['preserve_ephemeral'],
|
||||
'boot_option': deploy_utils.get_boot_option(node),
|
||||
'boot_mode': _get_boot_mode(node)})
|
||||
'boot_mode': _get_boot_mode(node),
|
||||
'cpu_arch': node.properties.get('cpu_arch')})
|
||||
|
||||
# Append disk label if specified
|
||||
disk_label = deploy_utils.get_disk_label(node)
|
||||
@ -408,7 +409,10 @@ class AgentDeployMixin(agent_base_vendor.AgentDeployMixin):
|
||||
uuid_dict_returned = do_agent_iscsi_deploy(task, self._client)
|
||||
root_uuid = uuid_dict_returned.get('root uuid')
|
||||
efi_sys_uuid = uuid_dict_returned.get('efi system partition uuid')
|
||||
self.prepare_instance_to_boot(task, root_uuid, efi_sys_uuid)
|
||||
prep_boot_part_uuid = uuid_dict_returned.get(
|
||||
'PrEP Boot partition uuid')
|
||||
self.prepare_instance_to_boot(task, root_uuid, efi_sys_uuid,
|
||||
prep_boot_part_uuid=prep_boot_part_uuid)
|
||||
self.reboot_and_finish_deploy(task)
|
||||
|
||||
|
||||
|
@ -983,7 +983,7 @@ class TestAgentDeploy(db_base.DbTestCase):
|
||||
self.assertIn("Ironic Python Agent version 3.1.0 and beyond",
|
||||
log_mock.call_args[0][0])
|
||||
prepare_instance_mock.assert_called_once_with(mock.ANY, task,
|
||||
None, None)
|
||||
None, None, None)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
get_power_state_mock.assert_called_once_with(task)
|
||||
node_power_action_mock.assert_called_once_with(
|
||||
@ -1078,8 +1078,67 @@ class TestAgentDeploy(db_base.DbTestCase):
|
||||
driver_int_info['root_uuid_or_disk_id']),
|
||||
boot_mode_mock.assert_called_once_with(task.node)
|
||||
self.assertFalse(log_mock.called)
|
||||
prepare_instance_mock.assert_called_once_with(mock.ANY, task,
|
||||
'root_uuid', None)
|
||||
prepare_instance_mock.assert_called_once_with(mock.ANY,
|
||||
task,
|
||||
'root_uuid',
|
||||
None, None)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
get_power_state_mock.assert_called_once_with(task)
|
||||
node_power_action_mock.assert_called_once_with(
|
||||
task, states.POWER_ON)
|
||||
self.assertEqual(states.ACTIVE, task.node.provision_state)
|
||||
self.assertEqual(states.NOSTATE, task.node.target_provision_state)
|
||||
|
||||
@mock.patch.object(agent.LOG, 'warning', spec_set=True, autospec=True)
|
||||
@mock.patch.object(boot_mode_utils, 'get_boot_mode_for_deploy',
|
||||
autospec=True)
|
||||
@mock.patch.object(agent.AgentDeployMixin, '_get_uuid_from_result',
|
||||
autospec=True)
|
||||
@mock.patch.object(manager_utils, 'node_power_action', autospec=True)
|
||||
@mock.patch.object(fake.FakePower, 'get_power_state',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch.object(agent_client.AgentClient, 'power_off',
|
||||
spec=types.FunctionType)
|
||||
@mock.patch.object(agent.AgentDeployMixin, 'prepare_instance_to_boot',
|
||||
autospec=True)
|
||||
@mock.patch('ironic.drivers.modules.agent.AgentDeployMixin'
|
||||
'.check_deploy_success', autospec=True)
|
||||
def test_reboot_to_instance_partition_localboot_ppc64(
|
||||
self, check_deploy_mock, prepare_instance_mock,
|
||||
power_off_mock, get_power_state_mock,
|
||||
node_power_action_mock, uuid_mock, boot_mode_mock, log_mock):
|
||||
check_deploy_mock.return_value = None
|
||||
uuid_mock.side_effect = ['root_uuid', 'prep_boot_part_uuid']
|
||||
self.node.provision_state = states.DEPLOYWAIT
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
self.node.save()
|
||||
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
get_power_state_mock.return_value = states.POWER_OFF
|
||||
driver_internal_info = task.node.driver_internal_info
|
||||
driver_internal_info['is_whole_disk_image'] = False
|
||||
task.node.driver_internal_info = driver_internal_info
|
||||
boot_option = {'capabilities': '{"boot_option": "local"}'}
|
||||
task.node.instance_info = boot_option
|
||||
properties = task.node.properties
|
||||
properties.update(cpu_arch='ppc64le')
|
||||
task.node.properties = properties
|
||||
boot_mode_mock.return_value = 'bios'
|
||||
task.driver.deploy.reboot_to_instance(task)
|
||||
|
||||
check_deploy_mock.assert_called_once_with(mock.ANY, task.node)
|
||||
driver_int_info = task.node.driver_internal_info
|
||||
self.assertEqual('root_uuid',
|
||||
driver_int_info['root_uuid_or_disk_id']),
|
||||
uuid_mock_calls = [
|
||||
mock.call(mock.ANY, task, 'root_uuid'),
|
||||
mock.call(mock.ANY, task, 'PReP_Boot_partition_uuid')]
|
||||
uuid_mock.assert_has_calls(uuid_mock_calls)
|
||||
boot_mode_mock.assert_called_once_with(task.node)
|
||||
self.assertFalse(log_mock.called)
|
||||
prepare_instance_mock.assert_called_once_with(
|
||||
mock.ANY, task, 'root_uuid', None, 'prep_boot_part_uuid')
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
get_power_state_mock.assert_called_once_with(task)
|
||||
node_power_action_mock.assert_called_once_with(
|
||||
@ -1171,7 +1230,7 @@ class TestAgentDeploy(db_base.DbTestCase):
|
||||
boot_mode_mock.assert_called_once_with(task.node)
|
||||
self.assertFalse(log_mock.called)
|
||||
prepare_instance_mock.assert_called_once_with(
|
||||
mock.ANY, task, 'root_uuid', 'efi_uuid')
|
||||
mock.ANY, task, 'root_uuid', 'efi_uuid', None)
|
||||
power_off_mock.assert_called_once_with(task.node)
|
||||
get_power_state_mock.assert_called_once_with(task)
|
||||
node_power_action_mock.assert_called_once_with(
|
||||
|
@ -763,7 +763,25 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||
task, boot_devices.DISK)
|
||||
install_bootloader_mock.assert_called_once_with(
|
||||
mock.ANY, task.node, root_uuid='some-root-uuid',
|
||||
efi_system_part_uuid=None)
|
||||
efi_system_part_uuid=None, prep_boot_part_uuid=None)
|
||||
|
||||
@mock.patch.object(agent_client.AgentClient, 'install_bootloader',
|
||||
autospec=True)
|
||||
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
|
||||
def test_configure_local_boot_with_prep(self, try_set_boot_device_mock,
|
||||
install_bootloader_mock):
|
||||
install_bootloader_mock.return_value = {
|
||||
'command_status': 'SUCCESS', 'command_error': None}
|
||||
with task_manager.acquire(self.context, self.node['uuid'],
|
||||
shared=False) as task:
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = False
|
||||
self.deploy.configure_local_boot(task, root_uuid='some-root-uuid',
|
||||
prep_boot_part_uuid='fake-prep')
|
||||
try_set_boot_device_mock.assert_called_once_with(
|
||||
task, boot_devices.DISK)
|
||||
install_bootloader_mock.assert_called_once_with(
|
||||
mock.ANY, task.node, root_uuid='some-root-uuid',
|
||||
efi_system_part_uuid=None, prep_boot_part_uuid='fake-prep')
|
||||
|
||||
@mock.patch.object(agent_client.AgentClient, 'install_bootloader',
|
||||
autospec=True)
|
||||
@ -782,7 +800,8 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||
task, boot_devices.DISK)
|
||||
install_bootloader_mock.assert_called_once_with(
|
||||
mock.ANY, task.node, root_uuid='some-root-uuid',
|
||||
efi_system_part_uuid='efi-system-part-uuid')
|
||||
efi_system_part_uuid='efi-system-part-uuid',
|
||||
prep_boot_part_uuid=None)
|
||||
|
||||
@mock.patch.object(deploy_utils, 'try_set_boot_device', autospec=True)
|
||||
@mock.patch.object(agent_client.AgentClient, 'install_bootloader',
|
||||
@ -828,7 +847,7 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||
task, root_uuid='some-root-uuid')
|
||||
install_bootloader_mock.assert_called_once_with(
|
||||
mock.ANY, task.node, root_uuid='some-root-uuid',
|
||||
efi_system_part_uuid=None)
|
||||
efi_system_part_uuid=None, prep_boot_part_uuid=None)
|
||||
collect_logs_mock.assert_called_once_with(mock.ANY, task.node)
|
||||
self.assertEqual(states.DEPLOYFAIL, task.node.provision_state)
|
||||
self.assertEqual(states.ACTIVE, task.node.target_provision_state)
|
||||
@ -852,10 +871,11 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = False
|
||||
self.assertRaises(exception.InstanceDeployFailure,
|
||||
self.deploy.configure_local_boot,
|
||||
task, root_uuid='some-root-uuid')
|
||||
task, root_uuid='some-root-uuid',
|
||||
prep_boot_part_uuid=None)
|
||||
install_bootloader_mock.assert_called_once_with(
|
||||
mock.ANY, task.node, root_uuid='some-root-uuid',
|
||||
efi_system_part_uuid=None)
|
||||
efi_system_part_uuid=None, prep_boot_part_uuid=None)
|
||||
try_set_boot_device_mock.assert_called_once_with(
|
||||
task, boot_devices.DISK)
|
||||
collect_logs_mock.assert_called_once_with(mock.ANY, task.node)
|
||||
@ -911,7 +931,39 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||
configure_mock.assert_called_once_with(
|
||||
self.deploy, task,
|
||||
root_uuid=root_uuid,
|
||||
efi_system_part_uuid=efi_system_part_uuid)
|
||||
efi_system_part_uuid=efi_system_part_uuid,
|
||||
prep_boot_part_uuid=None)
|
||||
boot_option_mock.assert_called_once_with(task.node)
|
||||
prepare_instance_mock.assert_called_once_with(task.driver.boot,
|
||||
task)
|
||||
self.assertFalse(failed_state_mock.called)
|
||||
|
||||
@mock.patch.object(deploy_utils, 'set_failed_state', autospec=True)
|
||||
@mock.patch.object(pxe.PXEBoot, 'prepare_instance', autospec=True)
|
||||
@mock.patch.object(deploy_utils, 'get_boot_option', autospec=True)
|
||||
@mock.patch.object(agent_base_vendor.AgentDeployMixin,
|
||||
'configure_local_boot', autospec=True)
|
||||
def test_prepare_instance_to_boot_localboot_prep_partition(
|
||||
self, configure_mock, boot_option_mock,
|
||||
prepare_instance_mock, failed_state_mock):
|
||||
boot_option_mock.return_value = 'local'
|
||||
prepare_instance_mock.return_value = None
|
||||
self.node.provision_state = states.DEPLOYING
|
||||
self.node.target_provision_state = states.ACTIVE
|
||||
self.node.save()
|
||||
root_uuid = 'root_uuid'
|
||||
efi_system_part_uuid = 'efi_sys_uuid'
|
||||
prep_boot_part_uuid = 'prep_boot_part_uuid'
|
||||
with task_manager.acquire(self.context, self.node['uuid'],
|
||||
shared=False) as task:
|
||||
self.deploy.prepare_instance_to_boot(task, root_uuid,
|
||||
efi_system_part_uuid,
|
||||
prep_boot_part_uuid)
|
||||
configure_mock.assert_called_once_with(
|
||||
self.deploy, task,
|
||||
root_uuid=root_uuid,
|
||||
efi_system_part_uuid=efi_system_part_uuid,
|
||||
prep_boot_part_uuid=prep_boot_part_uuid)
|
||||
boot_option_mock.assert_called_once_with(task.node)
|
||||
prepare_instance_mock.assert_called_once_with(task.driver.boot,
|
||||
task)
|
||||
@ -946,7 +998,8 @@ class AgentDeployMixinTest(AgentDeployMixinBaseTest):
|
||||
configure_mock.assert_called_once_with(
|
||||
self.deploy, task,
|
||||
root_uuid=root_uuid,
|
||||
efi_system_part_uuid=efi_system_part_uuid)
|
||||
efi_system_part_uuid=efi_system_part_uuid,
|
||||
prep_boot_part_uuid=None)
|
||||
boot_option_mock.assert_called_once_with(task.node)
|
||||
self.assertFalse(prepare_mock.called)
|
||||
self.assertFalse(failed_state_mock.called)
|
||||
|
@ -247,19 +247,29 @@ class TestAgentClient(base.TestCase):
|
||||
node=self.node, method='iscsi.start_iscsi_target',
|
||||
params=params, wait=True)
|
||||
|
||||
def test_install_bootloader(self):
|
||||
def _test_install_bootloader(self, root_uuid, efi_system_part_uuid=None,
|
||||
prep_boot_part_uuid=None):
|
||||
self.client._command = mock.MagicMock(spec_set=[])
|
||||
root_uuid = 'fake-root-uuid'
|
||||
efi_system_part_uuid = 'fake-efi-system-part-uuid'
|
||||
params = {'root_uuid': root_uuid,
|
||||
'efi_system_part_uuid': efi_system_part_uuid}
|
||||
'efi_system_part_uuid': efi_system_part_uuid,
|
||||
'prep_boot_part_uuid': prep_boot_part_uuid}
|
||||
|
||||
self.client.install_bootloader(
|
||||
self.node, root_uuid, efi_system_part_uuid=efi_system_part_uuid)
|
||||
self.node, root_uuid, efi_system_part_uuid=efi_system_part_uuid,
|
||||
prep_boot_part_uuid=prep_boot_part_uuid)
|
||||
self.client._command.assert_called_once_with(
|
||||
node=self.node, method='image.install_bootloader', params=params,
|
||||
wait=True)
|
||||
|
||||
def test_install_bootloader(self):
|
||||
self._test_install_bootloader(root_uuid='fake-root-uuid',
|
||||
efi_system_part_uuid='fake-efi-uuid')
|
||||
|
||||
def test_install_bootloaderi_with_prep(self):
|
||||
self._test_install_bootloader(root_uuid='fake-root-uuid',
|
||||
efi_system_part_uuid='fake-efi-uuid',
|
||||
prep_boot_part_uuid='fake-prep-uuid')
|
||||
|
||||
def test_get_clean_steps(self):
|
||||
self.client._command = mock.MagicMock(spec_set=[])
|
||||
ports = []
|
||||
|
@ -383,6 +383,7 @@ class PhysicalWorkTestCase(tests_base.TestCase):
|
||||
'boot_mode': None,
|
||||
'boot_option': None,
|
||||
'configdrive': None,
|
||||
'cpu_arch': None,
|
||||
'disk_label': None,
|
||||
'ephemeral_format': None,
|
||||
'ephemeral_mb': None,
|
||||
@ -422,6 +423,7 @@ class PhysicalWorkTestCase(tests_base.TestCase):
|
||||
'boot_option': deploy_args['boot_option'],
|
||||
'configdrive': deploy_args['configdrive'],
|
||||
'disk_label': deploy_args['disk_label'],
|
||||
'cpu_arch': deploy_args['cpu_arch'] or '',
|
||||
'preserve_ephemeral': deploy_args['preserve_ephemeral']
|
||||
}
|
||||
utils.deploy_partition_image(
|
||||
@ -444,7 +446,8 @@ class PhysicalWorkTestCase(tests_base.TestCase):
|
||||
# not set
|
||||
'boot_option': deploy_args['boot_option'] or 'netboot',
|
||||
'boot_mode': deploy_args['boot_mode'],
|
||||
'disk_label': deploy_args['disk_label']
|
||||
'disk_label': deploy_args['disk_label'],
|
||||
'cpu_arch': deploy_args['cpu_arch'] or ''
|
||||
}
|
||||
mock_work_on_disk.assert_called_once_with(
|
||||
dev, deploy_args['root_mb'], deploy_args['swap_mb'],
|
||||
@ -502,6 +505,9 @@ class PhysicalWorkTestCase(tests_base.TestCase):
|
||||
def test_deploy_partition_image_with_configdrive(self):
|
||||
self._test_deploy_partition_image(configdrive='http://1.2.3.4/cd')
|
||||
|
||||
def test_deploy_partition_image_with_cpu_arch(self):
|
||||
self._test_deploy_partition_image(cpu_arch='generic')
|
||||
|
||||
@mock.patch.object(disk_utils, 'create_config_drive_partition',
|
||||
autospec=True)
|
||||
@mock.patch.object(disk_utils, 'get_disk_identifier', autospec=True)
|
||||
@ -775,7 +781,8 @@ class PhysicalWorkTestCase(tests_base.TestCase):
|
||||
preserve_ephemeral=False,
|
||||
boot_option="netboot",
|
||||
boot_mode="bios",
|
||||
disk_label=None)]
|
||||
disk_label=None,
|
||||
cpu_arch="")]
|
||||
|
||||
self.assertRaises(TestException, utils.deploy_partition_image,
|
||||
address, port, iqn, lun, image_path,
|
||||
|
@ -896,7 +896,7 @@ class ISCSIDeployTestCase(db_base.DbTestCase):
|
||||
task, task.driver.deploy._client)
|
||||
configure_local_boot_mock.assert_called_once_with(
|
||||
task.driver.deploy, task, root_uuid='some-root-uuid',
|
||||
efi_system_part_uuid=None)
|
||||
efi_system_part_uuid=None, prep_boot_part_uuid=None)
|
||||
reboot_and_finish_deploy_mock.assert_called_once_with(
|
||||
task.driver.deploy, task)
|
||||
set_boot_device_mock.assert_called_once_with(
|
||||
@ -928,7 +928,7 @@ class ISCSIDeployTestCase(db_base.DbTestCase):
|
||||
task, task.driver.deploy._client)
|
||||
configure_local_boot_mock.assert_called_once_with(
|
||||
task.driver.deploy, task, root_uuid='some-root-uuid',
|
||||
efi_system_part_uuid='efi-part-uuid')
|
||||
efi_system_part_uuid='efi-part-uuid', prep_boot_part_uuid=None)
|
||||
reboot_and_finish_deploy_mock.assert_called_once_with(
|
||||
task.driver.deploy, task)
|
||||
set_boot_device_mock.assert_called_once_with(
|
||||
|
@ -38,7 +38,7 @@ greenlet==0.4.13
|
||||
hacking==1.0.0
|
||||
idna==2.6
|
||||
imagesize==1.0.0
|
||||
ironic-lib==2.5.0
|
||||
ironic-lib==2.14.0
|
||||
iso8601==0.1.11
|
||||
Jinja2==2.10
|
||||
jmespath==0.9.3
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- Added support for local booting a partition image for ppc64*
|
||||
hardware. If a PReP partition is detected when deploying to a
|
||||
ppc64* machine, the partition will be specified to IPA causing
|
||||
the bootloader to be installed there directly. This feature
|
||||
requires a ironic-python-agent ramdisk with ironic-lib >=2.14.
|
@ -11,7 +11,7 @@ python-cinderclient>=3.3.0 # Apache-2.0
|
||||
python-neutronclient>=6.7.0 # Apache-2.0
|
||||
python-glanceclient>=2.8.0 # Apache-2.0
|
||||
keystoneauth1>=3.4.0 # Apache-2.0
|
||||
ironic-lib>=2.5.0 # Apache-2.0
|
||||
ironic-lib>=2.14.0 # Apache-2.0
|
||||
python-swiftclient>=3.2.0 # Apache-2.0
|
||||
pytz>=2013.6 # MIT
|
||||
stevedore>=1.20.0 # Apache-2.0
|
||||
|
Loading…
Reference in New Issue
Block a user