Esempio n. 1
0
    def clean_up(self, task):
        """Clean up the deployment environment for the task's node.

        Unlinks TFTP and instance images and triggers image cache cleanup.
        Removes the TFTP configuration files for this node. As a precaution,
        this method also ensures the keystone auth token file was removed.

        :param task: a TaskManager instance containing the node to act on.
        """
        node = task.node
        pxe_info = _get_tftp_image_info(node, task.context)
        d_info = _parse_driver_info(node)
        for label in pxe_info:
            path = pxe_info[label][1]
            utils.unlink_without_raise(path)
        TFTPImageCache().clean_up()

        utils.unlink_without_raise(_get_pxe_config_file_path(
                node.uuid))
        for port in driver_utils.get_node_mac_addresses(task):
            mac_path = _get_pxe_mac_path(port)
            utils.unlink_without_raise(mac_path)

        utils.rmtree_without_raise(
                os.path.join(CONF.pxe.tftp_root, node.uuid))

        _destroy_images(d_info, node.uuid)
        _destroy_token_file(node)
Esempio n. 2
0
    def get_boot_device(self, task):
        """Get the current boot device for the task's node.

        Provides the current boot device of the node. Be aware that not
        all drivers support this.

        :param task: a task from TaskManager.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        :raises: SSHCommandFailed on an error from ssh.
        :returns: a dictionary containing:

            :boot_device: the boot device, one of
                :mod:`ironic.common.boot_devices` or None if it is unknown.
            :persistent: Whether the boot device will persist to all
                future boots or not, None if it is unknown.

        """
        node = task.node
        driver_info = _parse_driver_info(node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(node)
        response = {'boot_device': None, 'persistent': None}
        try:
            response['boot_device'] = _get_boot_device(ssh_obj, driver_info)
        except NotImplementedError:
            LOG.warning(_LW("Failed to get boot device for node %(node)s, "
                            "virt_type %(vtype)s does not support this "
                            "operation"),
                        {'node': node.uuid, 'vtype': driver_info['virt_type']})
        return response
Esempio n. 3
0
File: pxe.py Progetto: nkaul/ironic
    def clean_up(self, task, node):
        """Clean up the deployment environment for this node.

        Delete the deploy and user images from the local cache, if no remaining
        active nodes require them. Removes the TFTP configuration files for
        this node. As a precaution, this method also ensures the keystone auth
        token file was removed.

        :param task: a TaskManager instance.
        :param node: the Node to act upon.
        """
        pxe_info = _get_tftp_image_info(node, task.context)
        d_info = _parse_driver_info(node)
        for label in pxe_info:
            (uuid, path) = pxe_info[label]
            master_path = os.path.join(CONF.pxe.tftp_master_path, uuid)
            utils.unlink_without_raise(path)
            _unlink_master_image(master_path)

        utils.unlink_without_raise(_get_pxe_config_file_path(
                node.uuid))
        for port in driver_utils.get_node_mac_addresses(task, node):
            mac_path = _get_pxe_mac_path(port)
            utils.unlink_without_raise(mac_path)

        utils.rmtree_without_raise(
                os.path.join(CONF.pxe.tftp_root, node.uuid))

        _destroy_images(d_info, node.uuid)
        _destroy_token_file(node)
Esempio n. 4
0
    def clean_up(self, task):
        """Clean up the deployment environment for the task's node.

        Unlinks TFTP and instance images and triggers image cache cleanup.
        Removes the TFTP configuration files for this node. As a precaution,
        this method also ensures the keystone auth token file was removed.

        :param task: a TaskManager instance containing the node to act on.
        """
        node = task.node
        pxe_info = _get_tftp_image_info(node, task.context)
        d_info = _parse_driver_info(node)
        for label in pxe_info:
            path = pxe_info[label][1]
            utils.unlink_without_raise(path)
        TFTPImageCache().clean_up()

        utils.unlink_without_raise(_get_pxe_config_file_path(node.uuid))
        for port in driver_utils.get_node_mac_addresses(task):
            mac_path = _get_pxe_mac_path(port)
            utils.unlink_without_raise(mac_path)

        utils.rmtree_without_raise(os.path.join(CONF.pxe.tftp_root, node.uuid))

        _destroy_images(d_info, node.uuid)
        _destroy_token_file(node)
Esempio n. 5
0
def clean_up_pxe_config(task):
    """Clean up the TFTP environment for the task's node.

    :param task: A TaskManager instance.

    """
    LOG.debug("Cleaning up PXE config for node %s", task.node.uuid)

    is_uefi_boot_mode = (deploy_utils.get_boot_mode_for_deploy(
        task.node) == 'uefi')
    if is_uefi_boot_mode and not CONF.pxe.ipxe_enabled:
        api = dhcp_factory.DHCPFactory().provider
        ip_addresses = api.get_ip_addresses(task)
        if not ip_addresses:
            return

        for port_ip_address in ip_addresses:
            try:
                # Get xx.xx.xx.xx based grub config file
                ip_address_path = _get_pxe_ip_address_path(
                    port_ip_address, False)
                # Get 0AOAOAOA based elilo config file
                hex_ip_path = _get_pxe_ip_address_path(port_ip_address, True)
            except exception.InvalidIPv4Address:
                continue
            # Cleaning up config files created for grub2.
            ironic_utils.unlink_without_raise(ip_address_path)
            # Cleaning up config files created for elilo.
            ironic_utils.unlink_without_raise(hex_ip_path)
    else:
        for mac in driver_utils.get_node_mac_addresses(task):
            ironic_utils.unlink_without_raise(_get_pxe_mac_path(mac))

    utils.rmtree_without_raise(os.path.join(get_root_dir(), task.node.uuid))
Esempio n. 6
0
    def set_power_state(self, task, pstate):
        """Turn the power on or off.

        Set the power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :param pstate: Either POWER_ON or POWER_OFF from :class:
            `ironic.common.states`.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect, or if the desired power state is invalid.
        :raises: MissingParameterValue when a required parameter is missing
        :raises: NodeNotFound if could not find a VM corresponding to any
            of the provided MACs.
        :raises: PowerStateFailure if it failed to set power state to pstate.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        """
        driver_info = _parse_driver_info(task.node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(task.node)

        if pstate == states.POWER_ON:
            state = _power_on(ssh_obj, driver_info)
        elif pstate == states.POWER_OFF:
            state = _power_off(ssh_obj, driver_info)
        else:
            raise exception.InvalidParameterValue(
                _("set_power_state called with invalid power state %s.") %
                pstate)

        if state != pstate:
            raise exception.PowerStateFailure(pstate=pstate)
Esempio n. 7
0
File: ssh.py Progetto: n1zyy/ironic
    def set_boot_device(self, task, device, persistent=False):
        """Set the boot device for the task's node.

        Set the boot device to use on next reboot of the node.

        :param task: a task from TaskManager.
        :param device: the boot device, one of
                       :mod:`ironic.common.boot_devices`.
        :param persistent: Boolean value. True if the boot device will
                           persist to all future boots, False if not.
                           Default: False. Ignored by this driver.
        :raises: InvalidParameterValue if an invalid boot device is
                 specified or if any connection parameters are incorrect.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: NotImplementedError if the virt_type does not support
            setting the boot device.

        """
        node = task.node
        driver_info = _parse_driver_info(node)
        if device not in self.get_supported_boot_devices():
            raise exception.InvalidParameterValue(_(
                "Invalid boot device %s specified.") % device)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(node)
        try:
            _set_boot_device(ssh_obj, driver_info, _BOOT_DEVICES_MAP[device])
        except NotImplementedError:
            LOG.error(_LE("Failed to set boot device for node %(node)s, "
                          "virt_type %(vtype)s does not support this "
                          "operation") % {'node': node.uuid,
                                          'vtype': driver_info['virt_type']})
            raise
Esempio n. 8
0
    def reboot(self, task):
        """Cycles the power to the task's node.

        Power cycles a node.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect.
        :raises: MissingParameterValue when a required parameter is missing
        :raises: NodeNotFound.
        :raises: PowerStateFailure if it failed to set power state to POWER_ON.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        """
        driver_info = _parse_driver_info(task.node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(task.node)
        current_pstate = _get_power_status(ssh_obj, driver_info)
        if current_pstate == states.POWER_ON:
            _power_off(ssh_obj, driver_info)

        state = _power_on(ssh_obj, driver_info)

        if state != states.POWER_ON:
            raise exception.PowerStateFailure(pstate=states.POWER_ON)
Esempio n. 9
0
    def _validate_common(self, task):
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.")
                % node.uuid)

        # TODO(TheJulia): Once ipxe support is remove from the pxe
        # interface, this can be removed.
        if CONF.pxe.ipxe_enabled:
            if (not CONF.deploy.http_url
                or not CONF.deploy.http_root):
                raise exception.MissingParameterValue(_(
                    "iPXE boot is enabled but no HTTP URL or HTTP "
                    "root was specified."))

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            validate_boot_parameters_for_trusted_boot(node)

        pxe_utils.parse_driver_info(node)
Esempio n. 10
0
File: pxe.py Progetto: n1zyy/ironic
    def validate(self, task):
        """Validate the deployment information for the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue.
        """
        node = task.node
        if not driver_utils.get_node_mac_addresses(task):
            raise exception.InvalidParameterValue(_("Node %s does not have "
                                "any port associated with it.") % node.uuid)

        d_info = _parse_deploy_info(node)

        # Try to get the URL of the Ironic API
        try:
            # TODO(lucasagomes): Validate the format of the URL
            CONF.conductor.api_url or keystone.get_service_url()
        except (exception.CatalogFailure,
                exception.CatalogNotFound,
                exception.CatalogUnauthorized):
            raise exception.InvalidParameterValue(_(
                "Couldn't get the URL of the Ironic API service from the "
                "configuration file or keystone catalog."))

        _validate_glance_image(task.context, d_info)
Esempio n. 11
0
    def start_console(self, task):
        """Start a remote console for the node.

        :param task: a task from TaskManager
        :raises: MissingParameterValue if required ssh parameters are
                 missing
        :raises: ConsoleError if the directory for the PID file cannot be
                 created
        :raises: ConsoleSubprocessFailed when invoking the subprocess failed
        :raises: InvalidParameterValue if required parameters are invalid.
        """

        driver_info = _parse_driver_info(task.node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(task.node)
        node_name = _get_hosts_name_for_node(ssh_obj, driver_info)

        ssh_cmd = ("/:%(uid)s:%(gid)s:HOME:virsh console %(node)s"
                   % {'uid': os.getuid(),
                      'gid': os.getgid(),
                      'node': node_name})

        console_utils.start_shellinabox_console(driver_info['uuid'],
                                                driver_info['terminal_port'],
                                                ssh_cmd)
Esempio n. 12
0
    def clean_up(self, task, node):
        """Clean up the deployment environment for this node.

        Delete the deploy and user images from the local cache, if no remaining
        active nodes require them. Removes the TFTP configuration files for
        this node. As a precaution, this method also ensures the keystone auth
        token file was removed.

        :param task: a TaskManager instance.
        :param node: the Node to act upon.
        """
        pxe_info = _get_tftp_image_info(node, task.context)
        d_info = _parse_driver_info(node)
        for label in pxe_info:
            (uuid, path) = pxe_info[label]
            master_path = os.path.join(CONF.pxe.tftp_master_path, uuid)
            utils.unlink_without_raise(path)
            _unlink_master_image(master_path)

        utils.unlink_without_raise(_get_pxe_config_file_path(node.uuid))
        for port in driver_utils.get_node_mac_addresses(task, node):
            mac_path = _get_pxe_mac_path(port)
            utils.unlink_without_raise(mac_path)

        utils.rmtree_without_raise(os.path.join(CONF.pxe.tftp_root, node.uuid))

        _destroy_images(d_info, node.uuid)
        _destroy_token_file(node)
Esempio n. 13
0
    def set_power_state(self, task, pstate):
        """Turn the power on or off.

        Set the power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :param pstate: Either POWER_ON or POWER_OFF from :class:
            `ironic.common.states`.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect, or if the desired power state is invalid.
        :raises: MissingParameterValue when a required parameter is missing
        :raises: NodeNotFound.
        :raises: PowerStateFailure if it failed to set power state to pstate.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        """
        driver_info = _parse_driver_info(task.node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(task.node)

        if pstate == states.POWER_ON:
            state = _power_on(ssh_obj, driver_info)
        elif pstate == states.POWER_OFF:
            state = _power_off(ssh_obj, driver_info)
        else:
            raise exception.InvalidParameterValue(
                _("set_power_state called with invalid power state %s."
                  ) % pstate)

        if state != pstate:
            raise exception.PowerStateFailure(pstate=pstate)
Esempio n. 14
0
def clean_up_pxe_config(task):
    """Clean up the TFTP environment for the task's node.

    :param task: A TaskManager instance.

    """
    LOG.debug("Cleaning up PXE config for node %s", task.node.uuid)

    if deploy_utils.get_boot_mode_for_deploy(task.node) == 'uefi':
        api = dhcp_factory.DHCPFactory().provider
        ip_addresses = api.get_ip_addresses(task)
        if not ip_addresses:
            return

        for port_ip_address in ip_addresses:
            try:
                ip_address_path = _get_pxe_ip_address_path(port_ip_address)
            except exception.InvalidIPv4Address:
                continue
            utils.unlink_without_raise(ip_address_path)
    else:
        for mac in driver_utils.get_node_mac_addresses(task):
            utils.unlink_without_raise(_get_pxe_mac_path(mac))
            # TODO(lucasagomes): Backward compatibility with :hexraw,
            # to be removed in M.
            # see: https://bugs.launchpad.net/ironic/+bug/1441710
            if CONF.pxe.ipxe_enabled:
                utils.unlink_without_raise(_get_pxe_mac_path(mac,
                                                             delimiter=''))

    utils.rmtree_without_raise(os.path.join(get_root_dir(), task.node.uuid))
Esempio n. 15
0
    def reboot(self, task, node):
        """Cycles the power to a node.

        Power cycles a node.

        :param task: An instance of `ironic.manager.task_manager.TaskManager`.
        :param node: A single node.

        :raises: InvalidParameterValue if any connection parameters are
            incorrect.
        :raises: NodeNotFound.
        :raises: PowerStateFailure if it failed to set power state to POWER_ON.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        """
        driver_info = _parse_driver_info(node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task, node)
        ssh_obj = _get_connection(node)
        current_pstate = _get_power_status(ssh_obj, driver_info)
        if current_pstate == states.POWER_ON:
            _power_off(ssh_obj, driver_info)

        state = _power_on(ssh_obj, driver_info)

        if state != states.POWER_ON:
            raise exception.PowerStateFailure(pstate=states.POWER_ON)
Esempio n. 16
0
def clean_up_pxe_config(task):
    """Clean up the TFTP environment for the task's node.

    :param task: A TaskManager instance.

    """
    LOG.debug("Cleaning up PXE config for node %s", task.node.uuid)

    if driver_utils.get_node_capability(task.node, 'boot_mode') == 'uefi':
        api = dhcp_factory.DHCPFactory().provider
        ip_addresses = api.get_ip_addresses(task)
        if not ip_addresses:
            return

        for port_ip_address in ip_addresses:
            try:
                ip_address_path = _get_pxe_ip_address_path(port_ip_address)
            except exception.InvalidIPv4Address:
                continue
            utils.unlink_without_raise(ip_address_path)
    else:
        for mac in driver_utils.get_node_mac_addresses(task):
            utils.unlink_without_raise(_get_pxe_mac_path(mac))

    utils.rmtree_without_raise(os.path.join(get_root_dir(),
                                            task.node.uuid))
Esempio n. 17
0
    def set_power_state(self, task, node, pstate):
        """Turn the power on or off.

        Set the power state of a node.

        :param task: An instance of `ironic.manager.task_manager.TaskManager`.
        :param node: A single node.
        :param pstate: Either POWER_ON or POWER_OFF from :class:
            `ironic.common.states`.

        :raises: InvalidParameterValue if any connection parameters are
            incorrect, or if the desired power state is invalid.
        :raises: NodeNotFound.
        :raises: PowerStateFailure if it failed to set power state to pstate.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        """
        driver_info = _parse_driver_info(node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task, node)
        ssh_obj = _get_connection(node)

        if pstate == states.POWER_ON:
            state = _power_on(ssh_obj, driver_info)
        elif pstate == states.POWER_OFF:
            state = _power_off(ssh_obj, driver_info)
        else:
            raise exception.InvalidParameterValue(
                _("set_power_state called "
                  "with invalid power state %s.") % pstate)

        if state != pstate:
            raise exception.PowerStateFailure(pstate=pstate)
Esempio n. 18
0
def validate(task):
    """Validates the pre-requisites for iSCSI deploy.

    Validates whether node in the task provided has some ports enrolled.
    This method validates whether conductor url is available either from CONF
    file or from keystone.

    :param task: a TaskManager instance containing the node to act on.
    :raises: InvalidParameterValue if the URL of the Ironic API service is not
             configured in config file and is not accessible via Keystone
             catalog.
    :raises: MissingParameterValue if no ports are enrolled for the given node.
    """
    node = task.node
    if not driver_utils.get_node_mac_addresses(task):
        raise exception.MissingParameterValue(
            _("Node %s does not have any port associated with it.") %
            node.uuid)

    try:
        # TODO(lucasagomes): Validate the format of the URL
        CONF.conductor.api_url or keystone.get_service_url()
    except (exception.KeystoneFailure, exception.CatalogNotFound,
            exception.KeystoneUnauthorized) as e:
        raise exception.InvalidParameterValue(
            _("Couldn't get the URL of the Ironic API service from the "
              "configuration file or keystone catalog. Keystone error: %s") %
            e)

    # Validate the root device hints
    deploy_utils.parse_root_device_hints(node)
Esempio n. 19
0
def clean_up_pxe_config(task):
    """Clean up the TFTP environment for the task's node.

    :param task: A TaskManager instance.

    """
    LOG.debug("Cleaning up PXE config for node %s", task.node.uuid)

    is_uefi_boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node) == "uefi"
    if is_uefi_boot_mode and not CONF.pxe.ipxe_enabled:
        api = dhcp_factory.DHCPFactory().provider
        ip_addresses = api.get_ip_addresses(task)
        if not ip_addresses:
            return

        for port_ip_address in ip_addresses:
            try:
                # Get xx.xx.xx.xx based grub config file
                ip_address_path = _get_pxe_ip_address_path(port_ip_address, False)
                # Get 0AOAOAOA based elilo config file
                hex_ip_path = _get_pxe_ip_address_path(port_ip_address, True)
            except exception.InvalidIPv4Address:
                continue
            # Cleaning up config files created for grub2.
            ironic_utils.unlink_without_raise(ip_address_path)
            # Cleaning up config files created for elilo.
            ironic_utils.unlink_without_raise(hex_ip_path)
    else:
        for mac in driver_utils.get_node_mac_addresses(task):
            ironic_utils.unlink_without_raise(_get_pxe_mac_path(mac))

    utils.rmtree_without_raise(os.path.join(get_root_dir(), task.node.uuid))
Esempio n. 20
0
def clean_up_pxe_config(task):
    """Clean up the TFTP environment for the task's node.

    :param task: A TaskManager instance.

    """
    LOG.debug("Cleaning up PXE config for node %s", task.node.uuid)

    if deploy_utils.get_boot_mode_for_deploy(task.node) == 'uefi':
        api = dhcp_factory.DHCPFactory().provider
        ip_addresses = api.get_ip_addresses(task)
        if not ip_addresses:
            return

        for port_ip_address in ip_addresses:
            try:
                ip_address_path = _get_pxe_ip_address_path(port_ip_address)
            except exception.InvalidIPv4Address:
                continue
            utils.unlink_without_raise(ip_address_path)
    else:
        for mac in driver_utils.get_node_mac_addresses(task):
            utils.unlink_without_raise(_get_pxe_mac_path(mac))
            # TODO(lucasagomes): Backward compatibility with :hexraw,
            # to be removed in M.
            # see: https://bugs.launchpad.net/ironic/+bug/1441710
            if CONF.pxe.ipxe_enabled:
                utils.unlink_without_raise(_get_pxe_mac_path(mac,
                                           delimiter=''))

    utils.rmtree_without_raise(os.path.join(get_root_dir(),
                                            task.node.uuid))
Esempio n. 21
0
def validate(task):
    """Validates the pre-requisites for iSCSI deploy.

    Validates whether node in the task provided has some ports enrolled.
    This method validates whether conductor url is available either from CONF
    file or from keystone.

    :param task: a TaskManager instance containing the node to act on.
    :raises: InvalidParameterValue if the URL of the Ironic API service is not
             configured in config file and is not accessible via Keystone
             catalog.
    :raises: MissingParameterValue if no ports are enrolled for the given node.
    """
    node = task.node
    if not driver_utils.get_node_mac_addresses(task):
        raise exception.MissingParameterValue(_("Node %s does not have " "any port associated with it.") % node.uuid)

    try:
        # TODO(lucasagomes): Validate the format of the URL
        CONF.conductor.api_url or keystone.get_service_url()
    except (exception.KeystoneFailure, exception.CatalogNotFound, exception.KeystoneUnauthorized) as e:
        raise exception.InvalidParameterValue(
            _(
                "Couldn't get the URL of the Ironic API service from the "
                "configuration file or keystone catalog. Keystone error: %s"
            )
            % e
        )

    # Validate the root device hints
    deploy_utils.parse_root_device_hints(node)
Esempio n. 22
0
    def get_boot_device(self, task):
        """Get the current boot device for the task's node.

        Provides the current boot device of the node. Be aware that not
        all drivers support this.

        :param task: a task from TaskManager.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        :raises: SSHCommandFailed on an error from ssh.
        :returns: a dictionary containing:

            :boot_device: the boot device, one of
                :mod:`ironic.common.boot_devices` or None if it is unknown.
            :persistent: Whether the boot device will persist to all
                future boots or not, None if it is unknown.

        """
        node = task.node
        driver_info = _parse_driver_info(node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(node)
        response = {'boot_device': None, 'persistent': None}
        try:
            response['boot_device'] = _get_boot_device(ssh_obj, driver_info)
        except NotImplementedError:
            LOG.warning(_LW("Failed to get boot device for node %(node)s, "
                            "virt_type %(vtype)s does not support this "
                            "operation"),
                        {'node': node.uuid, 'vtype': driver_info['virt_type']})
        return response
Esempio n. 23
0
    def validate(self, task):
        """Check that the node's 'driver_info' is valid.

        Check that the node's 'driver_info' contains the requisite fields
        and that an Libvirt connection to the node can be established.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect or if failed to connect to the libvirt socket.
        :raises: MissingParameterValue if no ports are enrolled for the given
                 node.
       """

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.") %
                task.node.uuid)
        driver_info = _parse_driver_info(task.node)
        try:
            _get_libvirt_connection(driver_info)
        except f_exc.LibvirtError:
            LOG.error(_LE("Failed to get libvirt connection node %(node)s"),
                      {'node': task.node.uuid})
            raise exception.InvalidParameterValue(
                _("Libvirt connection cannot"
                  " be established"))
Esempio n. 24
0
    def start_console(self, task):
        """Start a remote console for the node.

        :param task: a task from TaskManager
        :raises: MissingParameterValue if required ssh parameters are
                 missing
        :raises: ConsoleError if the directory for the PID file cannot be
                 created
        :raises: ConsoleSubprocessFailed when invoking the subprocess failed
        :raises: InvalidParameterValue if required parameters are invalid.
        """

        driver_info = _parse_driver_info(task.node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(task.node)
        node_name = _get_hosts_name_for_node(ssh_obj, driver_info)

        ssh_cmd = ("/:%(uid)s:%(gid)s:HOME:virsh console %(node)s"
                   % {'uid': os.getuid(),
                      'gid': os.getgid(),
                      'node': node_name})

        console_utils.start_shellinabox_console(driver_info['uuid'],
                                                driver_info['terminal_port'],
                                                ssh_cmd)
Esempio n. 25
0
def clean_up_pxe_config(task):
    """Clean up the TFTP environment for the task's node.

    :param task: A TaskManager instance.

    """
    LOG.debug("Cleaning up PXE config for node %s", task.node.uuid)

    if driver_utils.get_node_capability(task.node, 'boot_mode') == 'uefi':
        api = dhcp_factory.DHCPFactory().provider
        ip_addresses = api.get_ip_addresses(task)
        if not ip_addresses:
            return

        for port_ip_address in ip_addresses:
            try:
                ip_address_path = _get_pxe_ip_address_path(port_ip_address)
            except exception.InvalidIPv4Address:
                continue
            utils.unlink_without_raise(ip_address_path)
    else:
        for mac in driver_utils.get_node_mac_addresses(task):
            utils.unlink_without_raise(_get_pxe_mac_path(mac))

    utils.rmtree_without_raise(os.path.join(get_root_dir(), task.node.uuid))
Esempio n. 26
0
    def _validate_common(self, task):
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.") %
                node.uuid)

        if self.ipxe_enabled:
            if not CONF.deploy.http_url or not CONF.deploy.http_root:
                raise exception.MissingParameterValue(
                    _("iPXE boot is enabled but no HTTP URL or HTTP "
                      "root was specified."))

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            if self.ipxe_enabled:
                # NOTE(TheJulia): So in theory (huge theory here, not put to
                # practice or tested), that one can define the kernel as tboot
                # and define the actual kernel and ramdisk as appended data.
                # Similar to how one can iPXE load the XEN hypervisor.
                # tboot mailing list seem to indicate pxe/ipxe support, or
                # more specifically avoiding breaking the scenarios of use,
                # but there is also no definitive documentation on the subject.
                LOG.warning(
                    'Trusted boot has been requested for %(node)s in '
                    'concert with iPXE. This is not a supported '
                    'configuration for an ironic deployment.',
                    {'node': node.uuid})
            pxe_utils.validate_boot_parameters_for_trusted_boot(node)

        pxe_utils.parse_driver_info(node)
Esempio n. 27
0
    def validate(self, task):
        """Validate the deployment information for the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue.
        """
        node = task.node
        if not driver_utils.get_node_mac_addresses(task):
            raise exception.InvalidParameterValue(
                _("Node %s does not have "
                  "any port associated with it.") % node.uuid)

        d_info = _parse_deploy_info(node)

        # Try to get the URL of the Ironic API
        try:
            # TODO(lucasagomes): Validate the format of the URL
            CONF.conductor.api_url or keystone.get_service_url()
        except (exception.CatalogFailure, exception.CatalogNotFound,
                exception.CatalogUnauthorized):
            raise exception.InvalidParameterValue(
                _("Couldn't get the URL of the Ironic API service from the "
                  "configuration file or keystone catalog."))

        _validate_glance_image(task.context, d_info)
Esempio n. 28
0
    def reboot(self, task):
        """Cycles the power to the task's node.

        Power cycles a node.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect.
        :raises: MissingParameterValue when a required parameter is missing
        :raises: NodeNotFound.
        :raises: PowerStateFailure if it failed to set power state to POWER_ON.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        """
        driver_info = _parse_driver_info(task.node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(task.node)
        current_pstate = _get_power_status(ssh_obj, driver_info)
        if current_pstate == states.POWER_ON:
            _power_off(ssh_obj, driver_info)

        state = _power_on(ssh_obj, driver_info)

        if state != states.POWER_ON:
            raise exception.PowerStateFailure(pstate=states.POWER_ON)
Esempio n. 29
0
    def validate(self, task):
        """Check that the node's 'driver_info' is valid.

        Check that the node's 'driver_info' contains the requisite fields
        and that an Libvirt connection to the node can be established.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect or if failed to connect to the libvirt socket.
        :raises: MissingParameterValue if no ports are enrolled for the given
                 node.
       """

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it."
                  ) % task.node.uuid)
        driver_info = _parse_driver_info(task.node)
        try:
            _get_libvirt_connection(driver_info)
        except f_exc.LibvirtError:
            LOG.error(_LE("Failed to get libvirt connection node %(node)s"),
                      {'node': task.node.uuid})
            raise exception.InvalidParameterValue(_("Libvirt connection cannot"
                                                    " be established"))
Esempio n. 30
0
    def validate(self, task):
        """Validate the PXE-specific info for booting deploy/instance images.

        This method validates the PXE-specific info for booting the
        ramdisk and instance on the node.  If invalid, raises an
        exception; otherwise returns None.

        :param task: a task from TaskManager.
        :returns: None
        :raises: InvalidParameterValue, if some parameters are invalid.
        :raises: MissingParameterValue, if some required parameters are
            missing.
        """
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.")
                % node.uuid)

        if not CONF.deploy.http_url or not CONF.deploy.http_root:
            raise exception.MissingParameterValue(_(
                "iPXE boot is enabled but no HTTP URL or HTTP "
                "root was specified."))

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            # NOTE(TheJulia): So in theory (huge theory here, not put to
            # practice or tested), that one can define the kernel as tboot
            # and define the actual kernel and ramdisk as appended data.
            # Similar to how one can iPXE load the XEN hypervisor.
            # tboot mailing list seem to indicate pxe/ipxe support, or
            # more specifically avoiding breaking the scenarios of use,
            # but there is also no definitive documentation on the subject.
            LOG.warning('Trusted boot has been requested for %(node)s in '
                        'concert with iPXE. This is not a supported '
                        'configuration for an ironic deployment.',
                        {'node': node.uuid})
            pxe.validate_boot_parameters_for_trusted_boot(node)

        pxe_utils.parse_driver_info(node)
        # NOTE(TheJulia): If we're not writing an image, we can skip
        # the remainder of this method.
        if (not task.driver.storage.should_write_image(task)):
            return

        d_info = deploy_utils.get_image_instance_info(node)
        if (node.driver_internal_info.get('is_whole_disk_image')
                or deploy_utils.get_boot_option(node) == 'local'):
            props = []
        elif service_utils.is_glance_image(d_info['image_source']):
            props = ['kernel_id', 'ramdisk_id']
        else:
            props = ['kernel', 'ramdisk']
        deploy_utils.validate_image_properties(task.context, d_info, props)
Esempio n. 31
0
    def validate(self, task):
        """Validate the PXE-specific info for booting deploy/instance images.

        This method validates the PXE-specific info for booting the
        ramdisk and instance on the node.  If invalid, raises an
        exception; otherwise returns None.

        :param task: a task from TaskManager.
        :returns: None
        :raises: InvalidParameterValue, if some parameters are invalid.
        :raises: MissingParameterValue, if some required parameters are
            missing.
        """
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.") %
                node.uuid)

        if not CONF.deploy.http_url or not CONF.deploy.http_root:
            raise exception.MissingParameterValue(
                _("iPXE boot is enabled but no HTTP URL or HTTP "
                  "root was specified."))

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            # NOTE(TheJulia): So in theory (huge theory here, not put to
            # practice or tested), that one can define the kernel as tboot
            # and define the actual kernel and ramdisk as appended data.
            # Similar to how one can iPXE load the XEN hypervisor.
            # tboot mailing list seem to indicate pxe/ipxe support, or
            # more specifically avoiding breaking the scenarios of use,
            # but there is also no definitive documentation on the subject.
            LOG.warning(
                'Trusted boot has been requested for %(node)s in '
                'concert with iPXE. This is not a supported '
                'configuration for an ironic deployment.', {'node': node.uuid})
            pxe.validate_boot_parameters_for_trusted_boot(node)

        pxe_utils.parse_driver_info(node)
        # NOTE(TheJulia): If we're not writing an image, we can skip
        # the remainder of this method.
        if (not task.driver.storage.should_write_image(task)):
            return

        d_info = deploy_utils.get_image_instance_info(node)
        if (node.driver_internal_info.get('is_whole_disk_image')
                or deploy_utils.get_boot_option(node) == 'local'):
            props = []
        elif service_utils.is_glance_image(d_info['image_source']):
            props = ['kernel_id', 'ramdisk_id']
        else:
            props = ['kernel', 'ramdisk']
        deploy_utils.validate_image_properties(task.context, d_info, props)
Esempio n. 32
0
    def _validate_common(self, task):
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.") %
                node.uuid)

        if self.ipxe_enabled:
            if not CONF.deploy.http_url or not CONF.deploy.http_root:
                raise exception.MissingParameterValue(
                    _("iPXE boot is enabled but no HTTP URL or HTTP "
                      "root was specified."))

        # NOTE(zer0c00l): When 'kickstart' boot option is used we need to store
        # kickstart and squashfs files in http_root directory. These files
        # will be eventually requested by anaconda installer during deployment
        # over http(s).
        if deploy_utils.get_boot_option(node) == 'kickstart':
            if not CONF.deploy.http_url or not CONF.deploy.http_root:
                raise exception.MissingParameterValue(
                    _("'kickstart' boot option is set on the node but no HTTP "
                      "URL or HTTP root was specified."))

            if not CONF.anaconda.default_ks_template:
                raise exception.MissingParameterValue(
                    _("'kickstart' boot option is set on the node but no "
                      "default kickstart template is specified."))

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            if self.ipxe_enabled:
                # NOTE(TheJulia): So in theory (huge theory here, not put to
                # practice or tested), that one can define the kernel as tboot
                # and define the actual kernel and ramdisk as appended data.
                # Similar to how one can iPXE load the XEN hypervisor.
                # tboot mailing list seem to indicate pxe/ipxe support, or
                # more specifically avoiding breaking the scenarios of use,
                # but there is also no definitive documentation on the subject.
                LOG.warning(
                    'Trusted boot has been requested for %(node)s in '
                    'concert with iPXE. This is not a supported '
                    'configuration for an ironic deployment.',
                    {'node': node.uuid})
            pxe_utils.validate_boot_parameters_for_trusted_boot(node)

        # Check if we have invalid parameters being passed which will not work
        # for ramdisk configurations.
        if (node.instance_info.get('image_source')
                and node.instance_info.get('boot_iso')):
            raise exception.InvalidParameterValue(
                _("An 'image_source' and 'boot_iso' parameter may not be "
                  "specified at the same time."))

        pxe_utils.parse_driver_info(node)
Esempio n. 33
0
File: pxe.py Progetto: naterh/ironic
    def validate(self, task):
        """Validate the PXE-specific info for booting deploy/instance images.

        This method validates the PXE-specific info for booting the
        ramdisk and instance on the node.  If invalid, raises an
        exception; otherwise returns None.

        :param task: a task from TaskManager.
        :returns: None
        :raises: InvalidParameterValue, if some parameters are invalid.
        :raises: MissingParameterValue, if some required parameters are
            missing.
        """
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.")
                % node.uuid)

        # Get the boot_mode capability value.
        boot_mode = deploy_utils.get_boot_mode_for_deploy(node)

        if CONF.pxe.ipxe_enabled:
            if (not CONF.deploy.http_url or
                not CONF.deploy.http_root):
                raise exception.MissingParameterValue(_(
                    "iPXE boot is enabled but no HTTP URL or HTTP "
                    "root was specified."))
            # iPXE and UEFI should not be configured together.
            if boot_mode == 'uefi':
                LOG.error(_LE("UEFI boot mode is not supported with "
                              "iPXE boot enabled."))
                raise exception.InvalidParameterValue(_(
                    "Conflict: iPXE is enabled, but cannot be used with node"
                    "%(node_uuid)s configured to use UEFI boot") %
                    {'node_uuid': node.uuid})

        if boot_mode == 'uefi':
            validate_boot_option_for_uefi(node)

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            validate_boot_parameters_for_trusted_boot(node)

        _parse_driver_info(node)
        d_info = _parse_instance_info(node)
        if node.driver_internal_info.get('is_whole_disk_image'):
            props = []
        elif service_utils.is_glance_image(d_info['image_source']):
            props = ['kernel_id', 'ramdisk_id']
        else:
            props = ['kernel', 'ramdisk']
        deploy_utils.validate_image_properties(task.context, d_info, props)
Esempio n. 34
0
    def validate(self, task):
        """Validate the PXE-specific info for booting deploy/instance images.

        This method validates the PXE-specific info for booting the
        ramdisk and instance on the node.  If invalid, raises an
        exception; otherwise returns None.

        :param task: a task from TaskManager.
        :returns: None
        :raises: InvalidParameterValue, if some parameters are invalid.
        :raises: MissingParameterValue, if some required parameters are
            missing.
        """
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.")
                % node.uuid)

        # Get the boot_mode capability value.
        boot_mode = deploy_utils.get_boot_mode_for_deploy(node)

        if CONF.pxe.ipxe_enabled:
            if (not CONF.deploy.http_url or
                not CONF.deploy.http_root):
                raise exception.MissingParameterValue(_(
                    "iPXE boot is enabled but no HTTP URL or HTTP "
                    "root was specified."))
            # iPXE and UEFI should not be configured together.
            if boot_mode == 'uefi':
                LOG.error(_LE("UEFI boot mode is not supported with "
                              "iPXE boot enabled."))
                raise exception.InvalidParameterValue(_(
                    "Conflict: iPXE is enabled, but cannot be used with node"
                    "%(node_uuid)s configured to use UEFI boot") %
                    {'node_uuid': node.uuid})

        if boot_mode == 'uefi':
            validate_boot_option_for_uefi(node)

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            validate_boot_parameters_for_trusted_boot(node)

        _parse_driver_info(node)
        d_info = _parse_instance_info(node)
        if node.driver_internal_info.get('is_whole_disk_image'):
            props = []
        elif service_utils.is_glance_image(d_info['image_source']):
            props = ['kernel_id', 'ramdisk_id']
        else:
            props = ['kernel', 'ramdisk']
        deploy_utils.validate_image_properties(task.context, d_info, props)
Esempio n. 35
0
    def set_boot_device(self, task, device, persistent=False):
        """Set the boot device for the task's node.

        Set the boot device to use on next reboot of the node.

        :param task: a task from TaskManager.
        :param device: the boot device, one of
                       :mod:`ironic.common.boot_devices`.
        :param persistent: Boolean value. True if the boot device will
                           persist to all future boots, False if not.
                           Default: False. Ignored by this driver.
        :raises: InvalidParameterValue if an invalid boot device is
                 specified or if any connection parameters are incorrect.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: NotImplementedError if the virt_type does not support
            setting the boot device.
        :raises: NodeNotFound if could not find a VM corresponding to any
            of the provided MACs.

        """
        node = task.node
        driver_info = _parse_driver_info(node)
        if device not in self.get_supported_boot_devices(task):
            raise exception.InvalidParameterValue(
                _("Invalid boot device %s specified.") % device)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(node)

        node_name = _get_hosts_name_for_node(ssh_obj, driver_info)
        virt_type = driver_info['virt_type']
        use_headless = driver_info['use_headless']

        if virt_type == 'vbox':
            if use_headless:
                current_pstate = _get_power_status(ssh_obj, driver_info)
                if current_pstate == states.POWER_ON:
                    LOG.debug(
                        "Forcing VBox VM %s to power off "
                        "in order to set the boot device.", node_name)
                    _power_off(ssh_obj, driver_info)

        boot_device_map = _get_boot_device_map(driver_info['virt_type'])
        try:
            _set_boot_device(ssh_obj, driver_info, boot_device_map[device])
        except NotImplementedError:
            with excutils.save_and_reraise_exception():
                LOG.error(
                    _LE("Failed to set boot device for node %(node)s, "
                        "virt_type %(vtype)s does not support this "
                        "operation"), {
                            'node': node.uuid,
                            'vtype': driver_info['virt_type']
                        })
Esempio n. 36
0
def _link_mac_pxe_configs(task):
    """Link each MAC address with the PXE configuration file.

    :param task: A TaskManager instance.

    """
    pxe_config_file_path = get_pxe_config_file_path(task.node.uuid)
    for mac in driver_utils.get_node_mac_addresses(task):
        mac_path = _get_pxe_mac_path(mac)
        utils.unlink_without_raise(mac_path)
        utils.create_link_without_raise(pxe_config_file_path, mac_path)
Esempio n. 37
0
def _link_mac_pxe_configs(task):
    """Link each MAC address with the PXE configuration file.

    :param task: A TaskManager instance.

    """
    pxe_config_file_path = get_pxe_config_file_path(task.node.uuid)
    for mac in driver_utils.get_node_mac_addresses(task):
        mac_path = _get_pxe_mac_path(mac)
        utils.unlink_without_raise(mac_path)
        utils.create_link_without_raise(pxe_config_file_path, mac_path)
Esempio n. 38
0
    def set_boot_device(self, task, device, persistent=False):
        """Set the boot device for the task's node.

        Set the boot device to use on next reboot of the node.

        :param task: a task from TaskManager.
        :param device: the boot device, one of
                       :mod:`ironic.common.boot_devices`.
        :param persistent: Boolean value. True if the boot device will
                           persist to all future boots, False if not.
                           Default: False. Ignored by this driver.
        :raises: InvalidParameterValue if an invalid boot device is
                 specified or if any connection parameters are incorrect.
        :raises: MissingParameterValue if a required parameter is missing
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: NotImplementedError if the virt_type does not support
            setting the boot device.
        :raises: NodeNotFound if could not find a VM corresponding to any
            of the provided MACs.

        """
        node = task.node
        driver_info = _parse_driver_info(node)
        if device not in self.get_supported_boot_devices(task):
            raise exception.InvalidParameterValue(_(
                "Invalid boot device %s specified.") % device)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(node)

        node_name = _get_hosts_name_for_node(ssh_obj, driver_info)
        virt_type = driver_info['virt_type']
        use_headless = driver_info['use_headless']

        if virt_type == 'vbox':
            if use_headless:
                current_pstate = _get_power_status(ssh_obj, driver_info)
                if current_pstate == states.POWER_ON:
                    LOG.debug("Forcing VBox VM %s to power off "
                              "in order to set the boot device.",
                              node_name)
                    _power_off(ssh_obj, driver_info)

        boot_device_map = _get_boot_device_map(driver_info['virt_type'])
        try:
            _set_boot_device(ssh_obj, driver_info, boot_device_map[device])
        except NotImplementedError:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Failed to set boot device for node %(node)s, "
                              "virt_type %(vtype)s does not support this "
                              "operation"),
                          {'node': node.uuid,
                           'vtype': driver_info['virt_type']})
Esempio n. 39
0
def clean_up_pxe_config(task):
    """Clean up the TFTP environment for the task's node.

    :param task: A TaskManager instance.

    """
    LOG.debug("Cleaning up PXE config for node %s", task.node.uuid)

    for mac in driver_utils.get_node_mac_addresses(task):
        utils.unlink_without_raise(_get_pxe_mac_path(mac))

    utils.rmtree_without_raise(os.path.join(CONF.pxe.tftp_root,
                                            task.node.uuid))
Esempio n. 40
0
def clean_up_pxe_config(task):
    """Clean up the TFTP environment for the task's node.

    :param task: A TaskManager instance.

    """
    LOG.debug("Cleaning up PXE config for node %s", task.node.uuid)

    for mac in driver_utils.get_node_mac_addresses(task):
        utils.unlink_without_raise(_get_pxe_mac_path(mac))

    utils.rmtree_without_raise(os.path.join(CONF.pxe.tftp_root,
                                            task.node.uuid))
Esempio n. 41
0
    def validate(self, task):
        """Validate the PXE-specific info for booting deploy/instance images.

        This method validates the PXE-specific info for booting the
        ramdisk and instance on the node.  If invalid, raises an
        exception; otherwise returns None.

        :param task: a task from TaskManager.
        :returns: None
        :raises: InvalidParameterValue, if some parameters are invalid.
        :raises: MissingParameterValue, if some required parameters are
            missing.
        """
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.")
                % node.uuid)

        # TODO(TheJulia): Once ipxe support is remove from the pxe
        # interface, this can be removed.
        if CONF.pxe.ipxe_enabled:
            if (not CONF.deploy.http_url
                or not CONF.deploy.http_root):
                raise exception.MissingParameterValue(_(
                    "iPXE boot is enabled but no HTTP URL or HTTP "
                    "root was specified."))

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            validate_boot_parameters_for_trusted_boot(node)

        pxe_utils.parse_driver_info(node)
        # NOTE(TheJulia): If we're not writing an image, we can skip
        # the remainder of this method.
        if (not task.driver.storage.should_write_image(task)):
            return

        d_info = deploy_utils.get_image_instance_info(node)
        if (node.driver_internal_info.get('is_whole_disk_image')
                or deploy_utils.get_boot_option(node) == 'local'):
            props = []
        elif service_utils.is_glance_image(d_info['image_source']):
            props = ['kernel_id', 'ramdisk_id']
        else:
            props = ['kernel', 'ramdisk']
        deploy_utils.validate_image_properties(task.context, d_info, props)
Esempio n. 42
0
    def validate(self, task):
        """Validate the PXE-specific info for booting deploy/instance images.

        This method validates the PXE-specific info for booting the
        ramdisk and instance on the node.  If invalid, raises an
        exception; otherwise returns None.

        :param task: a task from TaskManager.
        :returns: None
        :raises: InvalidParameterValue, if some parameters are invalid.
        :raises: MissingParameterValue, if some required parameters are
            missing.
        """
        node = task.node

        if not driver_utils.get_node_mac_addresses(task):
            raise exception.MissingParameterValue(
                _("Node %s does not have any port associated with it.")
                % node.uuid)

        # TODO(TheJulia): Once ipxe support is remove from the pxe
        # interface, this can be removed.
        if CONF.pxe.ipxe_enabled:
            if (not CONF.deploy.http_url
                or not CONF.deploy.http_root):
                raise exception.MissingParameterValue(_(
                    "iPXE boot is enabled but no HTTP URL or HTTP "
                    "root was specified."))

        # Check the trusted_boot capabilities value.
        deploy_utils.validate_capabilities(node)
        if deploy_utils.is_trusted_boot_requested(node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            validate_boot_parameters_for_trusted_boot(node)

        pxe_utils.parse_driver_info(node)
        # NOTE(TheJulia): If we're not writing an image, we can skip
        # the remainder of this method.
        if (not task.driver.storage.should_write_image(task)):
            return

        d_info = deploy_utils.get_image_instance_info(node)
        if (node.driver_internal_info.get('is_whole_disk_image')
                or deploy_utils.get_boot_option(node) == 'local'):
            props = []
        elif service_utils.is_glance_image(d_info['image_source']):
            props = ['kernel_id', 'ramdisk_id']
        else:
            props = ['kernel', 'ramdisk']
        deploy_utils.validate_image_properties(task.context, d_info, props)
Esempio n. 43
0
def _create_pxe_config(task, pxe_info):
    """Generate pxe configuration file and link mac ports to it for
    tftp booting.
    """
    fileutils.ensure_tree(os.path.join(CONF.pxe.tftp_root, task.node.uuid))
    fileutils.ensure_tree(os.path.join(CONF.pxe.tftp_root, 'pxelinux.cfg'))

    pxe_config_file_path = _get_pxe_config_file_path(task.node.uuid)
    pxe_config = _build_pxe_config(task.node, pxe_info, task.context)
    utils.write_to_file(pxe_config_file_path, pxe_config)
    for port in driver_utils.get_node_mac_addresses(task):
        mac_path = _get_pxe_mac_path(port)
        utils.unlink_without_raise(mac_path)
        utils.create_link_without_raise(pxe_config_file_path, mac_path)
Esempio n. 44
0
def _link_mac_pxe_configs(task):
    """Link each MAC address with the PXE configuration file.

    :param task: A TaskManager instance.

    """

    def create_link(mac_path):
        ironic_utils.unlink_without_raise(mac_path)
        relative_source_path = os.path.relpath(pxe_config_file_path, os.path.dirname(mac_path))
        utils.create_link_without_raise(relative_source_path, mac_path)

    pxe_config_file_path = get_pxe_config_file_path(task.node.uuid)
    for mac in driver_utils.get_node_mac_addresses(task):
        create_link(_get_pxe_mac_path(mac))
Esempio n. 45
0
def _link_mac_pxe_configs(task):
    """Link each MAC address with the PXE configuration file.

    :param task: A TaskManager instance.

    """
    def create_link(mac_path):
        ironic_utils.unlink_without_raise(mac_path)
        relative_source_path = os.path.relpath(pxe_config_file_path,
                                               os.path.dirname(mac_path))
        utils.create_link_without_raise(relative_source_path, mac_path)

    pxe_config_file_path = get_pxe_config_file_path(task.node.uuid)
    for mac in driver_utils.get_node_mac_addresses(task):
        create_link(_get_pxe_mac_path(mac))
Esempio n. 46
0
 def test_get_node_mac_addresses(self):
     ports = []
     ports.append(
         obj_utils.create_test_port(
             self.context, address="aa:bb:cc", uuid="bb43dc0b-03f2-4d2e-ae87-c02d7f33cc53", node_id=self.node.id
         )
     )
     ports.append(
         obj_utils.create_test_port(
             self.context, address="dd:ee:ff", uuid="4fc26c0b-03f2-4d2e-ae87-c02d7f33c234", node_id=self.node.id
         )
     )
     with task_manager.acquire(self.context, self.node.uuid) as task:
         node_macs = driver_utils.get_node_mac_addresses(task)
     self.assertEqual(sorted([p.address for p in ports]), sorted(node_macs))
Esempio n. 47
0
File: pxe.py Progetto: nkaul/ironic
def _create_pxe_config(task, node, pxe_info):
    """Generate pxe configuration file and link mac ports to it for
    tftp booting.
    """
    fileutils.ensure_tree(os.path.join(CONF.pxe.tftp_root,
                                       node.uuid))
    fileutils.ensure_tree(os.path.join(CONF.pxe.tftp_root,
                                       'pxelinux.cfg'))

    pxe_config_file_path = _get_pxe_config_file_path(node.uuid)
    pxe_config = _build_pxe_config(node, pxe_info, task.context)
    utils.write_to_file(pxe_config_file_path, pxe_config)
    for port in driver_utils.get_node_mac_addresses(task, node):
        mac_path = _get_pxe_mac_path(port)
        utils.unlink_without_raise(mac_path)
        utils.create_link_without_raise(pxe_config_file_path, mac_path)
Esempio n. 48
0
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.
        Get the image info from glance, config the mac for the xcat
        use ssh and iptables to disable dhcp on network node
        :param task: a TaskManager instance containing the node to act on.
        """
        # TODO(deva): optimize this if rerun on existing files
        d_info = _parse_deploy_info(task.node)
        i_info = task.node.instance_info
        image_id = d_info['image_source']
        try:
            glance_service = service.Service(version=1, context=task.context)
            image_name = glance_service.show(image_id)['name']
            i_info['image_name'] = image_name
        except (exception.GlanceConnectionFailed, exception.ImageNotAuthorized,
                exception.Invalid):
            LOG.warning(
                _("Failed to connect to Glance to get the properties "
                  "of the image %s") % image_id)

        node_mac_addresses = driver_utils.get_node_mac_addresses(task)
        vif_ports_info = xcat_neutron.get_ports_info_from_neutron(task)
        try:
            network_info = self._get_deploy_network_info(
                vif_ports_info, node_mac_addresses)
        except (xcat_exception.GetNetworkFixedIPFailure,
                xcat_exception.GetNetworkIdFailure):
            LOG.error(_("Failed to get network info"))
            return
        if not network_info:
            LOG.error(_("Failed to get network info"))
            return

        fixed_ip_address = network_info['fixed_ip_address']
        deploy_mac_address = network_info['mac_address']
        network_id = network_info['network_id']

        i_info['fixed_ip_address'] = fixed_ip_address
        i_info['network_id'] = network_id
        i_info['deploy_mac_address'] = deploy_mac_address

        # use iptables to drop the dhcp mac of baremetal machine
        self._ssh_append_dhcp_rule(CONF.xcat.network_node_ip,
                                   CONF.xcat.ssh_port, CONF.xcat.ssh_user,
                                   CONF.xcat.ssh_password, network_id,
                                   deploy_mac_address)
        self._chdef_node_mac_address(d_info, deploy_mac_address)
Esempio n. 49
0
 def test_get_node_mac_addresses(self):
     ports = []
     ports.append(
         obj_utils.create_test_port(
             self.context,
             address='aa:bb:cc',
             uuid='bb43dc0b-03f2-4d2e-ae87-c02d7f33cc53',
             node_id=self.node.id))
     ports.append(
         obj_utils.create_test_port(
             self.context,
             address='dd:ee:ff',
             uuid='4fc26c0b-03f2-4d2e-ae87-c02d7f33c234',
             node_id=self.node.id))
     with task_manager.acquire(self.context, self.node.uuid) as task:
         node_macs = driver_utils.get_node_mac_addresses(task)
     self.assertEqual(sorted([p.address for p in ports]), sorted(node_macs))
    def validate(self, task):
        """Check that the node's 'driver_info' is valid.

        Check that the node's 'driver_info' contains the requisite fields
        and that an Libvirt connection to the node can be established.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect or if failed to connect to the libvirt socket.
        :raises: MissingParameterValue if no ports are enrolled for the given
                 node.
       """

        if not driver_utils.get_node_mac_addresses(task):
            raise ir_exc.MissingParameterValue(
                _("Node %s does not have any ports associated with it") %
                task.node.uuid)
Esempio n. 51
0
    def get_power_state(self, task):
        """Get the current power state of the task's node.

        Poll the host for the current power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: power state. One of :class:`ironic.common.states`.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect.
        :raises: NodeNotFound.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        """
        driver_info = _parse_driver_info(task.node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(task.node)
        return _get_power_status(ssh_obj, driver_info)
Esempio n. 52
0
    def validate(self, task):
        """Check that the node's 'driver_info' is valid.

        Check that the node's 'driver_info' contains the requisite fields
        and that an Libvirt connection to the node can be established.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect or if failed to connect to the libvirt socket.
        :raises: MissingParameterValue if no ports are enrolled for the given
                 node.
       """

        if not driver_utils.get_node_mac_addresses(task):
            raise ir_exc.MissingParameterValue(
                _("Node %s does not have any ports associated with it"
                  ) % task.node.uuid)
Esempio n. 53
0
    def get_power_state(self, task):
        """Get the current power state of the task's node.

        Poll the host for the current power state of the task's node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: power state. One of :class:`ironic.common.states`.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect.
        :raises: NodeNotFound.
        :raises: SSHCommandFailed on an error from ssh.
        :raises: SSHConnectFailed if ssh failed to connect to the node.
        """
        driver_info = _parse_driver_info(task.node)
        driver_info['macs'] = driver_utils.get_node_mac_addresses(task)
        ssh_obj = _get_connection(task.node)
        return _get_power_status(ssh_obj, driver_info)
Esempio n. 54
0
    def _wait_for_node_deploy(self, task):
        """Wait for xCAT node deployment to complete."""
        locals = {'errstr': ''}
        driver_info = _parse_deploy_info(task.node)
        node_mac_addrsses = driver_utils.get_node_mac_addresses(task)
        i_info = task.node.instance_info

        def _wait_for_deploy():
            out, err = xcat_util.exec_xcatcmd(driver_info, 'nodels',
                                              'nodelist.status')
            if err:
                locals['errstr'] = _(
                    "Error returned when quering node status"
                    " for node %s:%s") % (driver_info['xcat_node'], err)
                LOG.warning(locals['errstr'])
                raise loopingcall.LoopingCallDone()

            if out:
                node, status = out.split(": ")
                status = status.strip()
                if status == "booted":
                    LOG.info(
                        _("Deployment for node %s completed.") %
                        driver_info['xcat_node'])
                    raise loopingcall.LoopingCallDone()

            if (CONF.xcat.deploy_timeout and timeutils.utcnow() > expiration):
                locals['errstr'] = _(
                    "Timeout while waiting for"
                    " deployment of node %s.") % driver_info['xcat_node']
                LOG.warning(locals['errstr'])
                raise loopingcall.LoopingCallDone()

        expiration = timeutils.utcnow() + datetime.timedelta(
            seconds=CONF.xcat.deploy_timeout)
        timer = loopingcall.FixedIntervalLoopingCall(_wait_for_deploy)
        # default check every 10 seconds
        timer.start(interval=CONF.xcat.deploy_checking_interval).wait()

        if locals['errstr']:
            raise xcat_exception.xCATDeploymentFailure(locals['errstr'])
        # deploy end, delete the dhcp rule for xcat
        self._ssh_delete_dhcp_rule(CONF.xcat.network_node_ip,
                                   CONF.xcat.ssh_port, CONF.xcat.ssh_user,
                                   CONF.xcat.ssh_password,
                                   i_info['network_id'], node_mac_addrsses[0])
Esempio n. 55
0
    def validate(self, task):
        """Check that the node's 'driver_info' is valid.

        Check that the node's 'driver_info' contains the requisite fields
        and that an SSH connection to the node can be established.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any connection parameters are
            incorrect or if ssh failed to connect to the node.
        """
        if not driver_utils.get_node_mac_addresses(task):
            raise exception.InvalidParameterValue(_("Node %s does not have "
                              "any port associated with it.") % task.node.uuid)
        try:
            _get_connection(task.node)
        except exception.SSHConnectFailed as e:
            raise exception.InvalidParameterValue(_("SSH connection cannot"
                                                    " be established: %s") % e)
Esempio n. 56
0
def _link_mac_pxe_configs(task):
    """Link each MAC address with the PXE configuration file.

    :param task: A TaskManager instance.

    """

    def create_link(mac_path):
        utils.unlink_without_raise(mac_path)
        utils.create_link_without_raise(pxe_config_file_path, mac_path)

    pxe_config_file_path = get_pxe_config_file_path(task.node.uuid)
    for mac in driver_utils.get_node_mac_addresses(task):
        create_link(_get_pxe_mac_path(mac))
        # TODO(lucasagomes): Backward compatibility with :hexraw,
        # to be removed in Mitaka.
        # see: https://bugs.launchpad.net/ironic/+bug/1441710
        if CONF.pxe.ipxe_enabled:
            create_link(_get_pxe_mac_path(mac, delimiter=''))
Esempio n. 57
0
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.
        Get the image info from glance, config the mac for the xcat
        use ssh and iptables to disable dhcp on network node
        :param task: a TaskManager instance containing the node to act on.
        """
        # TODO(deva): optimize this if rerun on existing files
        d_info = _parse_deploy_info(task.node)
        i_info = task.node.instance_info
        image_id = d_info['image_source']
        try:
            glance_service = service.Service(version=1, context=task.context)
            image_name = glance_service.show(image_id)['name']
            i_info['image_name'] = image_name
        except (exception.GlanceConnectionFailed,
                exception.ImageNotAuthorized,
                exception.Invalid):
            LOG.warning(_("Failed to connect to Glance to get the properties "
                "of the image %s") % image_id)

        node_mac_addresses = driver_utils.get_node_mac_addresses(task)
        vif_ports_info = xcat_neutron.get_ports_info_from_neutron(task)
        try:
            network_info = self._get_deploy_network_info(vif_ports_info, node_mac_addresses)
        except (xcat_exception.GetNetworkFixedIPFailure,xcat_exception.GetNetworkIdFailure):
            LOG.error(_("Failed to get network info"))
            return
        if not network_info:
            LOG.error(_("Failed to get network info"))
            return

        fixed_ip_address = network_info['fixed_ip_address']
        deploy_mac_address = network_info['mac_address']
        network_id = network_info['network_id']

        i_info['fixed_ip_address'] = fixed_ip_address
        i_info['network_id'] = network_id
        i_info['deploy_mac_address'] = deploy_mac_address

        # use iptables to drop the dhcp mac of baremetal machine
        self._ssh_append_dhcp_rule(CONF.xcat.network_node_ip,CONF.xcat.ssh_port,CONF.xcat.ssh_user,
                                     CONF.xcat.ssh_password,network_id,deploy_mac_address)
        self._chdef_node_mac_address(d_info,deploy_mac_address)
Esempio n. 58
0
 def test_get_node_mac_addresses(self):
     ports = []
     ports.append(
         self.dbapi.create_port(
             db_utils.get_test_port(
                 id=6,
                 address='aa:bb:cc',
                 uuid='bb43dc0b-03f2-4d2e-ae87-c02d7f33cc53',
                 node_id=self.node.id)))
     ports.append(
         self.dbapi.create_port(
             db_utils.get_test_port(
                 id=7,
                 address='dd:ee:ff',
                 uuid='4fc26c0b-03f2-4d2e-ae87-c02d7f33c234',
                 node_id=self.node.id)))
     with task_manager.acquire(self.context, [self.node.uuid]) as task:
         node_macs = driver_utils.get_node_mac_addresses(task)
     self.assertEqual(sorted([p.address for p in ports]), sorted(node_macs))
Esempio n. 59
0
    def _wait_for_node_deploy(self, task):
        """Wait for xCAT node deployment to complete."""
        locals = {'errstr':''}
        driver_info = _parse_deploy_info(task.node)
        node_mac_addrsses = driver_utils.get_node_mac_addresses(task)
        i_info = task.node.instance_info

        def _wait_for_deploy():
            out,err = xcat_util.exec_xcatcmd(driver_info,'nodels','nodelist.status')
            if err:
                locals['errstr'] = _("Error returned when quering node status"
                           " for node %s:%s") % (driver_info['xcat_node'], err)
                LOG.warning(locals['errstr'])
                raise loopingcall.LoopingCallDone()

            if out:
                node,status = out.split(": ")
                status = status.strip()
                if status == "booted":
                    LOG.info(_("Deployment for node %s completed.")
                             % driver_info['xcat_node'])
                    raise loopingcall.LoopingCallDone()

            if (CONF.xcat.deploy_timeout and
                    timeutils.utcnow() > expiration):
                locals['errstr'] = _("Timeout while waiting for"
                           " deployment of node %s.") % driver_info['xcat_node']
                LOG.warning(locals['errstr'])
                raise loopingcall.LoopingCallDone()

        expiration = timeutils.utcnow() + datetime.timedelta(
                seconds=CONF.xcat.deploy_timeout)
        timer = loopingcall.FixedIntervalLoopingCall(_wait_for_deploy)
        # default check every 10 seconds
        timer.start(interval=CONF.xcat.deploy_checking_interval).wait()

        if locals['errstr']:
            raise xcat_exception.xCATDeploymentFailure(locals['errstr'])
        # deploy end, delete the dhcp rule for xcat
        self._ssh_delete_dhcp_rule(CONF.xcat.network_node_ip,CONF.xcat.ssh_port,CONF.xcat.ssh_user,
                                     CONF.xcat.ssh_password,i_info['network_id'],node_mac_addrsses[0])
Esempio n. 60
0
File: pxe.py Progetto: nkaul/ironic
    def validate(self, task, node):
        """Validate the driver-specific Node deployment info.

        :param task: a task from TaskManager.
        :param node: a single Node to validate.
        :returns: InvalidParameterValue.
        """
        if not driver_utils.get_node_mac_addresses(task, node):
            raise exception.InvalidParameterValue(_("Node %s does not have "
                                "any port associated with it.") % node.uuid)
        _parse_driver_info(node)

        # Try to get the URL of the Ironic API
        try:
            # TODO(lucasagomes): Validate the format of the URL
            CONF.conductor.api_url or keystone.get_service_url()
        except (exception.CatalogFailure,
                exception.CatalogNotFound,
                exception.CatalogUnauthorized):
            raise exception.InvalidParameterValue(_(
                "Couldn't get the URL of the Ironic API service from the "
                "configuration file or keystone catalog."))