Example #1
0
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.

        Generates the TFTP configuration for PXE-booting both the deployment
        and user images, fetches the TFTP image from Glance and add it to the
        local cache.

        :param task: a TaskManager instance containing the node to act on.
        """
        node = task.node
        # TODO(deva): optimize this if rerun on existing files
        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(
                CONF.pxe.http_root,
                os.path.basename(CONF.pxe.ipxe_boot_script))
            shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)
        pxe_info = _get_image_info(node, task.context)
        pxe_options = _build_pxe_config_options(node, pxe_info, task.context)

        if deploy_utils.get_boot_mode_for_deploy(node) == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = CONF.pxe.pxe_config_template

        pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)

        # FIXME(lucasagomes): If it's local boot we should not cache
        # the image kernel and ramdisk (Or even require it).
        _cache_ramdisk_kernel(task.context, node, pxe_info)

        # NOTE(deva): prepare may be called from conductor._do_takeover
        # in which case, it may need to regenerate the PXE config file for an
        # already-active deployment.
        if node.provision_state == states.ACTIVE:
            # this should have been stashed when the deploy was done
            # but let's guard, just in case it's missing
            iwdi = node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = (
                    node.driver_internal_info['root_uuid_or_disk_id'])
            except KeyError:
                if not iwdi:
                    LOG.warn(
                        _LW("The UUID for the root partition can't be "
                            "found, unable to switch the pxe config from "
                            "deployment mode to service (boot) mode for node "
                            "%(node)s"), {"node": node.uuid})
                else:
                    LOG.warn(
                        _LW("The disk id for the whole disk image can't "
                            "be found, unable to switch the pxe config from "
                            "deployment mode to service (boot) mode for "
                            "node %(node)s"), {"node": node.uuid})
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
                deploy_utils.switch_pxe_config(
                    pxe_config_path, root_uuid_or_disk_id,
                    deploy_utils.get_boot_mode_for_deploy(node), iwdi,
                    deploy_utils.is_trusted_boot_requested(node))
Example #2
0
    def test_create_pxe_config_uefi_ipxe(self, ensure_tree_mock, render_mock,
                                         write_mock, link_mac_pxe_mock,
                                         chmod_mock):
        self.config(ipxe_enabled=True, group='pxe')
        ipxe_template = "ironic/drivers/modules/ipxe_config.template"
        with task_manager.acquire(self.context, self.node.uuid) as task:
            task.node.properties['capabilities'] = 'boot_mode:uefi'
            pxe_utils.create_pxe_config(task, self.ipxe_options,
                                        ipxe_template)

            ensure_calls = [
                mock.call(os.path.join(CONF.deploy.http_root, self.node.uuid)),
                mock.call(os.path.join(CONF.deploy.http_root, 'pxelinux.cfg')),
            ]
            ensure_tree_mock.assert_has_calls(ensure_calls)
            chmod_mock.assert_not_called()
            render_mock.assert_called_with(
                ipxe_template,
                {'pxe_options': self.ipxe_options,
                 'ROOT': '{{ ROOT }}',
                 'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'})
            link_mac_pxe_mock.assert_called_once_with(task)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path,
                                      render_mock.return_value)
Example #3
0
def _prepare_pxe_boot(task):
    """Prepare the files required for PXE booting the agent."""
    pxe_info = _get_tftp_image_info(task.node)
    pxe_options = _build_pxe_config_options(task, pxe_info)
    pxe_utils.create_pxe_config(task, pxe_options,
                                CONF.fuel.pxe_config_template)
    _cache_tftp_images(task.context, task.node, pxe_info)
Example #4
0
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.

        Generates the TFTP configuration for PXE-booting both the deployment
        and user images, fetches the TFTP image from Glance and add it to the
        local cache.

        :param task: a TaskManager instance containing the node to act on.
        """
        # TODO(deva): optimize this if rerun on existing files
        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(CONF.pxe.http_root,
                                   os.path.basename(CONF.pxe.ipxe_boot_script))
            shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)
        pxe_info = _get_image_info(task.node, task.context)
        pxe_options = _build_pxe_config_options(task.node, pxe_info,
                                                task.context)

        if driver_utils.get_node_capability(task.node, 'boot_mode') == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = CONF.pxe.pxe_config_template

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template)
        _cache_ramdisk_kernel(task.context, task.node, pxe_info)
Example #5
0
    def _prepare_instance_pxe_config(self,
                                     task,
                                     image_info,
                                     iscsi_boot=False,
                                     ramdisk_boot=False):
        """Prepares the config file for PXE boot

        :param task: a task from TaskManager.
        :param image_info: a dict of values of instance image
            metadata to set on the configuration file.
        :param iscsi_boot: if boot is from an iSCSI volume or not.
        :param ramdisk_boot: if the boot is to a ramdisk configuration.
        :returns: None
        """

        node = task.node
        dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)
        pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
        if not os.path.isfile(pxe_config_path):
            pxe_options = _build_pxe_config_options(task,
                                                    image_info,
                                                    service=ramdisk_boot)
            pxe_config_template = (deploy_utils.get_pxe_config_template(node))
            pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)
        deploy_utils.switch_pxe_config(
            pxe_config_path,
            None,
            boot_mode_utils.get_boot_mode_for_deploy(node),
            False,
            iscsi_boot=iscsi_boot,
            ramdisk_boot=ramdisk_boot)
Example #6
0
    def test_create_pxe_config_set_dir_permission(self, ensure_tree_mock,
                                                  render_mock, write_mock,
                                                  chmod_mock):
        self.config(dir_permission=0o755, group='pxe')
        with task_manager.acquire(self.context, self.node.uuid) as task:
            pxe_utils.create_pxe_config(task, self.pxe_options,
                                        CONF.pxe.pxe_config_template)
            render_mock.assert_called_with(
                CONF.pxe.pxe_config_template, {
                    'pxe_options': self.pxe_options,
                    'ROOT': '{{ ROOT }}',
                    'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'
                })
        node_dir = os.path.join(CONF.pxe.tftp_root, self.node.uuid)
        pxe_dir = os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg')
        ensure_calls = [
            mock.call(node_dir),
            mock.call(pxe_dir),
        ]
        ensure_tree_mock.assert_has_calls(ensure_calls)
        chmod_calls = [mock.call(node_dir, 0o755), mock.call(pxe_dir, 0o755)]
        chmod_mock.assert_has_calls(chmod_calls)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path,
                                      render_mock.return_value)
Example #7
0
    def test_create_pxe_config_uefi_grub(self, ensure_tree_mock, render_mock,
                                         write_mock, link_ip_configs_mock,
                                         chmod_mock):
        grub_tmplte = "ironic/drivers/modules/pxe_grub_config.template"
        with task_manager.acquire(self.context, self.node.uuid) as task:
            task.node.properties['capabilities'] = 'boot_mode:uefi'
            pxe_utils.create_pxe_config(task, self.pxe_options, grub_tmplte)

            ensure_calls = [
                mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
                mock.call(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg')),
            ]
            ensure_tree_mock.assert_has_calls(ensure_calls)
            chmod_mock.assert_not_called()
            render_mock.assert_called_with(
                grub_tmplte, {
                    'pxe_options': self.pxe_options,
                    'ROOT': '(( ROOT ))',
                    'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'
                })
            link_ip_configs_mock.assert_called_once_with(task, False)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path,
                                      render_mock.return_value)
Example #8
0
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.

        Generates the TFTP configuration for PXE-booting both the deployment
        and user images, fetches the TFTP image from Glance and add it to the
        local cache.

        :param task: a TaskManager instance containing the node to act on.
        """
        # TODO(deva): optimize this if rerun on existing files
        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(
                CONF.pxe.http_root,
                os.path.basename(CONF.pxe.ipxe_boot_script))
            shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)
        pxe_info = _get_image_info(task.node, task.context)
        pxe_options = _build_pxe_config_options(task.node, pxe_info,
                                                task.context)

        if driver_utils.get_node_capability(task.node, 'boot_mode') == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = CONF.pxe.pxe_config_template

        pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)
        _cache_ramdisk_kernel(task.context, task.node, pxe_info)
Example #9
0
    def test_create_pxe_config_uefi_grub(self, ensure_tree_mock, render_mock,
                                         write_mock, link_ip_configs_mock,
                                         chmod_mock):
        grub_tmplte = "ironic/drivers/modules/pxe_grub_config.template"
        with task_manager.acquire(self.context, self.node.uuid) as task:
            task.node.properties['capabilities'] = 'boot_mode:uefi'
            pxe_utils.create_pxe_config(task, self.pxe_options,
                                        grub_tmplte)

            ensure_calls = [
                mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
                mock.call(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg')),
            ]
            ensure_tree_mock.assert_has_calls(ensure_calls)
            chmod_mock.assert_not_called()
            render_mock.assert_called_with(
                grub_tmplte,
                {'pxe_options': self.pxe_options,
                 'ROOT': '(( ROOT ))',
                 'DISK_IDENTIFIER': '(( DISK_IDENTIFIER ))'})
            link_ip_configs_mock.assert_called_once_with(task, False)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path,
                                      render_mock.return_value)
Example #10
0
    def test_create_pxe_config_set_dir_permission(self, ensure_tree_mock,
                                                  render_mock,
                                                  write_mock, chmod_mock):
        self.config(dir_permission=0o755, group='pxe')
        with task_manager.acquire(self.context, self.node.uuid) as task:
            pxe_utils.create_pxe_config(task, self.pxe_options,
                                        CONF.pxe.pxe_config_template)
            render_mock.assert_called_with(
                CONF.pxe.pxe_config_template,
                {'pxe_options': self.pxe_options,
                 'ROOT': '{{ ROOT }}',
                 'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'}
            )
        node_dir = os.path.join(CONF.pxe.tftp_root, self.node.uuid)
        pxe_dir = os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg')
        ensure_calls = [
            mock.call(node_dir), mock.call(pxe_dir),
        ]
        ensure_tree_mock.assert_has_calls(ensure_calls)
        chmod_calls = [mock.call(node_dir, 0o755), mock.call(pxe_dir, 0o755)]
        chmod_mock.assert_has_calls(chmod_calls)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path,
                                      render_mock.return_value)
Example #11
0
    def test_create_pxe_config_uefi_elilo(self, ensure_tree_mock, render_mock,
                                          write_mock, link_ip_configs_mock):
        self.config(uefi_pxe_config_template=('ironic/drivers/modules/'
                                              'elilo_efi_pxe_config.template'),
                    group='pxe')
        with task_manager.acquire(self.context, self.node.uuid) as task:
            task.node.properties['capabilities'] = 'boot_mode:uefi'
            pxe_utils.create_pxe_config(task, self.pxe_options,
                                        CONF.pxe.uefi_pxe_config_template)

            ensure_calls = [
                mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
                mock.call(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg'))
            ]
            ensure_tree_mock.assert_has_calls(ensure_calls)
            render_mock.assert_called_with(
                CONF.pxe.uefi_pxe_config_template, {
                    'pxe_options': self.pxe_options,
                    'ROOT': '{{ ROOT }}',
                    'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'
                })
            link_ip_configs_mock.assert_called_once_with(task, True)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path,
                                      render_mock.return_value)
Example #12
0
    def test_create_pxe_config_uefi_ipxe(self, ensure_tree_mock, render_mock,
                                         write_mock, link_mac_pxe_mock,
                                         chmod_mock):
        self.config(ipxe_enabled=True, group='pxe')
        ipxe_template = "ironic/drivers/modules/ipxe_config.template"
        with task_manager.acquire(self.context, self.node.uuid) as task:
            task.node.properties['capabilities'] = 'boot_mode:uefi'
            pxe_utils.create_pxe_config(task, self.ipxe_options, ipxe_template)

            ensure_calls = [
                mock.call(os.path.join(CONF.deploy.http_root, self.node.uuid)),
                mock.call(os.path.join(CONF.deploy.http_root, 'pxelinux.cfg')),
            ]
            ensure_tree_mock.assert_has_calls(ensure_calls)
            chmod_mock.assert_not_called()
            render_mock.assert_called_with(
                ipxe_template, {
                    'pxe_options': self.ipxe_options,
                    'ROOT': '{{ ROOT }}',
                    'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'
                })
            link_mac_pxe_mock.assert_called_once_with(task)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path,
                                      render_mock.return_value)
Example #13
0
File: pxe.py Project: uggla/ironic
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.

        Generates the TFTP configuration for PXE-booting both the deployment
        and user images, fetches the TFTP image from Glance and add it to the
        local cache.

        :param task: a TaskManager instance containing the node to act on.
        """
        node = task.node
        # TODO(deva): optimize this if rerun on existing files
        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(CONF.pxe.http_root,
                                   os.path.basename(CONF.pxe.ipxe_boot_script))
            shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)
        pxe_info = _get_image_info(node, task.context)
        pxe_options = _build_pxe_config_options(node, pxe_info,
                                                task.context)

        if deploy_utils.get_boot_mode_for_deploy(node) == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = CONF.pxe.pxe_config_template

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template)

        # FIXME(lucasagomes): If it's local boot we should not cache
        # the image kernel and ramdisk (Or even require it).
        _cache_ramdisk_kernel(task.context, node, pxe_info)

        # NOTE(deva): prepare may be called from conductor._do_takeover
        # in which case, it may need to regenerate the PXE config file for an
        # already-active deployment.
        if node.provision_state == states.ACTIVE:
            # this should have been stashed when the deploy was done
            # but let's guard, just in case it's missing
            iwdi = node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = node.driver_internal_info[
                                                'root_uuid_or_disk_id']
            except KeyError:
                if not iwdi:
                    LOG.warn(_LW("The UUID for the root partition can't be "
                             "found, unable to switch the pxe config from "
                             "deployment mode to service (boot) mode for node "
                             "%(node)s"), {"node": node.uuid})
                else:
                    LOG.warn(_LW("The disk id for the whole disk image can't "
                             "be found, unable to switch the pxe config from "
                             "deployment mode to service (boot) mode for "
                             "node %(node)s"), {"node": node.uuid})
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(
                    node.uuid)
                deploy_utils.switch_pxe_config(
                    pxe_config_path, root_uuid_or_disk_id,
                    deploy_utils.get_boot_mode_for_deploy(node),
                    iwdi)
def _prepare_pxe_boot(task):
    """Prepare the files required for PXE booting the agent."""
    pxe_info = _get_tftp_image_info(task.node)
    pxe_options = _build_pxe_config_options(task, pxe_info)
    pxe_utils.create_pxe_config(task,
                                pxe_options,
                                CONF.fuel.pxe_config_template)
    _cache_tftp_images(task.context, task.node, pxe_info)
Example #15
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy kernel/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.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :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

        if CONF.pxe.ipxe_enabled:
            # NOTE(mjturek): At this point, the ipxe boot script should
            # already exist as it is created at startup time. However, we
            # call the boot script create method here to assert its
            # existence and handle the unlikely case that it wasn't created
            # or was deleted.
            pxe_utils.create_ipxe_boot_script()

        dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = _get_deploy_image_info(node)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(_get_instance_image_info(node, task.context))

        pxe_options = _build_pxe_config_options(task, pxe_info)
        pxe_options.update(ramdisk_params)

        pxe_config_template = deploy_utils.get_pxe_config_template(node)

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template)
        persistent = strutils.bool_from_string(
            node.driver_info.get('force_persistent_boot_device',
                                 False))
        manager_utils.node_set_boot_device(task, boot_devices.PXE,
                                           persistent=persistent)

        if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
            pxe_info.pop('deploy_kernel', None)
            pxe_info.pop('deploy_ramdisk', None)
        if pxe_info:
            _cache_ramdisk_kernel(task.context, node, pxe_info)
Example #16
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy kernel/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.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :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

        if CONF.pxe.ipxe_enabled:
            # NOTE(mjturek): At this point, the ipxe boot script should
            # already exist as it is created at startup time. However, we
            # call the boot script create method here to assert its
            # existence and handle the unlikely case that it wasn't created
            # or was deleted.
            pxe_utils.create_ipxe_boot_script()

        dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = _get_deploy_image_info(node)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(_get_instance_image_info(node, task.context))

        pxe_options = _build_pxe_config_options(task, pxe_info)
        pxe_options.update(ramdisk_params)

        pxe_config_template = deploy_utils.get_pxe_config_template(node)

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template)
        persistent = strutils.bool_from_string(
            node.driver_info.get('force_persistent_boot_device',
                                 False))
        manager_utils.node_set_boot_device(task, boot_devices.PXE,
                                           persistent=persistent)

        if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
            pxe_info.pop('deploy_kernel', None)
            pxe_info.pop('deploy_ramdisk', None)
        if pxe_info:
            _cache_ramdisk_kernel(task.context, node, pxe_info)
Example #17
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy kernel/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.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :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

        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(
                CONF.deploy.http_root,
                os.path.basename(CONF.pxe.ipxe_boot_script))
            if (not os.path.isfile(bootfile_path) or
                    not filecmp.cmp(CONF.pxe.ipxe_boot_script, bootfile_path)):
                shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)

        dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = _get_deploy_image_info(node)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(_get_instance_image_info(node, task.context))

        pxe_options = _build_pxe_config_options(task, pxe_info)
        pxe_options.update(ramdisk_params)

        if deploy_utils.get_boot_mode_for_deploy(node) == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = CONF.pxe.pxe_config_template

        pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)
        deploy_utils.try_set_boot_device(task, boot_devices.PXE)

        if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
            pxe_info.pop('deploy_kernel', None)
            pxe_info.pop('deploy_ramdisk', None)
        if pxe_info:
            _cache_ramdisk_kernel(task.context, node, pxe_info)
Example #18
0
File: pxe.py Project: naterh/ironic
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy kernel/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.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :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

        # TODO(deva): optimize this if rerun on existing files
        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(
                CONF.deploy.http_root,
                os.path.basename(CONF.pxe.ipxe_boot_script))
            shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)

        dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = _get_deploy_image_info(node)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(_get_instance_image_info(node, task.context))

        pxe_options = _build_pxe_config_options(task, pxe_info)
        pxe_options.update(ramdisk_params)

        if deploy_utils.get_boot_mode_for_deploy(node) == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = _get_pxe_conf_option(task,
                                                       'pxe_config_template')

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template)
        deploy_utils.try_set_boot_device(task, boot_devices.PXE)

        # FIXME(lucasagomes): If it's local boot we should not cache
        # the image kernel and ramdisk (Or even require it).
        _cache_ramdisk_kernel(task.context, node, pxe_info)
Example #19
0
    def test_create_pxe_config(self, ensure_tree_mock, build_mock, write_mock):
        build_mock.return_value = self.pxe_options
        with task_manager.acquire(self.context, self.node.uuid) as task:
            pxe_utils.create_pxe_config(task, self.pxe_options, CONF.pxe.pxe_config_template)
            build_mock.assert_called_with(self.pxe_options, CONF.pxe.pxe_config_template)
        ensure_calls = [
            mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
            mock.call(os.path.join(CONF.pxe.tftp_root, "pxelinux.cfg")),
        ]
        ensure_tree_mock.has_calls(ensure_calls)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path, self.pxe_options)
Example #20
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        """
        node = task.node
        pxe_info = _get_tftp_image_info(task.node)
        pxe_options = _build_pxe_config_options(task.node, pxe_info)
        pxe_utils.create_pxe_config(task, pxe_options, CONF.agent.agent_pxe_config_template)
        _cache_tftp_images(task.context, node, pxe_info)

        node.instance_info = build_instance_info_for_deploy(task)
        node.save()
Example #21
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        """
        node = task.node
        pxe_info = _get_tftp_image_info(task.node)
        pxe_options = _build_pxe_config_options(pxe_info)
        pxe_utils.create_pxe_config(task, pxe_options,
                                    CONF.agent.agent_pxe_config_template)
        _cache_tftp_images(task.context, node, pxe_info)

        node.instance_info = build_instance_info_for_deploy(task)
        node.save(task.context)
Example #22
0
    def test_create_pxe_config(self, ensure_tree_mock, build_mock, write_mock):
        build_mock.return_value = self.pxe_options
        with task_manager.acquire(self.context, self.node.uuid) as task:
            pxe_utils.create_pxe_config(task, self.pxe_options,
                                        CONF.pxe.pxe_config_template)
            build_mock.assert_called_with(self.pxe_options,
                                          CONF.pxe.pxe_config_template)
        ensure_calls = [
            mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
            mock.call(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg'))
        ]
        ensure_tree_mock.assert_has_calls(ensure_calls)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path, self.pxe_options)
Example #23
0
File: pxe.py Project: n1zyy/ironic
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.

        Generates the TFTP configuration for PXE-booting both the deployment
        and user images, fetches the TFTP image from Glance and add it to the
        local cache.

        :param task: a TaskManager instance containing the node to act on.
        """
        # TODO(deva): optimize this if rerun on existing files
        pxe_info = _get_tftp_image_info(task.node, task.context)
        pxe_options = _build_pxe_config_options(task.node, pxe_info,
                                                task.context)
        pxe_utils.create_pxe_config(task, pxe_options,
                                    CONF.pxe.pxe_config_template)
        _cache_tftp_images(task.context, task.node, pxe_info)
Example #24
0
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.

        Generates the TFTP configuration for PXE-booting both the deployment
        and user images, fetches the TFTP image from Glance and add it to the
        local cache.

        :param task: a TaskManager instance containing the node to act on.
        """
        # TODO(deva): optimize this if rerun on existing files
        pxe_info = _get_tftp_image_info(task.node, task.context)
        pxe_options = _build_pxe_config_options(task.node, pxe_info,
                                                task.context)
        pxe_utils.create_pxe_config(task, pxe_options,
                                    CONF.pxe.pxe_config_template)
        _cache_tftp_images(task.context, task.node, pxe_info)
Example #25
0
    def _prepare_pxe_boot(self, task):
        """Prepare the files required for PXE booting the agent."""
        pxe_info = self._get_tftp_image_info(task.node)

        # Do live boot if squashfs is specified in either way.
        is_live_boot = (task.node.driver_info.get('deploy_squashfs') or
                        CONF.bareon.deploy_squashfs)
        pxe_options = self._build_pxe_config_options(task, pxe_info,
                                                     is_live_boot)
        template = (CONF.bareon.pxe_config_template_live if is_live_boot
                    else CONF.bareon.pxe_config_template)
        pxe_utils.create_pxe_config(task,
                                    pxe_options,
                                    template)

        self._cache_tftp_images(task.context, task.node, pxe_info)
Example #26
0
def _build_service_pxe_config(task, instance_image_info, root_uuid_or_disk_id):
    node = task.node
    pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
    # NOTE(pas-ha) if it is takeover of ACTIVE node,
    # first ensure that basic PXE configs and links
    # are in place before switching pxe config
    if (node.provision_state == states.ACTIVE
            and not os.path.isfile(pxe_config_path)):
        pxe_options = _build_pxe_config_options(task,
                                                instance_image_info,
                                                service=True)
        pxe_config_template = deploy_utils.get_pxe_config_template(node)
        pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    deploy_utils.switch_pxe_config(
        pxe_config_path, root_uuid_or_disk_id,
        deploy_utils.get_boot_mode_for_deploy(node), iwdi,
        deploy_utils.is_trusted_boot_requested(node))
Example #27
0
def _build_service_pxe_config(task, instance_image_info,
                              root_uuid_or_disk_id):
    node = task.node
    pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
    # NOTE(pas-ha) if it is takeover of ACTIVE node,
    # first ensure that basic PXE configs and links
    # are in place before switching pxe config
    if (node.provision_state == states.ACTIVE and
            not os.path.isfile(pxe_config_path)):
        pxe_options = _build_pxe_config_options(task, instance_image_info,
                                                service=True)
        pxe_config_template = deploy_utils.get_pxe_config_template(node)
        pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    deploy_utils.switch_pxe_config(
        pxe_config_path, root_uuid_or_disk_id,
        deploy_utils.get_boot_mode_for_deploy(node),
        iwdi, deploy_utils.is_trusted_boot_requested(node),
        deploy_utils.is_iscsi_boot(task))
Example #28
0
 def test_create_pxe_config_existing_dirs(self, ensure_tree_mock,
                                          render_mock, write_mock,
                                          chmod_mock, isdir_mock):
     self.config(dir_permission=0o755, group='pxe')
     with task_manager.acquire(self.context, self.node.uuid) as task:
         isdir_mock.return_value = True
         pxe_utils.create_pxe_config(task, self.pxe_options,
                                     CONF.pxe.pxe_config_template)
         render_mock.assert_called_with(
             CONF.pxe.pxe_config_template, {
                 'pxe_options': self.pxe_options,
                 'ROOT': '{{ ROOT }}',
                 'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'
             })
     ensure_tree_mock.assert_has_calls([])
     chmod_mock.assert_not_called()
     isdir_mock.assert_has_calls([])
     pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
     write_mock.assert_called_with(pxe_cfg_file_path,
                                   render_mock.return_value)
Example #29
0
    def test_create_pxe_config(self, ensure_tree_mock, render_mock,
                               write_mock):
        with task_manager.acquire(self.context, self.node.uuid) as task:
            pxe_utils.create_pxe_config(task, self.pxe_options,
                                        CONF.pxe.pxe_config_template)
            render_mock.assert_called_with(
                CONF.pxe.pxe_config_template, {
                    'pxe_options': self.pxe_options,
                    'ROOT': '{{ ROOT }}',
                    'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'
                })
        ensure_calls = [
            mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
            mock.call(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg'))
        ]
        ensure_tree_mock.assert_has_calls(ensure_calls)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path,
                                      render_mock.return_value)
Example #30
0
    def test_create_pxe_config_uefi_elilo(self, ensure_tree_mock, build_mock,
                                          write_mock, link_ip_configs_mock):
        build_mock.return_value = self.pxe_options_uefi
        with task_manager.acquire(self.context, self.node.uuid) as task:
            task.node.properties['capabilities'] = 'boot_mode:uefi'
            pxe_utils.create_pxe_config(task, self.pxe_options_uefi,
                                        CONF.pxe.uefi_pxe_config_template)

            ensure_calls = [
                mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
                mock.call(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg'))
            ]
            ensure_tree_mock.assert_has_calls(ensure_calls)
            build_mock.assert_called_with(self.pxe_options_uefi,
                                          CONF.pxe.uefi_pxe_config_template,
                                          '{{ ROOT }}',
                                          '{{ DISK_IDENTIFIER }}')
            link_ip_configs_mock.assert_called_once_with(task, True)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path, self.pxe_options_uefi)
Example #31
0
 def test_create_pxe_config_existing_dirs(self, ensure_tree_mock,
                                          render_mock,
                                          write_mock, chmod_mock,
                                          isdir_mock):
     self.config(dir_permission=0o755, group='pxe')
     with task_manager.acquire(self.context, self.node.uuid) as task:
         isdir_mock.return_value = True
         pxe_utils.create_pxe_config(task, self.pxe_options,
                                     CONF.pxe.pxe_config_template)
         render_mock.assert_called_with(
             CONF.pxe.pxe_config_template,
             {'pxe_options': self.pxe_options,
              'ROOT': '{{ ROOT }}',
              'DISK_IDENTIFIER': '{{ DISK_IDENTIFIER }}'}
         )
     ensure_tree_mock.assert_has_calls([])
     chmod_mock.assert_not_called()
     isdir_mock.assert_has_calls([])
     pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
     write_mock.assert_called_with(pxe_cfg_file_path,
                                   render_mock.return_value)
Example #32
0
    def test_create_pxe_config_uefi_elilo(self, ensure_tree_mock, build_mock,
                                          write_mock, link_ip_configs_mock):
        build_mock.return_value = self.pxe_options_uefi
        with task_manager.acquire(self.context, self.node.uuid) as task:
            task.node.properties['capabilities'] = 'boot_mode:uefi'
            pxe_utils.create_pxe_config(task, self.pxe_options_uefi,
                                        CONF.pxe.uefi_pxe_config_template)

            ensure_calls = [
                mock.call(os.path.join(CONF.pxe.tftp_root, self.node.uuid)),
                mock.call(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg'))
            ]
            ensure_tree_mock.assert_has_calls(ensure_calls)
            build_mock.assert_called_with(self.pxe_options_uefi,
                                          CONF.pxe.uefi_pxe_config_template,
                                          '{{ ROOT }}',
                                          '{{ DISK_IDENTIFIER }}')
            link_ip_configs_mock.assert_called_once_with(task, True)

        pxe_cfg_file_path = pxe_utils.get_pxe_config_file_path(self.node.uuid)
        write_mock.assert_called_with(pxe_cfg_file_path, self.pxe_options_uefi)
Example #33
0
    def prepare_ramdisk(self, task, ramdisk_params):
        node = task.node

        # TODO(deva): optimize this if rerun on existing files
        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(
                CONF.deploy.http_root,
                os.path.basename(CONF.pxe.ipxe_boot_script))
            shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)

        prov_ip = self._plug_provisioning(task)

        task.ports = objects.Port.list_by_node_id(task.context, node.id)

        pxe_info = pxe._get_deploy_image_info(node)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(pxe._get_instance_image_info(node, task.context))

        pxe_options = pxe._build_pxe_config_options(task, pxe_info)
        pxe_options.update(ramdisk_params)
        pxe_options['advertise_host'] = prov_ip

        if deploy_utils.get_boot_mode_for_deploy(node) == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = CONF.pxe.pxe_config_template

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template)
        deploy_utils.try_set_boot_device(task, boot_devices.PXE)

        # FIXME(lucasagomes): If it's local boot we should not cache
        # the image kernel and ramdisk (Or even require it).
        pxe._cache_ramdisk_kernel(task.context, node, pxe_info)
Example #34
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy or rescue kernel/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.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :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

        # Label indicating a deploy or rescue operation being carried out on
        # the node, 'deploy' or 'rescue'. Unless the node is in a rescue like
        # state, the mode is set to 'deploy', indicating deploy operation is
        # being carried out.
        mode = deploy_utils.rescue_or_deploy_mode(node)

        # NOTE(mjturek): At this point, the ipxe boot script should
        # already exist as it is created at startup time. However, we
        # call the boot script create method here to assert its
        # existence and handle the unlikely case that it wasn't created
        # or was deleted.
        pxe_utils.create_ipxe_boot_script()

        dhcp_opts = pxe_utils.dhcp_options_for_instance(task,
                                                        ipxe_enabled=True)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = pxe_utils.get_image_info(node, mode=mode, ipxe_enabled=True)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(
                pxe_utils.get_instance_image_info(task, ipxe_enabled=True))
            boot_mode_utils.sync_boot_mode(task)

        pxe_options = pxe_utils.build_pxe_config_options(task,
                                                         pxe_info,
                                                         ipxe_enabled=True)
        pxe_options.update(ramdisk_params)

        pxe_config_template = deploy_utils.get_pxe_config_template(node)

        pxe_utils.create_pxe_config(task,
                                    pxe_options,
                                    pxe_config_template,
                                    ipxe_enabled=True)
        persistent = False
        value = node.driver_info.get('force_persistent_boot_device', 'Default')
        if value in {'Always', 'Default', 'Never'}:
            if value == 'Always':
                persistent = True
        else:
            persistent = strutils.bool_from_string(value, False)
        manager_utils.node_set_boot_device(task,
                                           boot_devices.PXE,
                                           persistent=persistent)

        if CONF.pxe.ipxe_use_swift:
            kernel_label = '%s_kernel' % mode
            ramdisk_label = '%s_ramdisk' % mode
            pxe_info.pop(kernel_label, None)
            pxe_info.pop(ramdisk_label, None)

        if pxe_info:
            pxe_utils.cache_ramdisk_kernel(task, pxe_info, ipxe_enabled=True)
Example #35
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy kernel/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.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :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

        if CONF.pxe.ipxe_enabled:
            # Render the iPXE boot script template and save it
            # to HTTP root directory
            boot_script = utils.render_template(
                CONF.pxe.ipxe_boot_script,
                {'ipxe_for_mac_uri': pxe_utils.PXE_CFG_DIR_NAME + '/'})
            bootfile_path = os.path.join(
                CONF.deploy.http_root,
                os.path.basename(CONF.pxe.ipxe_boot_script))
            # NOTE(pas-ha) to prevent unneeded writes,
            # only write to file if its content is different from required,
            # which should be rather rare
            if (not os.path.isfile(bootfile_path) or
                not utils.file_has_content(bootfile_path, boot_script)):
                    utils.write_to_file(bootfile_path, boot_script)

        dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = _get_deploy_image_info(node)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(_get_instance_image_info(node, task.context))

        pxe_options = _build_pxe_config_options(task, pxe_info)
        pxe_options.update(ramdisk_params)

        pxe_config_template = deploy_utils.get_pxe_config_template(node)

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template)
        deploy_utils.try_set_boot_device(task, boot_devices.PXE)

        if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
            pxe_info.pop('deploy_kernel', None)
            pxe_info.pop('deploy_ramdisk', None)
        if pxe_info:
            _cache_ramdisk_kernel(task.context, node, pxe_info)
Example #36
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy or rescue kernel/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.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :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

        # Label indicating a deploy or rescue operation being carried out on
        # the node, 'deploy' or 'rescue'. Unless the node is in a rescue like
        # state, the mode is set to 'deploy', indicating deploy operation is
        # being carried out.
        mode = deploy_utils.rescue_or_deploy_mode(node)

        # NOTE(mjturek): At this point, the ipxe boot script should
        # already exist as it is created at startup time. However, we
        # call the boot script create method here to assert its
        # existence and handle the unlikely case that it wasn't created
        # or was deleted.
        pxe_utils.create_ipxe_boot_script()

        dhcp_opts = pxe_utils.dhcp_options_for_instance(
            task, ipxe_enabled=True)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = pxe_utils.get_image_info(node, mode=mode,
                                            ipxe_enabled=True)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(
                pxe_utils.get_instance_image_info(task, ipxe_enabled=True))
            boot_mode_utils.sync_boot_mode(task)

        pxe_options = pxe_utils.build_pxe_config_options(task, pxe_info,
                                                         ipxe_enabled=True)
        pxe_options.update(ramdisk_params)

        pxe_config_template = deploy_utils.get_pxe_config_template(node)

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template,
                                    ipxe_enabled=True)
        persistent = False
        value = node.driver_info.get('force_persistent_boot_device',
                                     'Default')
        if value in {'Always', 'Default', 'Never'}:
            if value == 'Always':
                persistent = True
        else:
            persistent = strutils.bool_from_string(value, False)
        manager_utils.node_set_boot_device(task, boot_devices.PXE,
                                           persistent=persistent)

        if CONF.pxe.ipxe_use_swift:
            kernel_label = '%s_kernel' % mode
            ramdisk_label = '%s_ramdisk' % mode
            pxe_info.pop(kernel_label, None)
            pxe_info.pop(ramdisk_label, None)

        if pxe_info:
            pxe_utils.cache_ramdisk_kernel(task, pxe_info, ipxe_enabled=True)
Example #37
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of Ironic ramdisk using PXE.

        This method prepares the boot of the deploy or rescue kernel/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.
            pxe driver passes these parameters as kernel command-line
            arguments.
        :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

        # Label indicating a deploy or rescue operation being carried out on
        # the node, 'deploy' or 'rescue'. Unless the node is in a rescue like
        # state, the mode is set to 'deploy', indicating deploy operation is
        # being carried out.
        mode = deploy_utils.rescue_or_deploy_mode(node)
        ipxe_enabled = CONF.pxe.ipxe_enabled
        if ipxe_enabled:
            # NOTE(mjturek): At this point, the ipxe boot script should
            # already exist as it is created at startup time. However, we
            # call the boot script create method here to assert its
            # existence and handle the unlikely case that it wasn't created
            # or was deleted.
            pxe_utils.create_ipxe_boot_script()

        dhcp_opts = pxe_utils.dhcp_options_for_instance(
            task, ipxe_enabled=ipxe_enabled)
        provider = dhcp_factory.DHCPFactory()
        provider.update_dhcp(task, dhcp_opts)

        pxe_info = pxe_utils.get_image_info(node, mode=mode)

        # NODE: Try to validate and fetch instance images only
        # if we are in DEPLOYING state.
        if node.provision_state == states.DEPLOYING:
            pxe_info.update(pxe_utils.get_instance_image_info(task))
            boot_mode_utils.sync_boot_mode(task)

        pxe_options = pxe_utils.build_pxe_config_options(
            task,
            pxe_info,
            ipxe_enabled=ipxe_enabled,
            ramdisk_params=ramdisk_params)
        # TODO(dtantsur): backwards compability hack, remove in the V release
        if ramdisk_params.get("ipa-api-url"):
            pxe_options["ipa-api-url"] = ramdisk_params["ipa-api-url"]

        pxe_config_template = deploy_utils.get_pxe_config_template(node)

        pxe_utils.create_pxe_config(task,
                                    pxe_options,
                                    pxe_config_template,
                                    ipxe_enabled=CONF.pxe.ipxe_enabled)

        persistent = self._persistent_ramdisk_boot(node)
        manager_utils.node_set_boot_device(task,
                                           boot_devices.PXE,
                                           persistent=persistent)

        if CONF.pxe.ipxe_enabled and CONF.pxe.ipxe_use_swift:
            kernel_label = '%s_kernel' % mode
            ramdisk_label = '%s_ramdisk' % mode
            pxe_info.pop(kernel_label, None)
            pxe_info.pop(ramdisk_label, None)

        if pxe_info:
            pxe_utils.cache_ramdisk_kernel(task,
                                           pxe_info,
                                           ipxe_enabled=CONF.pxe.ipxe_enabled)
        LOG.debug(
            'Ramdisk PXE boot for node %(node)s has been prepared '
            'with kernel params %(params)s', {
                'node': node.uuid,
                'params': pxe_options
            })
Example #38
0
    def prepare_instance(self, task):
        """Prepares the boot of instance.

        This method prepares the boot of the instance after reading
        relevant information from the node's instance_info. In case of netboot,
        it updates the dhcp entries and switches the PXE config. In case of
        localboot, it cleans up the PXE config.

        :param task: a task from TaskManager.
        :returns: None
        """
        node = task.node
        boot_option = deploy_utils.get_boot_option(node)
        boot_device = None

        if deploy_utils.is_iscsi_boot(task):
            dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
            provider = dhcp_factory.DHCPFactory()
            provider.update_dhcp(task, dhcp_opts)

            # configure iPXE for iscsi boot
            pxe_config_path = pxe_utils.get_pxe_config_file_path(
                task.node.uuid)
            if not os.path.isfile(pxe_config_path):
                pxe_options = _build_pxe_config_options(task, {})
                pxe_config_template = (
                    deploy_utils.get_pxe_config_template(node))
                pxe_utils.create_pxe_config(
                    task, pxe_options, pxe_config_template)
            deploy_utils.switch_pxe_config(
                pxe_config_path, None,
                deploy_utils.get_boot_mode_for_deploy(node), False,
                iscsi_boot=True)
            boot_device = boot_devices.PXE

        elif boot_option != "local":
            if task.driver.storage.should_write_image(task):
                # Make sure that the instance kernel/ramdisk is cached.
                # This is for the takeover scenario for active nodes.
                instance_image_info = _get_instance_image_info(
                    task.node, task.context)
                _cache_ramdisk_kernel(task.context, task.node,
                                      instance_image_info)

            # If it's going to PXE boot we need to update the DHCP server
            dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
            provider = dhcp_factory.DHCPFactory()
            provider.update_dhcp(task, dhcp_opts)

            iwdi = task.node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = task.node.driver_internal_info[
                    'root_uuid_or_disk_id'
                ]
            except KeyError:
                if not task.driver.storage.should_write_image(task):
                    pass
                elif not iwdi:
                    LOG.warning("The UUID for the root partition can't be "
                                "found, unable to switch the pxe config from "
                                "deployment mode to service (boot) mode for "
                                "node %(node)s", {"node": task.node.uuid})
                else:
                    LOG.warning("The disk id for the whole disk image can't "
                                "be found, unable to switch the pxe config "
                                "from deployment mode to service (boot) mode "
                                "for node %(node)s", {"node": task.node.uuid})
            else:
                _build_service_pxe_config(task, instance_image_info,
                                          root_uuid_or_disk_id)
                boot_device = boot_devices.PXE
        else:
            # If it's going to boot from the local disk, we don't need
            # PXE config files. They still need to be generated as part
            # of the prepare() because the deployment does PXE boot the
            # deploy ramdisk
            pxe_utils.clean_up_pxe_config(task)
            boot_device = boot_devices.DISK

        # NOTE(pas-ha) do not re-set boot device on ACTIVE nodes
        # during takeover
        if boot_device and task.node.provision_state != states.ACTIVE:
            manager_utils.node_set_boot_device(task, boot_device,
                                               persistent=True)
Example #39
0
    def prepare_instance(self, task):
        """Prepares the boot of instance.

        This method prepares the boot of the instance after reading
        relevant information from the node's instance_info. In case of netboot,
        it updates the dhcp entries and switches the PXE config. In case of
        localboot, it cleans up the PXE config.

        :param task: a task from TaskManager.
        :returns: None
        """
        node = task.node
        boot_option = deploy_utils.get_boot_option(node)
        boot_device = None

        if deploy_utils.is_iscsi_boot(task):
            dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
            provider = dhcp_factory.DHCPFactory()
            provider.update_dhcp(task, dhcp_opts)

            # configure iPXE for iscsi boot
            pxe_config_path = pxe_utils.get_pxe_config_file_path(
                task.node.uuid)
            if not os.path.isfile(pxe_config_path):
                pxe_options = _build_pxe_config_options(task, {})
                pxe_config_template = (
                    deploy_utils.get_pxe_config_template(node))
                pxe_utils.create_pxe_config(
                    task, pxe_options, pxe_config_template)
            deploy_utils.switch_pxe_config(
                pxe_config_path, None,
                deploy_utils.get_boot_mode_for_deploy(node), False,
                iscsi_boot=True)
            boot_device = boot_devices.PXE

        elif boot_option != "local":
            if task.driver.storage.should_write_image(task):
                # Make sure that the instance kernel/ramdisk is cached.
                # This is for the takeover scenario for active nodes.
                instance_image_info = _get_instance_image_info(
                    task.node, task.context)
                _cache_ramdisk_kernel(task.context, task.node,
                                      instance_image_info)

            # If it's going to PXE boot we need to update the DHCP server
            dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
            provider = dhcp_factory.DHCPFactory()
            provider.update_dhcp(task, dhcp_opts)

            iwdi = task.node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = task.node.driver_internal_info[
                    'root_uuid_or_disk_id'
                ]
            except KeyError:
                if not task.driver.storage.should_write_image(task):
                    pass
                elif not iwdi:
                    LOG.warning("The UUID for the root partition can't be "
                                "found, unable to switch the pxe config from "
                                "deployment mode to service (boot) mode for "
                                "node %(node)s", {"node": task.node.uuid})
                else:
                    LOG.warning("The disk id for the whole disk image can't "
                                "be found, unable to switch the pxe config "
                                "from deployment mode to service (boot) mode "
                                "for node %(node)s. Booting the instance "
                                "from disk.", {"node": task.node.uuid})
                    pxe_utils.clean_up_pxe_config(task)
                    boot_device = boot_devices.DISK
            else:
                _build_service_pxe_config(task, instance_image_info,
                                          root_uuid_or_disk_id)
                boot_device = boot_devices.PXE
        else:
            # If it's going to boot from the local disk, we don't need
            # PXE config files. They still need to be generated as part
            # of the prepare() because the deployment does PXE boot the
            # deploy ramdisk
            pxe_utils.clean_up_pxe_config(task)
            boot_device = boot_devices.DISK

        # NOTE(pas-ha) do not re-set boot device on ACTIVE nodes
        # during takeover
        if boot_device and task.node.provision_state != states.ACTIVE:
            manager_utils.node_set_boot_device(task, boot_device,
                                               persistent=True)