def test_prepare_deploy_iso_network_data(self, mock__prepare_iso_image): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: d_info = { 'ilo_deploy_kernel': 'kernel', 'ilo_deploy_ramdisk': 'ramdisk' } task.node.driver_info.update(d_info) task.node.instance_info.update() network_data = {'a': ['b']} mock_get_node_nw_data = mock.MagicMock(return_value=network_data) task.driver.network.get_node_network_data = mock_get_node_nw_data image_utils.prepare_deploy_iso(task, {}, 'deploy', d_info) expected_files = { b"""{ "a": [ "b" ] }""": 'openstack/latest/network_data.json' } mock__prepare_iso_image.assert_called_once_with( task, 'kernel', 'ramdisk', bootloader_href=None, params={}, inject_files=expected_files, base_iso=None)
def test_prepare_deploy_iso_tls(self, mock__prepare_iso_image): with tempfile.NamedTemporaryFile(delete=False) as tf: temp_name = tf.name self.addCleanup(lambda: os.unlink(temp_name)) self.config(api_ca_file=temp_name, group='agent') tf.write(b'I can haz SSLz') with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: d_info = { 'ilo_deploy_kernel': 'kernel', 'ilo_deploy_ramdisk': 'ramdisk', 'ilo_bootloader': 'bootloader' } task.node.driver_info.update(d_info) task.node.instance_info.update(deploy_boot_mode='uefi') image_utils.prepare_deploy_iso(task, {}, 'deploy', d_info) expected_files = { b"""[DEFAULT] cafile = /etc/ironic-python-agent/ironic.crt """: 'etc/ironic-python-agent.d/ironic-tls.conf', temp_name: 'etc/ironic-python-agent/ironic.crt' } mock__prepare_iso_image.assert_called_once_with( task, 'kernel', 'ramdisk', 'bootloader', params={}, inject_files=expected_files, base_iso=None)
def test_prepare_deploy_iso(self, mock__prepare_iso_image, find_mock): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: d_info = { 'ilo_deploy_kernel': 'kernel', 'ilo_deploy_ramdisk': 'ramdisk', 'ilo_bootloader': 'bootloader' } task.node.driver_info.update(d_info) find_call_list = [ mock.call('deploy_kernel', d_info), mock.call('deploy_ramdisk', d_info), mock.call('bootloader', d_info) ] find_mock.side_effect = [ 'kernel', 'ramdisk', 'bootloader' ] task.node.instance_info.update(deploy_boot_mode='uefi') image_utils.prepare_deploy_iso(task, {}, 'deploy', d_info) mock__prepare_iso_image.assert_called_once_with( task, 'kernel', 'ramdisk', 'bootloader', params={}, inject_files={}) find_mock.assert_has_calls(find_call_list)
def test_prepare_deploy_iso_network_data(self, mock_create_vfat_image, mock__prepare_iso_image): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: d_info = {'deploy_kernel': 'kernel', 'deploy_ramdisk': 'ramdisk'} task.node.driver_info.update(d_info) task.node.instance_info.update() network_data = {'a': ['b']} mock_get_node_nw_data = mock.MagicMock(return_value=network_data) task.driver.network.get_node_network_data = mock_get_node_nw_data image_utils.prepare_deploy_iso(task, {}, 'deploy', d_info) mock_create_vfat_image.assert_called_once_with(mock.ANY, mock.ANY) mock__prepare_iso_image.assert_called_once_with( task, 'kernel', 'ramdisk', bootloader_href=None, configdrive=mock.ANY, params={})
def test_prepare_deploy_iso_existing_iso(self, mock__prepare_iso_image): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: d_info = { 'redfish_deploy_iso': 'iso', } task.node.driver_info.update(d_info) task.node.instance_info.update(deploy_boot_mode='uefi') image_utils.prepare_deploy_iso(task, {}, 'deploy', d_info) mock__prepare_iso_image.assert_called_once_with( task, None, None, None, params={}, inject_files={}, base_iso='iso')
def test_prepare_deploy_iso(self, mock__prepare_iso_image): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: d_info = { 'ilo_deploy_kernel': 'kernel', 'ilo_deploy_ramdisk': 'ramdisk', 'ilo_bootloader': 'bootloader' } task.node.driver_info.update(d_info) task.node.instance_info.update(deploy_boot_mode='uefi') image_utils.prepare_deploy_iso(task, {}, 'deploy', d_info) mock__prepare_iso_image.assert_called_once_with( task, 'kernel', 'ramdisk', 'bootloader', params={}, inject_files={}, base_iso=None)
def prepare_ramdisk(self, task, ramdisk_params): """Prepares the boot of deploy or rescue ramdisk over virtual media. This method prepares the boot of the deploy or rescue ramdisk after reading relevant information from the node's driver_info and instance_info. :param task: A task from TaskManager. :param ramdisk_params: the parameters to be passed to the ramdisk. :returns: None :raises: MissingParameterValue, if some information is missing in node's driver_info or instance_info. :raises: InvalidParameterValue, if some information provided is invalid. :raises: IronicException, if some power or set boot boot device operation failed on the node. """ node = task.node # NOTE(TheJulia): If this method is being called by something # aside from deployment, clean and rescue, such as conductor takeover, # we should treat this as a no-op and move on otherwise we would # modify the state of the node due to virtual media operations. if node.provision_state not in (states.DEPLOYING, states.CLEANING, states.RESCUING, states.INSPECTING): return # NOTE(TheJulia): Since we're deploying, cleaning, or rescuing, # with virtual media boot, we should generate a token! manager_utils.add_secret_token(node, pregenerated=True) node.save() ramdisk_params['ipa-agent-token'] = \ node.driver_internal_info['agent_secret_token'] manager_utils.node_power_action(task, states.POWER_OFF) d_info = _parse_driver_info(node) config_via_floppy = d_info.get('config_via_floppy') deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task) ramdisk_params['BOOTIF'] = deploy_nic_mac if CONF.debug and 'ipa-debug' not in ramdisk_params: ramdisk_params['ipa-debug'] = '1' if config_via_floppy: if _has_vmedia_device(task, sushy.VIRTUAL_MEDIA_FLOPPY): # NOTE (etingof): IPA will read the diskette only if # we tell it to ramdisk_params['boot_method'] = 'vmedia' floppy_ref = image_utils.prepare_floppy_image( task, params=ramdisk_params) _eject_vmedia(task, sushy.VIRTUAL_MEDIA_FLOPPY) _insert_vmedia(task, floppy_ref, sushy.VIRTUAL_MEDIA_FLOPPY) LOG.debug( 'Inserted virtual floppy with configuration for ' 'node %(node)s', {'node': task.node.uuid}) else: LOG.warning( 'Config via floppy is requested, but ' 'Floppy drive is not available on node ' '%(node)s', {'node': task.node.uuid}) mode = deploy_utils.rescue_or_deploy_mode(node) iso_ref = image_utils.prepare_deploy_iso(task, ramdisk_params, mode, d_info) _eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD) _insert_vmedia(task, iso_ref, sushy.VIRTUAL_MEDIA_CD) boot_mode_utils.sync_boot_mode(task) self._set_boot_device(task, boot_devices.CDROM) LOG.debug("Node %(node)s is set to one time boot from " "%(device)s", { 'node': task.node.uuid, 'device': boot_devices.CDROM })
def prepare_ramdisk(self, task, ramdisk_params): """Prepares the boot of deploy or rescue ramdisk over virtual media. This method prepares the boot of the deploy or rescue ramdisk after reading relevant information from the node's driver_info and instance_info. :param task: A task from TaskManager. :param ramdisk_params: the parameters to be passed to the ramdisk. :returns: None :raises: MissingParameterValue, if some information is missing in node's driver_info or instance_info. :raises: InvalidParameterValue, if some information provided is invalid. :raises: IronicException, if some power or set boot boot device operation failed on the node. """ node = task.node # NOTE(TheJulia): If this method is being called by something # aside from deployment, clean and rescue, such as conductor takeover, # we should treat this as a no-op and move on otherwise we would # modify the state of the node due to virtual media operations. if node.provision_state not in (states.DEPLOYING, states.CLEANING, states.RESCUING, states.INSPECTING): return d_info = _parse_driver_info(node) managers = redfish_utils.get_system(task.node).managers if manager_utils.is_fast_track(task): if _has_vmedia_device(managers, sushy.VIRTUAL_MEDIA_CD, inserted=True): LOG.debug( 'Fast track operation for node %s, not inserting ' 'any devices', node.uuid) return else: LOG.warning( 'Fast track is possible for node %s, but no ISO ' 'is currently inserted! Proceeding with ' 'normal operation.', node.uuid) # NOTE(TheJulia): Since we're deploying, cleaning, or rescuing, # with virtual media boot, we should generate a token! # However, we don't have a way to inject it with a pre-built ISO # if a removable disk is not used. can_config = d_info.pop('can_provide_config', True) if can_config: manager_utils.add_secret_token(node, pregenerated=True) node.save() ramdisk_params['ipa-agent-token'] = \ node.driver_internal_info['agent_secret_token'] manager_utils.node_power_action(task, states.POWER_OFF) deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task) if deploy_nic_mac is not None: ramdisk_params['BOOTIF'] = deploy_nic_mac if CONF.debug and 'ipa-debug' not in ramdisk_params: ramdisk_params['ipa-debug'] = '1' # NOTE(TheJulia): This is a mandatory setting for virtual media # based deployment operations. ramdisk_params['boot_method'] = 'vmedia' config_via_removable = d_info.get('config_via_removable') if config_via_removable: removable = _has_vmedia_device( managers, # Prefer USB devices since floppies are outdated [sushy.VIRTUAL_MEDIA_USBSTICK, sushy.VIRTUAL_MEDIA_FLOPPY]) if removable: floppy_ref = image_utils.prepare_floppy_image( task, params=ramdisk_params) _eject_vmedia(task, managers, removable) _insert_vmedia(task, managers, floppy_ref, removable) LOG.info( 'Inserted virtual %(type)s device with configuration' ' for node %(node)s', { 'node': task.node.uuid, 'type': removable }) else: LOG.warning( 'Config via a removable device is requested, but ' 'virtual USB and floppy devices are not ' 'available on node %(node)s', {'node': task.node.uuid}) mode = deploy_utils.rescue_or_deploy_mode(node) iso_ref = image_utils.prepare_deploy_iso(task, ramdisk_params, mode, d_info) _eject_vmedia(task, managers, sushy.VIRTUAL_MEDIA_CD) _insert_vmedia(task, managers, iso_ref, sushy.VIRTUAL_MEDIA_CD) del managers boot_mode_utils.sync_boot_mode(task) self._set_boot_device(task, boot_devices.CDROM) LOG.debug("Node %(node)s is set to one time boot from " "%(device)s", { 'node': task.node.uuid, 'device': boot_devices.CDROM })
def prepare_ramdisk(self, task, ramdisk_params): """Prepares the boot of deploy ramdisk using virtual media. This method prepares the boot of the deploy or rescue ramdisk after reading relevant information from the node's driver_info and instance_info. :param task: a task from TaskManager. :param ramdisk_params: the parameters to be passed to the ramdisk. :returns: None :raises: MissingParameterValue, if some information is missing in node's driver_info or instance_info. :raises: InvalidParameterValue, if some information provided is invalid. :raises: IronicException, if some power or set boot boot device operation failed on the node. :raises: IloOperationError, if some operation on iLO failed. """ node = task.node # NOTE(TheJulia): If this method is being called by something # aside from deployment, clean and rescue, such as conductor takeover, # we should treat this as a no-op and move on otherwise we would # modify the state of the node due to virtual media operations. if node.provision_state not in (states.DEPLOYING, states.CLEANING, states.RESCUING, states.INSPECTING): return prepare_node_for_deploy(task) # Clear ilo_boot_iso if it's a glance image to force recreate # another one again (or use existing one in glance). # This is mainly for rebuild and rescue scenario. if service_utils.is_glance_image( node.instance_info.get('image_source')): instance_info = node.instance_info instance_info.pop('ilo_boot_iso', None) node.instance_info = instance_info node.save() # Eject all virtual media devices, as we are going to use them # during boot. ilo_common.eject_vmedia_devices(task) # NOTE(TheJulia): Since we're deploying, cleaning, or rescuing, # with virtual media boot, we should generate a token! manager_utils.add_secret_token(task.node, pregenerated=True) ramdisk_params['ipa-agent-token'] = \ task.node.driver_internal_info['agent_secret_token'] task.node.save() deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task) if deploy_nic_mac is not None: ramdisk_params['BOOTIF'] = deploy_nic_mac if (node.driver_info.get('ilo_rescue_iso') and node.provision_state == states.RESCUING): iso = node.driver_info['ilo_rescue_iso'] ilo_common.setup_vmedia(task, iso, ramdisk_params) elif node.driver_info.get('ilo_deploy_iso'): iso = node.driver_info['ilo_deploy_iso'] ilo_common.setup_vmedia(task, iso, ramdisk_params) else: mode = deploy_utils.rescue_or_deploy_mode(node) d_info = parse_driver_info(node, mode) iso = image_utils.prepare_deploy_iso(task, ramdisk_params, mode, d_info) ilo_common.setup_vmedia(task, iso)