<commit_before># -*- encoding: utf-8 -*-
#
# Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
PXE Driver and supporting meta-classes.
"""

import os
import shutil

from oslo_config import cfg

from ironic.common import boot_devices
from ironic.common import dhcp_factory
from ironic.common import exception
from ironic.common.glance_service import service_utils
from ironic.common.i18n import _
from ironic.common.i18n import _LE
from ironic.common.i18n import _LI
from ironic.common.i18n import _LW
from ironic.common import image_service as service
from ironic.common import keystone
from ironic.common import paths
from ironic.common import pxe_utils
from ironic.common import states
from ironic.common import utils
from ironic.conductor import task_manager
from ironic.conductor import utils as manager_utils
from ironic.drivers import base
from ironic.drivers.modules import agent
from ironic.drivers.modules import agent_base_vendor
from ironic.drivers.modules import deploy_utils
from ironic.drivers.modules import image_cache
from ironic.drivers.modules import iscsi_deploy
from ironic.drivers import utils as driver_utils
from ironic.openstack.common import fileutils
from ironic.openstack.common import log as logging


pxe_opts = [
    cfg.StrOpt('pxe_config_template',
               default=paths.basedir_def(
                    'drivers/modules/pxe_config.template'),
               help='Template file for PXE configuration.'),
    cfg.StrOpt('uefi_pxe_config_template',
               default=paths.basedir_def(
                    'drivers/modules/elilo_efi_pxe_config.template'),
               help='Template file for PXE configuration for UEFI boot'
                    ' loader.'),
    cfg.StrOpt('tftp_server',
               default='$my_ip',
               help='IP address of Ironic compute node\'s tftp server.'),
    cfg.StrOpt('tftp_root',
               default='/tftpboot',
               help='Ironic compute node\'s tftp root path.'),
    cfg.StrOpt('tftp_master_path',
               default='/tftpboot/master_images',
               help='Directory where master tftp images are stored on disk.'),
    # NOTE(dekehn): Additional boot files options may be created in the event
    #  other architectures require different boot files.
    cfg.StrOpt('pxe_bootfile_name',
               default='pxelinux.0',
               help='Bootfile DHCP parameter.'),
    cfg.StrOpt('uefi_pxe_bootfile_name',
               default='elilo.efi',
               help='Bootfile DHCP parameter for UEFI boot mode.'),
    cfg.StrOpt('http_url',
                help='Ironic compute node\'s HTTP server URL. '
                     'Example: http://172.16.31.10:8080'),
    cfg.StrOpt('http_root',
                default='/httpboot',
                help='Ironic compute node\'s HTTP root path.'),
    cfg.BoolOpt('ipxe_enabled',
                default=False,
                help='Enable iPXE boot.'),
    cfg.StrOpt('ipxe_boot_script',
               default=paths.basedir_def(
                    'drivers/modules/boot.ipxe'),
               help='The path to the main iPXE script file.'),
    ]

LOG = logging.getLogger(__name__)

CONF = cfg.CONF
CONF.register_opts(pxe_opts, group='pxe')
CONF.import_opt('deploy_callback_timeout', 'ironic.conductor.manager',
                group='conductor')


REQUIRED_PROPERTIES = {
    'deploy_kernel': _("UUID (from Glance) of the deployment kernel. "
                       "Required."),
    'deploy_ramdisk': _("UUID (from Glance) of the ramdisk that is "
                        "mounted at boot time. Required."),
    'pxe_deploy_kernel': _("DEPRECATED: Use deploy_kernel instead. UUID "
                           "(from Glance) of the deployment kernel. "
                           "Required."),
    'pxe_deploy_ramdisk': _("DEPRECATED: Use deploy_ramdisk instead. UUID "
                            "(from Glance) of the ramdisk that is "
                            "mounted at boot time. Required."),
}
COMMON_PROPERTIES = REQUIRED_PROPERTIES


def _parse_driver_info(node):
    """Gets the driver specific Node deployment info.

    This method validates whether the 'driver_info' property of the
    supplied node contains the required information for this driver to
    deploy images to the node.

    :param node: a single Node.
    :returns: A dict with the driver_info values.
    :raises: MissingParameterValue
    """
    info = node.driver_info
    d_info = {}

    # NOTE(lucasagomes): For backwards compatibility let's keep accepting
    # pxe_deploy_{kernel, ramdisk}, should be removed in Liberty.
    deprecated_msg = _LW('The "%(old_param)s" parameter is deprecated. '
                         'Please use "%(new_param)s" instead.')

    for parameter in ('deploy_kernel', 'deploy_ramdisk'):
        value = info.get(parameter)
        if not value:
            old_parameter = 'pxe_' + parameter
            value = info.get(old_parameter)
            if value:
                LOG.warning(deprecated_msg, {'old_param': old_parameter,
                                             'new_param': parameter})
        d_info[parameter] = value

    error_msg = _("Cannot validate PXE bootloader. Some parameters were"
                  " missing in node's driver_info")
    deploy_utils.check_for_missing_params(d_info, error_msg)

    return d_info


def _parse_deploy_info(node):
    """Gets the instance and driver specific Node deployment info.

    This method validates whether the 'instance_info' and 'driver_info'
    property of the supplied node contains the required information for
    this driver to deploy images to the node.

    :param node: a single Node.
    :returns: A dict with the instance_info and driver_info values.<commit_msg>Add node UUID to deprecated log message<commit_after># -*- encoding: utf-8 -*-
#
# Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
PXE Driver and supporting meta-classes.
"""

import os
import shutil

from oslo_config import cfg

from ironic.common import boot_devices
from ironic.common import dhcp_factory
from ironic.common import exception
from ironic.common.glance_service import service_utils
from ironic.common.i18n import _
from ironic.common.i18n import _LE
from ironic.common.i18n import _LI
from ironic.common.i18n import _LW
from ironic.common import image_service as service
from ironic.common import keystone
from ironic.common import paths
from ironic.common import pxe_utils
from ironic.common import states
from ironic.common import utils
from ironic.conductor import task_manager
from ironic.conductor import utils as manager_utils
from ironic.drivers import base
from ironic.drivers.modules import agent
from ironic.drivers.modules import agent_base_vendor
from ironic.drivers.modules import deploy_utils
from ironic.drivers.modules import image_cache
from ironic.drivers.modules import iscsi_deploy
from ironic.drivers import utils as driver_utils
from ironic.openstack.common import fileutils
from ironic.openstack.common import log as logging


pxe_opts = [
    cfg.StrOpt('pxe_config_template',
               default=paths.basedir_def(
                    'drivers/modules/pxe_config.template'),
               help='Template file for PXE configuration.'),
    cfg.StrOpt('uefi_pxe_config_template',
               default=paths.basedir_def(
                    'drivers/modules/elilo_efi_pxe_config.template'),
               help='Template file for PXE configuration for UEFI boot'
                    ' loader.'),
    cfg.StrOpt('tftp_server',
               default='$my_ip',
               help='IP address of Ironic compute node\'s tftp server.'),
    cfg.StrOpt('tftp_root',
               default='/tftpboot',
               help='Ironic compute node\'s tftp root path.'),
    cfg.StrOpt('tftp_master_path',
               default='/tftpboot/master_images',
               help='Directory where master tftp images are stored on disk.'),
    # NOTE(dekehn): Additional boot files options may be created in the event
    #  other architectures require different boot files.
    cfg.StrOpt('pxe_bootfile_name',
               default='pxelinux.0',
               help='Bootfile DHCP parameter.'),
    cfg.StrOpt('uefi_pxe_bootfile_name',
               default='elilo.efi',
               help='Bootfile DHCP parameter for UEFI boot mode.'),
    cfg.StrOpt('http_url',
                help='Ironic compute node\'s HTTP server URL. '
                     'Example: http://172.16.31.10:8080'),
    cfg.StrOpt('http_root',
                default='/httpboot',
                help='Ironic compute node\'s HTTP root path.'),
    cfg.BoolOpt('ipxe_enabled',
                default=False,
                help='Enable iPXE boot.'),
    cfg.StrOpt('ipxe_boot_script',
               default=paths.basedir_def(
                    'drivers/modules/boot.ipxe'),
               help='The path to the main iPXE script file.'),
    ]

LOG = logging.getLogger(__name__)

CONF = cfg.CONF
CONF.register_opts(pxe_opts, group='pxe')
CONF.import_opt('deploy_callback_timeout', 'ironic.conductor.manager',
                group='conductor')


REQUIRED_PROPERTIES = {
    'deploy_kernel': _("UUID (from Glance) of the deployment kernel. "
                       "Required."),
    'deploy_ramdisk': _("UUID (from Glance) of the ramdisk that is "
                        "mounted at boot time. Required."),
    'pxe_deploy_kernel': _("DEPRECATED: Use deploy_kernel instead. UUID "
                           "(from Glance) of the deployment kernel. "
                           "Required."),
    'pxe_deploy_ramdisk': _("DEPRECATED: Use deploy_ramdisk instead. UUID "
                            "(from Glance) of the ramdisk that is "
                            "mounted at boot time. Required."),
}
COMMON_PROPERTIES = REQUIRED_PROPERTIES


def _parse_driver_info(node):
    """Gets the driver specific Node deployment info.

    This method validates whether the 'driver_info' property of the
    supplied node contains the required information for this driver to
    deploy images to the node.

    :param node: a single Node.
    :returns: A dict with the driver_info values.
    :raises: MissingParameterValue
    """
    info = node.driver_info
    d_info = {}

    # NOTE(lucasagomes): For backwards compatibility let's keep accepting
    # pxe_deploy_{kernel, ramdisk}, should be removed in Liberty.
    deprecated_msg = _LW('The "%(old_param)s" parameter is deprecated. '
                         'Please update the node %(node)s to use '
                         '"%(new_param)s" instead.')

    for parameter in ('deploy_kernel', 'deploy_ramdisk'):
        value = info.get(parameter)
        if not value:
            old_parameter = 'pxe_' + parameter
            value = info.get(old_parameter)
            if value:
                LOG.warning(deprecated_msg, {'old_param': old_parameter,
                                             'new_param': parameter,
                                             'node': node.uuid})
        d_info[parameter] = value

    error_msg = _("Cannot validate PXE bootloader. Some parameters were"
                  " missing in node's driver_info")
    deploy_utils.check_for_missing_params(d_info, error_msg)

    return d_info


def _parse_deploy_info(node):
    """Gets the instance and driver specific Node deployment info.

    This method validates whether the 'instance_info' and 'driver_info'
    property of the supplied node contains the required information for
    this driver to deploy images to the node.

    :param node: a single Node.
    :returns: A dict with the instance_info and driver_info values.
{'fraction_non_alphanumeric': 0.08436763550667714, 'fraction_numerical': 0.004870384917517675, 'mean_word_length': 2.6625431530494823, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4712977', 'n_tokens_mistral': 3634, 'n_tokens_neox': 3400, 'n_words': 1118}