Example #1
0
 def test_is_glance_image(self):
     image_href = 'uuid'
     self.assertTrue(service_utils.is_glance_image(image_href))
     image_href = 'glance://uuid'
     self.assertTrue(service_utils.is_glance_image(image_href))
     image_href = 'http://aaa/bbb'
     self.assertFalse(service_utils.is_glance_image(image_href))
     image_href = None
     self.assertFalse(service_utils.is_glance_image(image_href))
Example #2
0
 def test_is_glance_image(self):
     image_href = 'uuid'
     self.assertTrue(service_utils.is_glance_image(image_href))
     image_href = 'glance://uuid'
     self.assertTrue(service_utils.is_glance_image(image_href))
     image_href = 'http://aaa/bbb'
     self.assertFalse(service_utils.is_glance_image(image_href))
     image_href = None
     self.assertFalse(service_utils.is_glance_image(image_href))
 def test_is_glance_image(self):
     image_href = u'uui\u0111'
     self.assertFalse(service_utils.is_glance_image(image_href))
     image_href = u'733d1c44-a2ea-414b-aca7-69decf20d810'
     self.assertTrue(service_utils.is_glance_image(image_href))
     image_href = u'glance://uui\u0111'
     self.assertTrue(service_utils.is_glance_image(image_href))
     image_href = 'http://aaa/bbb'
     self.assertFalse(service_utils.is_glance_image(image_href))
     image_href = None
     self.assertFalse(service_utils.is_glance_image(image_href))
Example #4
0
 def test_is_glance_image(self):
     image_href = u'uui\u0111'
     self.assertFalse(service_utils.is_glance_image(image_href))
     image_href = u'733d1c44-a2ea-414b-aca7-69decf20d810'
     self.assertTrue(service_utils.is_glance_image(image_href))
     image_href = u'glance://uui\u0111'
     self.assertTrue(service_utils.is_glance_image(image_href))
     image_href = 'http://aaa/bbb'
     self.assertFalse(service_utils.is_glance_image(image_href))
     image_href = None
     self.assertFalse(service_utils.is_glance_image(image_href))
Example #5
0
def start_deploy(task, manager, configdrive=None, event='deploy'):
    """Start deployment or rebuilding on a node.

    This function does not check the node suitability for deployment, it's left
    up to the caller.

    :param task: a TaskManager instance.
    :param manager: a ConductorManager to run tasks on.
    :param configdrive: a configdrive, if requested.
    :param event: event to process: deploy or rebuild.
    """
    node = task.node

    if event == 'rebuild':
        # Note(gilliard) Clear these to force the driver to
        # check whether they have been changed in glance
        # NOTE(vdrok): If image_source is not from Glance we should
        # not clear kernel and ramdisk as they're input manually
        if glance_utils.is_glance_image(
                node.instance_info.get('image_source')):
            instance_info = node.instance_info
            instance_info.pop('kernel', None)
            instance_info.pop('ramdisk', None)
            node.instance_info = instance_info

    # Infer the image type to make sure the deploy driver
    # validates only the necessary variables for different
    # image types.
    # NOTE(sirushtim): The iwdi variable can be None. It's up to
    # the deploy driver to validate this.
    iwdi = images.is_whole_disk_image(task.context, node.instance_info)
    driver_internal_info = node.driver_internal_info
    driver_internal_info['is_whole_disk_image'] = iwdi
    node.driver_internal_info = driver_internal_info
    node.save()

    try:
        task.driver.power.validate(task)
        task.driver.deploy.validate(task)
        utils.validate_instance_info_traits(task.node)
        conductor_steps.validate_deploy_templates(task, skip_missing=True)
    except exception.InvalidParameterValue as e:
        raise exception.InstanceDeployFailure(
            _("Failed to validate deploy or power info for node "
              "%(node_uuid)s. Error: %(msg)s") % {
                  'node_uuid': node.uuid,
                  'msg': e
              },
            code=e.code)

    try:
        task.process_event(event,
                           callback=manager._spawn_worker,
                           call_args=(do_node_deploy, task,
                                      manager.conductor.id, configdrive),
                           err_handler=utils.provisioning_error_handler)
    except exception.InvalidState:
        raise exception.InvalidStateRequested(action=event,
                                              node=task.node.uuid,
                                              state=task.node.provision_state)
Example #6
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, if config option has invalid value.
        :raises: IRMCSharedFileSystemNotMounted, if shared file system is
            not mounted.
        :raises: InvalidParameterValue, if some information is invalid.
        :raises: MissingParameterValue if 'kernel_id' and 'ramdisk_id' are
            missing in the Glance image, or if 'kernel' and 'ramdisk' are
            missing in the Non Glance image.
        """
        check_share_fs_mounted()

        self._validate_volume_boot(task)
        if not task.driver.storage.should_write_image(task):
            LOG.debug(
                'Node %(node)s skips image validation because of '
                'booting from a remote volume.', {'node': task.node.uuid})
            return

        d_info = _parse_deploy_info(task.node)
        if task.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)
Example #7
0
File: boot.py Project: LZMWL/ironic
    def _validate_instance_info(cls, task):
        """Validate instance image information for the task's node.

        This method validates whether the 'instance_info' property of the
        supplied node contains the required information for this driver.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any parameters are incorrect
        :raises: MissingParameterValue if some mandatory information
            is missing on the node
        """
        node = task.node

        d_info = cls._parse_deploy_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)
def build_instance_info_for_deploy(task):
    """Build instance_info necessary for deploying to a node."""
    node = task.node
    instance_info = node.instance_info

    image_source = instance_info['image_source']
    if service_utils.is_glance_image(image_source):
        glance = image_service.GlanceImageService(version=2,
                                                  context=task.context)
        image_info = glance.show(image_source)
        swift_temp_url = glance.swift_temp_url(image_info)
        LOG.debug('Got image info: %(info)s for node %(node)s.',
                  {'info': image_info, 'node': node.uuid})
        instance_info['image_url'] = swift_temp_url
        instance_info['image_checksum'] = image_info['checksum']
        instance_info['image_disk_format'] = image_info['disk_format']
    else:
        try:
            image_service.HttpImageService().validate_href(image_source)
        except exception.ImageRefValidationFailed:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Ansible deploy supports only HTTP(S) URLs as "
                              "instance_info['image_source']. Either %s "
                              "is not a valid HTTP(S) URL or "
                              "is not reachable."), image_source)
        instance_info['image_url'] = image_source

    return instance_info
Example #9
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.
        """
        self._validate_common(task)

        # 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

        node = task.node
        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)
Example #10
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, if some information is invalid.
        :raises: MissingParameterValue if 'kernel_id' and 'ramdisk_id' are
            missing in the Glance image or 'kernel' and 'ramdisk' not provided
            in instance_info for non-Glance image.
        """
        node = task.node
        boot_option = deploy_utils.get_boot_option(node)
        boot_iso = node.instance_info.get('ilo_boot_iso')
        if (boot_option == "ramdisk" and boot_iso):
            if not service_utils.is_glance_image(boot_iso):
                try:
                    image_service.HttpImageService().validate_href(boot_iso)
                except exception.ImageRefValidationFailed:
                    with excutils.save_and_reraise_exception():
                        LOG.error("Virtual media deploy with 'ramdisk' "
                                  "boot_option accepts only Glance images or "
                                  "HTTP(S) URLs as "
                                  "instance_info['ilo_boot_iso']. Either %s "
                                  "is not a valid HTTP(S) URL or is not "
                                  "reachable.", boot_iso)
            return

        _validate_driver_info(task)

        if not task.driver.storage.should_write_image(task):
            return
        else:
            _validate_instance_image_info(task)
Example #11
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, if config option has invalid value.
        :raises: IRMCSharedFileSystemNotMounted, if shared file system is
            not mounted.
        :raises: InvalidParameterValue, if some information is invalid.
        :raises: MissingParameterValue if 'kernel_id' and 'ramdisk_id' are
            missing in the Glance image, or if 'kernel' and 'ramdisk' are
            missing in the Non Glance image.
        """
        _check_share_fs_mounted()
        iscsi_deploy.validate(task)

        d_info = _parse_deploy_info(task.node)
        if task.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)
        deploy_utils.validate_capabilities(task.node)
Example #12
0
    def _validate_instance_info(self, task):
        """Validate instance image information for the task's node.

        This method validates whether the 'instance_info' property of the
        supplied node contains the required information for this driver.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if any parameters are incorrect
        :raises: MissingParameterValue if some mandatory information
            is missing on the node
        """
        node = task.node

        # NOTE(dtantsur): if we're are writing an image with local boot
        # the boot interface does not care about image parameters and
        # must not validate them.
        if (not task.driver.storage.should_write_image(task)
                or deploy_utils.get_boot_option(node) == 'local'):
            return

        d_info = _parse_deploy_info(node)

        if node.driver_internal_info.get('is_whole_disk_image'):
            props = []
        elif d_info.get('boot_iso'):
            props = ['boot_iso']
        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)
Example #13
0
def build_deploy_pxe_options(task,
                             pxe_info,
                             mode='deploy',
                             ipxe_enabled=False):
    pxe_opts = {}
    node = task.node
    kernel_label = '%s_kernel' % mode
    ramdisk_label = '%s_ramdisk' % mode
    for label, option in ((kernel_label, 'deployment_aki_path'),
                          (ramdisk_label, 'deployment_ari_path')):
        if ipxe_enabled:
            image_href = pxe_info[label][0]
            if (CONF.pxe.ipxe_use_swift
                    and service_utils.is_glance_image(image_href)):
                pxe_opts[option] = images.get_temp_url_for_glance_image(
                    task.context, image_href)
            else:
                pxe_opts[option] = '/'.join(
                    [CONF.deploy.http_url, node.uuid, label])
        else:
            pxe_opts[option] = get_path_relative_to_tftp_root(
                pxe_info[label][1])
    if ipxe_enabled:
        pxe_opts['initrd_filename'] = ramdisk_label
    return pxe_opts
Example #14
0
def build_instance_info_for_deploy(task):
    """Build instance_info necessary for deploying to a node.

    :param task: a TaskManager object containing the node
    :returns: a dictionary containing the properties to be updated
        in instance_info
    :raises: exception.ImageRefValidationFailed if image_source is not
        Glance href and is not HTTP(S) URL.
    """
    def validate_image_url(url, secret=False):
        """Validates image URL through the HEAD request.

        :param url: URL to be validated
        :param secret: if URL is secret (e.g. swift temp url),
            it will not be shown in logs.
        """
        try:
            image_service.HttpImageService().validate_href(url, secret)
        except exception.ImageRefValidationFailed as e:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Agent deploy supports only HTTP(S) URLs as "
                              "instance_info['image_source'] or swift "
                              "temporary URL. Either the specified URL is not "
                              "a valid HTTP(S) URL or is not reachable "
                              "for node %(node)s. Error: %(msg)s"),
                          {'node': node.uuid, 'msg': e})
    node = task.node
    instance_info = node.instance_info
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    image_source = instance_info['image_source']
    if service_utils.is_glance_image(image_source):
        glance = image_service.GlanceImageService(version=2,
                                                  context=task.context)
        image_info = glance.show(image_source)
        LOG.debug('Got image info: %(info)s for node %(node)s.',
                  {'info': image_info, 'node': node.uuid})
        swift_temp_url = glance.swift_temp_url(image_info)
        validate_image_url(swift_temp_url, secret=True)
        instance_info['image_url'] = swift_temp_url
        instance_info['image_checksum'] = image_info['checksum']
        instance_info['image_disk_format'] = image_info['disk_format']
        instance_info['image_container_format'] = (
            image_info['container_format'])
        instance_info['image_tags'] = image_info.get('tags', [])
        instance_info['image_properties'] = image_info['properties']

        if not iwdi:
            instance_info['kernel'] = image_info['properties']['kernel_id']
            instance_info['ramdisk'] = image_info['properties']['ramdisk_id']
    else:
        validate_image_url(image_source)
        instance_info['image_url'] = image_source

    if not iwdi:
        instance_info['image_type'] = 'partition'
        i_info = parse_instance_info(node)
        instance_info.update(i_info)
    else:
        instance_info['image_type'] = 'whole-disk-image'
    return instance_info
Example #15
0
def _validate(task):
    """Validate the prerequisites for virtual media based deploy.

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

    :param task: a TaskManager instance containing the node to act on.
    :raises: InvalidParameterValue if any parameters are incorrect
    :raises: MissingParameterValue if some mandatory information
        is missing on the node
    """
    node = task.node
    ilo_common.parse_driver_info(node)
    if 'ilo_deploy_iso' not in node.driver_info:
        raise exception.MissingParameterValue(_(
            "Missing 'ilo_deploy_iso' parameter in node's 'driver_info'."))
    deploy_iso = node.driver_info['ilo_deploy_iso']
    if not service_utils.is_glance_image(deploy_iso):
        try:
            image_service.HttpImageService().validate_href(deploy_iso)
        except exception.ImageRefValidationFailed:
            raise exception.InvalidParameterValue(_(
                "Virtual media deploy accepts only Glance images or "
                "HTTP(S) as driver_info['ilo_deploy_iso']. Either '%s' "
                "is not a glance UUID or not a valid HTTP(S) URL or "
                "the given URL is not reachable.") % deploy_iso)
Example #16
0
def _validate(task):
    """Validate the prerequisites for virtual media based deploy.

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

    :param task: a TaskManager instance containing the node to act on.
    :raises: InvalidParameterValue if any parameters are incorrect
    :raises: MissingParameterValue if some mandatory information
        is missing on the node
    """
    node = task.node
    ilo_common.parse_driver_info(node)
    if 'ilo_deploy_iso' not in node.driver_info:
        raise exception.MissingParameterValue(_(
            "Missing 'ilo_deploy_iso' parameter in node's 'driver_info'."))
    deploy_iso = node.driver_info['ilo_deploy_iso']
    if not service_utils.is_glance_image(deploy_iso):
        try:
            image_service.HttpImageService().validate_href(deploy_iso)
        except exception.ImageRefValidationFailed:
            raise exception.InvalidParameterValue(_(
                "Virtual media deploy accepts only Glance images or "
                "HTTP(S) as driver_info['ilo_deploy_iso']. Either '%s' "
                "is not a glance UUID or not a valid HTTP(S) URL or "
                "the given URL is not reachable.") % deploy_iso)
Example #17
0
def get_image_instance_info(node):
    """Gets the image information from the node.

    Get image information for the given node instance from its
    'instance_info' property.

    :param node: a single Node.
    :returns: A dict with required image properties retrieved from
        node's 'instance_info'.
    :raises: MissingParameterValue, if image_source is missing in node's
        instance_info. Also raises same exception if kernel/ramdisk is
        missing in instance_info for non-glance images.
    """
    info = {}
    info['image_source'] = node.instance_info.get('image_source')

    is_whole_disk_image = node.driver_internal_info.get('is_whole_disk_image')
    if not is_whole_disk_image:
        if not service_utils.is_glance_image(info['image_source']):
            info['kernel'] = node.instance_info.get('kernel')
            info['ramdisk'] = node.instance_info.get('ramdisk')

    error_msg = (_("Cannot validate image information for node %s because one "
                   "or more parameters are missing from its instance_info") %
                 node.uuid)
    check_for_missing_params(info, error_msg)

    return info
Example #18
0
def _delete_master_path_if_stale(master_path, href, ctx):
    """Delete image from cache if it is not up to date with href contents.

    :param master_path: path to an image in master cache
    :param href: image href
    :param ctx: context to use
    :returns: True if master_path is up to date with href contents,
        False if master_path was stale and was deleted or it didn't exist
    """
    if service_utils.is_glance_image(href):
        # Glance image contents cannot be updated without changing image's UUID
        return os.path.exists(master_path)
    if os.path.exists(master_path):
        img_service = image_service.get_image_service(href, context=ctx)
        img_mtime = img_service.show(href).get('updated_at')
        if not img_mtime:
            # This means that href is not a glance image and doesn't have an
            # updated_at attribute
            LOG.warning("Image service couldn't determine last "
                        "modification time of %(href)s, considering "
                        "cached image up to date.", {'href': href})
            return True
        master_mtime = utils.unix_file_modification_datetime(master_path)
        if img_mtime <= master_mtime:
            return True
        # Delete image from cache as it is outdated
        LOG.info('Image %(href)s was last modified at %(remote_time)s. '
                 'Deleting the cached copy "%(cached_file)s since it was '
                 'last modified at %(local_time)s and may be outdated.',
                 {'href': href, 'remote_time': img_mtime,
                  'local_time': master_mtime, 'cached_file': master_path})

        os.unlink(master_path)
    return False
Example #19
0
def get_image_instance_info(node):
    """Gets the image information from the node.

    Get image information for the given node instance from its
    'instance_info' property.

    :param node: a single Node.
    :returns: A dict with required image properties retrieved from
        node's 'instance_info'.
    :raises: MissingParameterValue, if image_source is missing in node's
        instance_info. Also raises same exception if kernel/ramdisk is
        missing in instance_info for non-glance images.
    """
    info = {}
    info['image_source'] = node.instance_info.get('image_source')

    is_whole_disk_image = node.driver_internal_info.get('is_whole_disk_image')
    if not is_whole_disk_image:
        if not service_utils.is_glance_image(info['image_source']):
            info['kernel'] = node.instance_info.get('kernel')
            info['ramdisk'] = node.instance_info.get('ramdisk')

    error_msg = (_("Cannot validate image information for node %s because one "
                   "or more parameters are missing from its instance_info.")
                 % node.uuid)
    check_for_missing_params(info, error_msg)

    return info
Example #20
0
def is_whole_disk_image(ctx, instance_info):
    """Find out if the image is a partition image or a whole disk image.

    :param ctx: an admin context
    :param instance_info: a node's instance info dict

    :returns True for whole disk images and False for partition images
        and None on no image_source or Error.
    """
    image_source = instance_info.get('image_source')
    if not image_source:
        return

    is_whole_disk_image = False
    if glance_utils.is_glance_image(image_source):
        try:
            iproperties = get_image_properties(ctx, image_source)
        except Exception:
            return
        is_whole_disk_image = (not iproperties.get('kernel_id') and
                               not iproperties.get('ramdisk_id'))
    else:
        # Non glance image ref
        if (not instance_info.get('kernel') and
            not instance_info.get('ramdisk')):
            is_whole_disk_image = True

    return is_whole_disk_image
Example #21
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, if some information is invalid.
        :raises: MissingParameterValue if 'kernel_id' and 'ramdisk_id' are
            missing in the Glance image or 'kernel' and 'ramdisk' not provided
            in instance_info for non-Glance image.
        """
        node = task.node
        boot_option = deploy_utils.get_boot_option(node)
        boot_iso = node.instance_info.get('ilo_boot_iso')
        if (boot_option == "ramdisk" and boot_iso):
            if not service_utils.is_glance_image(boot_iso):
                try:
                    image_service.HttpImageService().validate_href(boot_iso)
                except exception.ImageRefValidationFailed:
                    with excutils.save_and_reraise_exception():
                        LOG.error("Virtual media deploy with 'ramdisk' "
                                  "boot_option accepts only Glance images or "
                                  "HTTP(S) URLs as "
                                  "instance_info['ilo_boot_iso']. Either %s "
                                  "is not a valid HTTP(S) URL or is not "
                                  "reachable.", boot_iso)
            return

        _validate_driver_info(task)

        if not task.driver.storage.should_write_image(task):
            return
        else:
            _validate_instance_image_info(task)
Example #22
0
def _delete_master_path_if_stale(master_path, href, ctx):
    """Delete image from cache if it is not up to date with href contents.

    :param master_path: path to an image in master cache
    :param href: image href
    :param ctx: context to use
    :returns: True if master_path is up to date with href contents,
        False if master_path was stale and was deleted or it didn't exist
    """
    if service_utils.is_glance_image(href):
        # Glance image contents cannot be updated without changing image's UUID
        return os.path.exists(master_path)
    if os.path.exists(master_path):
        img_service = image_service.get_image_service(href, context=ctx)
        img_mtime = img_service.show(href).get('updated_at')
        if not img_mtime:
            # This means that href is not a glance image and doesn't have an
            # updated_at attribute
            LOG.warn(_LW("Image service couldn't determine last "
                         "modification time of %(href)s, considering "
                         "cached image up to date."), {'href': href})
            return True
        master_mtime = utils.unix_file_modification_datetime(master_path)
        if img_mtime <= master_mtime:
            return True
        # Delete image from cache as it is outdated
        LOG.info(_LI('Image %(href)s was last modified at %(remote_time)s. '
                     'Deleting the cached copy "%(cached_file)s since it was '
                     'last modified at %(local_time)s and may be outdated.'),
                 {'href': href, 'remote_time': img_mtime,
                  'local_time': master_mtime, 'cached_file': master_path})

        os.unlink(master_path)
    return False
Example #23
0
def parse_instance_info(node):
    """Gets the instance specific Node deployment info.

    This method validates whether the 'instance_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 values.
    :raises: MissingParameterValue, if any of the required parameters are
        missing.
    :raises: InvalidParameterValue, if any of the parameters have invalid
        value.
    """
    info = node.instance_info
    i_info = {}
    i_info["image_source"] = info.get("image_source")
    is_whole_disk_image = node.driver_internal_info.get("is_whole_disk_image")
    if not is_whole_disk_image:
        if i_info["image_source"] and not glance_service_utils.is_glance_image(i_info["image_source"]):
            i_info["kernel"] = info.get("kernel")
            i_info["ramdisk"] = info.get("ramdisk")
    i_info["root_gb"] = info.get("root_gb")

    error_msg = _("Cannot validate iSCSI deploy. Some parameters were missing" " in node's instance_info")
    deploy_utils.check_for_missing_params(i_info, error_msg)

    # Internal use only
    i_info["deploy_key"] = info.get("deploy_key")

    i_info["swap_mb"] = info.get("swap_mb", 0)
    i_info["ephemeral_gb"] = info.get("ephemeral_gb", 0)
    err_msg_invalid = _(
        "Cannot validate parameter for iSCSI deploy. " "Invalid parameter %(param)s. Reason: %(reason)s"
    )
    for param in ("root_gb", "swap_mb", "ephemeral_gb"):
        try:
            int(i_info[param])
        except ValueError:
            reason = _("%s is not an integer value.") % i_info[param]
            raise exception.InvalidParameterValue(err_msg_invalid % {"param": param, "reason": reason})

    if is_whole_disk_image:
        if int(i_info["swap_mb"]) > 0 or int(i_info["ephemeral_gb"]) > 0:
            err_msg_invalid = _("Cannot deploy whole disk image with " "swap or ephemeral size set")
            raise exception.InvalidParameterValue(err_msg_invalid)
        return i_info

    i_info["ephemeral_format"] = info.get("ephemeral_format")
    i_info["configdrive"] = info.get("configdrive")

    if i_info["ephemeral_gb"] and not i_info["ephemeral_format"]:
        i_info["ephemeral_format"] = CONF.pxe.default_ephemeral_format

    preserve_ephemeral = info.get("preserve_ephemeral", False)
    try:
        i_info["preserve_ephemeral"] = strutils.bool_from_string(preserve_ephemeral, strict=True)
    except ValueError as e:
        raise exception.InvalidParameterValue(err_msg_invalid % {"param": "preserve_ephemeral", "reason": e})
    return i_info
Example #24
0
def _parse_instance_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.
    :raises: MissingParameterValue, image_source is missing in node's
        instance_info. Also raises same exception if kernel/ramdisk is
        missing in instance_info for non-glance images.
    """
    info = {}
    info['image_source'] = node.instance_info.get('image_source')

    is_whole_disk_image = node.driver_internal_info.get('is_whole_disk_image')
    if not is_whole_disk_image:
        if not service_utils.is_glance_image(info['image_source']):
            info['kernel'] = node.instance_info.get('kernel')
            info['ramdisk'] = node.instance_info.get('ramdisk')

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

    return info
Example #25
0
def _get_ipxe_kernel_ramdisk(task, pxe_info):
    pxe_opts = {}
    node = task.node

    for label, option in (('deploy_kernel', 'deployment_aki_path'),
                          ('deploy_ramdisk', 'deployment_ari_path')):
        image_href = pxe_info[label][0]
        if (CONF.pxe.ipxe_use_swift and
            service_utils.is_glance_image(image_href)):
                pxe_opts[option] = images.get_temp_url_for_glance_image(
                    task.context, image_href)
        else:
            pxe_opts[option] = '/'.join([CONF.deploy.http_url, node.uuid,
                                         label])
    # NOTE(pas-ha) do not use Swift TempURLs for kernel and ramdisk
    # of user image when boot_option is not local,
    # as this will break instance reboot later when temp urls have timed out.
    if 'kernel' in pxe_info:
        pxe_opts['aki_path'] = '/'.join(
            [CONF.deploy.http_url, node.uuid, 'kernel'])
    if 'ramdisk' in pxe_info:
        pxe_opts['ari_path'] = '/'.join(
            [CONF.deploy.http_url, node.uuid, 'ramdisk'])

    return pxe_opts
Example #26
0
def build_instance_info_for_deploy(task):
    """Build instance_info necessary for deploying to a node."""
    node = task.node
    instance_info = node.instance_info

    image_source = instance_info['image_source']
    if service_utils.is_glance_image(image_source):
        glance = image_service.GlanceImageService(version=2,
                                                  context=task.context)
        image_info = glance.show(image_source)
        swift_temp_url = glance.swift_temp_url(image_info)
        LOG.debug('Got image info: %(info)s for node %(node)s.', {
            'info': image_info,
            'node': node.uuid
        })
        instance_info['image_url'] = swift_temp_url
        instance_info['image_checksum'] = image_info['checksum']
        instance_info['image_disk_format'] = image_info['disk_format']
    else:
        try:
            image_service.HttpImageService().validate_href(image_source)
        except exception.ImageRefValidationFailed:
            with excutils.save_and_reraise_exception():
                LOG.error(
                    _LE("Ansible deploy supports only HTTP(S) URLs as "
                        "instance_info['image_source']. Either %s "
                        "is not a valid HTTP(S) URL or "
                        "is not reachable."), image_source)
        instance_info['image_url'] = image_source

    return instance_info
Example #27
0
def is_whole_disk_image(ctx, instance_info):
    """Find out if the image is a partition image or a whole disk image.

    :param ctx: an admin context
    :param instance_info: a node's instance info dict

    :returns: True for whole disk images and False for partition images
        and None on no image_source or Error.
    """
    image_source = instance_info.get('image_source')
    if not image_source:
        return

    is_whole_disk_image = False
    if glance_utils.is_glance_image(image_source):
        try:
            iproperties = get_image_properties(ctx, image_source)
        except Exception:
            return
        is_whole_disk_image = (not iproperties.get('kernel_id')
                               and not iproperties.get('ramdisk_id'))
    else:
        # Non glance image ref
        if (not instance_info.get('kernel')
                and not instance_info.get('ramdisk')):
            is_whole_disk_image = True

    return is_whole_disk_image
Example #28
0
File: pxe.py Project: naterh/ironic
def _parse_instance_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.
    :raises: MissingParameterValue, image_source is missing in node's
        instance_info. Also raises same exception if kernel/ramdisk is
        missing in instance_info for non-glance images.
    """
    info = {}
    info['image_source'] = node.instance_info.get('image_source')

    is_whole_disk_image = node.driver_internal_info.get('is_whole_disk_image')
    if not is_whole_disk_image:
        if not service_utils.is_glance_image(info['image_source']):
            info['kernel'] = node.instance_info.get('kernel')
            info['ramdisk'] = node.instance_info.get('ramdisk')

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

    return info
Example #29
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, if config option has invalid value.
        :raises: IRMCSharedFileSystemNotMounted, if shared file system is
            not mounted.
        :raises: InvalidParameterValue, if some information is invalid.
        :raises: MissingParameterValue if 'kernel_id' and 'ramdisk_id' are
            missing in the Glance image, or if 'kernel' and 'ramdisk' are
            missing in the Non Glance image.
        """
        check_share_fs_mounted()

        self._validate_volume_boot(task)
        if not task.driver.storage.should_write_image(task):
            LOG.debug('Node %(node)s skips image validation because of '
                      'booting from a remote volume.',
                      {'node': task.node.uuid})
            return

        d_info = _parse_deploy_info(task.node)
        if task.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)
Example #30
0
def validate_http_provisioning_configuration(node):
    """Validate configuration options required to perform HTTP provisioning.

    :param node: an ironic node object
    :raises: MissingParameterValue if required option(s) is not set.
    """
    image_source = node.instance_info.get('image_source')
    image_download_source = deploy_utils.get_image_download_source(node)
    if image_download_source not in ('swift', 'http', 'local'):
        raise exception.InvalidParameterValue(
            _('Invalid value for image_download_source: "%s". Valid values '
              'are swift, http or local.') % image_download_source)

    # NOTE(dtantsur): local HTTP configuration is required in two cases:
    # 1. Glance images with image_download_source == http
    # 2. File images (since we need to serve them to IPA)
    if (not image_source.startswith('file://')
            and image_download_source != 'local'
            and (not service_utils.is_glance_image(image_source)
                 or image_download_source == 'swift')):
        return

    params = {
        '[deploy]http_url': CONF.deploy.http_url,
        '[deploy]http_root': CONF.deploy.http_root,
        '[deploy]http_image_subdir': CONF.deploy.http_image_subdir
    }
    error_msg = _('Node %s failed to validate http provisoning. Some '
                  'configuration options were missing') % node.uuid
    deploy_utils.check_for_missing_params(params, error_msg)
Example #31
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        if not task.driver.storage.should_write_image(task):
            # NOTE(TheJulia): There is no reason to validate
            # image properties if we will not be writing an image
            # in a boot from volume case. As such, return to the caller.
            LOG.debug(
                'Skipping complete deployment interface validation '
                'for node %s as it is set to boot from a remote '
                'volume.', node.uuid)
            return

        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid

        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(
                    _("image_source's image_checksum must be provided in "
                      "instance_info for node %s") % node.uuid)

        check_image_size(task, image_source)
        # Validate the root device hints
        try:
            root_device = node.properties.get('root_device')
            il_utils.parse_root_device_hints(root_device)
        except ValueError as e:
            raise exception.InvalidParameterValue(
                _('Failed to validate the root device hints for node '
                  '%(node)s. Error: %(error)s') % {
                      'node': node.uuid,
                      'error': e
                  })

        validate_image_proxies(node)
Example #32
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of deploy ramdisk using virtual media.

        This method prepares the boot of the deploy or rescue ramdisk after
        reading relevant information from the node's driver_info and
        instance_info.

        :param task: a task from TaskManager.
        :param ramdisk_params: the parameters to be passed to the ramdisk.
        :returns: None
        :raises: MissingParameterValue, if some information is missing in
            node's driver_info or instance_info.
        :raises: InvalidParameterValue, if some information provided is
            invalid.
        :raises: IronicException, if some power or set boot boot device
            operation failed on the node.
        :raises: IloOperationError, if some operation on iLO failed.
        """

        node = task.node
        # NOTE(TheJulia): If this method is being called by something
        # aside from deployment, clean and rescue, such as conductor takeover,
        # we should treat this as a no-op and move on otherwise we would
        # modify the state of the node due to virtual media operations.
        if node.provision_state not in (states.DEPLOYING, states.CLEANING,
                                        states.RESCUING, states.INSPECTING):
            return

        prepare_node_for_deploy(task)

        # Clear ilo_boot_iso if it's a glance image to force recreate
        # another one again (or use existing one in glance).
        # This is mainly for rebuild and rescue scenario.
        if service_utils.is_glance_image(
                node.instance_info.get('image_source')):
            instance_info = node.instance_info
            instance_info.pop('ilo_boot_iso', None)
            node.instance_info = instance_info
            node.save()

        # Eject all virtual media devices, as we are going to use them
        # during boot.
        ilo_common.eject_vmedia_devices(task)

        # NOTE(TheJulia): Since we're deploying, cleaning, or rescuing,
        # with virtual media boot, we should generate a token!
        manager_utils.add_secret_token(task.node, pregenerated=True)
        ramdisk_params['ipa-agent-token'] = \
            task.node.driver_internal_info['agent_secret_token']
        task.node.save()

        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
        ramdisk_params['BOOTIF'] = deploy_nic_mac
        if node.provision_state == states.RESCUING:
            iso = node.driver_info['ilo_rescue_iso']
        else:
            iso = node.driver_info['ilo_deploy_iso']

        ilo_common.setup_vmedia(task, iso, ramdisk_params)
Example #33
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)
Example #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)

        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)
Example #35
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)
Example #36
0
File: pxe.py Project: 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)
Example #37
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        if not task.driver.storage.should_write_image(task):
            # NOTE(TheJulia): There is no reason to validate
            # image properties if we will not be writing an image
            # in a boot from volume case. As such, return to the caller.
            LOG.debug('Skipping complete deployment interface validation '
                      'for node %s as it is set to boot from a remote '
                      'volume.', node.uuid)
            return

        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid

        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(_(
                    "image_source's image_checksum must be provided in "
                    "instance_info for node %s") % node.uuid)

        check_image_size(task, image_source)
        # Validate the root device hints
        try:
            root_device = node.properties.get('root_device')
            il_utils.parse_root_device_hints(root_device)
        except ValueError as e:
            raise exception.InvalidParameterValue(
                _('Failed to validate the root device hints for node '
                  '%(node)s. Error: %(error)s') % {'node': node.uuid,
                                                   'error': e})

        validate_image_proxies(node)
Example #38
0
def parse_instance_info(node):
    """Gets the instance specific Node deployment info.

    This method validates whether the 'instance_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 values.
    :raises: MissingParameterValue, if any of the required parameters are
        missing.
    :raises: InvalidParameterValue, if any of the parameters have invalid
        value.
    """

    info = node.instance_info
    i_info = {}
    i_info['image_source'] = info.get('image_source')
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    if not iwdi:
        if (i_info['image_source']
                and not service_utils.is_glance_image(i_info['image_source'])):
            i_info['kernel'] = info.get('kernel')
            i_info['ramdisk'] = info.get('ramdisk')
        i_info['root_gb'] = info.get('root_gb')

    error_msg = _("Cannot validate driver deploy. Some parameters were missing"
                  " in node's instance_info")
    check_for_missing_params(i_info, error_msg)

    # This is used in many places, so keep it even for whole-disk images.
    # There is also a potential use case of creating an ephemeral partition via
    # cloud-init and telling ironic to avoid metadata wipe via setting
    # preserve_ephemeral (not saying it will work, but it seems possible).
    preserve_ephemeral = info.get('preserve_ephemeral', False)
    try:
        i_info['preserve_ephemeral'] = (strutils.bool_from_string(
            preserve_ephemeral, strict=True))
    except ValueError as e:
        raise exception.InvalidParameterValue(_ERR_MSG_INVALID_DEPLOY % {
            'param': 'preserve_ephemeral',
            'reason': e
        })

    if iwdi:
        if i_info.get('swap_mb') or i_info.get('ephemeral_mb'):
            err_msg_invalid = _("Cannot deploy whole disk image with "
                                "swap or ephemeral size set")
            raise exception.InvalidParameterValue(err_msg_invalid)
    else:
        _validate_layout_properties(node, info, i_info)

    i_info['configdrive'] = info.get('configdrive')

    return i_info
Example #39
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of deploy ramdisk using virtual media.

        This method prepares the boot of the deploy ramdisk after
        reading relevant information from the node's driver_info and
        instance_info.

        :param task: a task from TaskManager.
        :param ramdisk_params: the parameters to be passed to the ramdisk.
        :returns: None
        :raises: MissingParameterValue, if some information is missing in
            node's driver_info or instance_info.
        :raises: InvalidParameterValue, if some information provided is
            invalid.
        :raises: IronicException, if some power or set boot boot device
            operation failed on the node.
        :raises: IloOperationError, if some operation on iLO failed.
        """

        node = task.node
        # NOTE(TheJulia): If this method is being called by something
        # aside from deployment and clean, such as conductor takeover, we
        # should treat this as a no-op and move on otherwise we would modify
        # the state of the node due to virtual media operations.
        if (node.provision_state != states.DEPLOYING and
                node.provision_state != states.CLEANING):
            return

        # Powering off the Node before initiating boot for node cleaning.
        # If node is in system POST, setting boot device fails.
        manager_utils.node_power_action(task, states.POWER_OFF)

        if task.node.provision_state == states.DEPLOYING:
            prepare_node_for_deploy(task)

        # Clear ilo_boot_iso if it's a glance image to force recreate
        # another one again (or use existing one in glance).
        # This is mainly for rebuild scenario.
        if service_utils.is_glance_image(
                node.instance_info.get('image_source')):
            instance_info = node.instance_info
            instance_info.pop('ilo_boot_iso', None)
            node.instance_info = instance_info
            node.save()

        # Eject all virtual media devices, as we are going to use them
        # during boot.
        ilo_common.eject_vmedia_devices(task)

        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
        ramdisk_params['BOOTIF'] = deploy_nic_mac
        deploy_iso = node.driver_info['ilo_deploy_iso']

        ilo_common.setup_vmedia(task, deploy_iso, ramdisk_params)
Example #40
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.
        :raises: MissingParameterValue
        """
        node = task.node

        # Check the boot_mode and boot_option capabilities values.
        deploy_utils.validate_capabilities(node)

        boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node)

        if CONF.pxe.ipxe_enabled:
            if not CONF.pxe.http_url or not CONF.pxe.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}
                )

        # Check if 'boot_option' is compatible with 'boot_mode' of uefi and
        # image being deployed
        if boot_mode == "uefi":
            validate_boot_option_for_uefi(task.node)

        if deploy_utils.is_trusted_boot_requested(task.node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            validate_boot_parameters_for_trusted_boot(task.node)

        d_info = _parse_deploy_info(node)

        iscsi_deploy.validate(task)

        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"]

        iscsi_deploy.validate_image_properties(task.context, d_info, props)
Example #41
0
def build_instance_info_for_deploy(task):
    """Build instance_info necessary for deploying to a node.

    :param task: a TaskManager object containing the node
    :returns: a dictionary containing the properties to be updated
        in instance_info
    :raises: exception.ImageRefValidationFailed if image_source is not
        Glance href and is not HTTP(S) URL.
    """
    node = task.node
    instance_info = node.instance_info
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    image_source = instance_info['image_source']
    if service_utils.is_glance_image(image_source):
        glance = image_service.GlanceImageService(version=2,
                                                  context=task.context)
        image_info = glance.show(image_source)
        swift_temp_url = glance.swift_temp_url(image_info)
        LOG.debug('Got image info: %(info)s for node %(node)s.', {
            'info': image_info,
            'node': node.uuid
        })
        instance_info['image_url'] = swift_temp_url
        instance_info['image_checksum'] = image_info['checksum']
        instance_info['image_disk_format'] = image_info['disk_format']
        instance_info['image_container_format'] = (
            image_info['container_format'])
        instance_info['image_tags'] = image_info.get('tags', [])
        instance_info['image_properties'] = image_info['properties']

        if not iwdi:
            instance_info['kernel'] = image_info['properties']['kernel_id']
            instance_info['ramdisk'] = image_info['properties']['ramdisk_id']
    else:
        try:
            image_service.HttpImageService().validate_href(image_source)
        except exception.ImageRefValidationFailed:
            with excutils.save_and_reraise_exception():
                LOG.error(
                    _LE("Agent deploy supports only HTTP(S) URLs as "
                        "instance_info['image_source']. Either %s "
                        "is not a valid HTTP(S) URL or "
                        "is not reachable."), image_source)
        instance_info['image_url'] = image_source

    if not iwdi:
        instance_info['image_type'] = 'partition'
        i_info = parse_instance_info(node)
        instance_info.update(i_info)
    else:
        instance_info['image_type'] = 'whole-disk-image'
    return instance_info
Example #42
0
def _is_image_href_ordinary_file_name(image_href):
    """Check if image_href is a ordinary file name.

    This method judges if image_href is an ordinary file name or not,
    which is a file supposed to be stored in share file system.
    The ordinary file name is neither glance image href
    nor image service href.

    :returns: True if image_href is ordinary file name, False otherwise.
    """
    return not (service_utils.is_glance_image(image_href)
                or urlparse.urlparse(image_href).scheme.lower()
                in image_service.protocol_mapping)
Example #43
0
def _is_image_href_ordinary_file_name(image_href):
    """Check if image_href is a ordinary file name.

    This method judges if image_href is an ordinary file name or not,
    which is a file supposed to be stored in share file system.
    The ordinary file name is neither glance image href
    nor image service href.

    :returns: True if image_href is ordinary file name, False otherwise.
    """
    return not (service_utils.is_glance_image(image_href)
                or urlparse.urlparse(image_href).scheme.lower() in
                image_service.protocol_mapping)
Example #44
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)
Example #45
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)
Example #46
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.
        :raises: MissingParameterValue
        """
        node = task.node

        # Check the boot_mode and boot_option capabilities values.
        deploy_utils.validate_capabilities(node)

        boot_mode = deploy_utils.get_boot_mode_for_deploy(task.node)

        if CONF.pxe.ipxe_enabled:
            if not CONF.pxe.http_url or not CONF.pxe.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})

        # Check if 'boot_option' is compatible with 'boot_mode' of uefi and
        # image being deployed
        if boot_mode == 'uefi':
            validate_boot_option_for_uefi(task.node)

        if deploy_utils.is_trusted_boot_requested(task.node):
            # Check if 'boot_option' and boot mode is compatible with
            # trusted boot.
            validate_boot_parameters_for_trusted_boot(task.node)

        d_info = _parse_deploy_info(node)

        iscsi_deploy.validate(task)

        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']

        iscsi_deploy.validate_image_properties(task.context, d_info, props)
Example #47
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node
        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid
        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(
                    _("image_source's image_checksum must be provided in "
                      "instance_info for node %s") % node.uuid)

        check_image_size(task, image_source)
        is_whole_disk_image = node.driver_internal_info.get(
            'is_whole_disk_image')
        # TODO(sirushtim): Remove once IPA has support for partition images.
        if is_whole_disk_image is False:
            raise exception.InvalidParameterValue(
                _("Node %(node)s is configured to use the %(driver)s driver "
                  "which currently does not support deploying partition "
                  "images.") % {
                      'node': node.uuid,
                      'driver': node.driver
                  })

        # Validate the root device hints
        deploy_utils.parse_root_device_hints(node)

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        validate_image_proxies(node)
Example #48
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node
        params = {}
        image_source = node.instance_info.get("image_source")
        params["instance_info.image_source"] = image_source
        error_msg = _("Node %s failed to validate deploy image info. Some " "parameters were missing") % node.uuid
        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get("image_checksum"):
                raise exception.MissingParameterValue(
                    _("image_source's image_checksum must be provided in " "instance_info for node %s") % node.uuid
                )

        check_image_size(task, image_source)
        is_whole_disk_image = node.driver_internal_info.get("is_whole_disk_image")
        # TODO(sirushtim): Remove once IPA has support for partition images.
        if is_whole_disk_image is False:
            raise exception.InvalidParameterValue(
                _(
                    "Node %(node)s is configured to use the %(driver)s driver "
                    "which currently does not support deploying partition "
                    "images."
                )
                % {"node": node.uuid, "driver": node.driver}
            )

        # Validate the root device hints
        deploy_utils.parse_root_device_hints(node)

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        validate_image_proxies(node)
Example #49
0
def build_instance_info_for_deploy(task):
    """Build instance_info necessary for deploying to a node.

    :param task: a TaskManager object containing the node
    :returns: a dictionary containing the properties to be updated
        in instance_info
    :raises: exception.ImageRefValidationFailed if image_source is not
        Glance href and is not HTTP(S) URL.
    """
    node = task.node
    instance_info = node.instance_info
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    image_source = instance_info['image_source']
    if service_utils.is_glance_image(image_source):
        glance = image_service.GlanceImageService(version=2,
                                                  context=task.context)
        image_info = glance.show(image_source)
        swift_temp_url = glance.swift_temp_url(image_info)
        LOG.debug('Got image info: %(info)s for node %(node)s.',
                  {'info': image_info, 'node': node.uuid})
        instance_info['image_url'] = swift_temp_url
        instance_info['image_checksum'] = image_info['checksum']
        instance_info['image_disk_format'] = image_info['disk_format']
        instance_info['image_container_format'] = (
            image_info['container_format'])
        instance_info['image_tags'] = image_info.get('tags', [])
        instance_info['image_properties'] = image_info['properties']

        if not iwdi:
            instance_info['kernel'] = image_info['properties']['kernel_id']
            instance_info['ramdisk'] = image_info['properties']['ramdisk_id']
    else:
        try:
            image_service.HttpImageService().validate_href(image_source)
        except exception.ImageRefValidationFailed:
            with excutils.save_and_reraise_exception():
                LOG.error(_LE("Agent deploy supports only HTTP(S) URLs as "
                              "instance_info['image_source']. Either %s "
                              "is not a valid HTTP(S) URL or "
                              "is not reachable."), image_source)
        instance_info['image_url'] = image_source

    if not iwdi:
        instance_info['image_type'] = 'partition'
        i_info = parse_instance_info(node)
        instance_info.update(i_info)
    else:
        instance_info['image_type'] = 'whole-disk-image'
    return instance_info
Example #50
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue, if any of the required parameters are
            missing.
        :raises: InvalidParameterValue, if any of the parameters have invalid
            value.
        """
        if CONF.agent.manage_agent_boot:
            task.driver.boot.validate(task)

        node = task.node
        params = {}
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid

        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(_(
                    "image_source's image_checksum must be provided in "
                    "instance_info for node %s") % node.uuid)

        check_image_size(task, image_source)
        # Validate the root device hints
        try:
            root_device = node.properties.get('root_device')
            il_utils.parse_root_device_hints(root_device)
        except ValueError as e:
            raise exception.InvalidParameterValue(
                _('Failed to validate the root device hints for node '
                  '%(node)s. Error: %(error)s') % {'node': node.uuid,
                                                   'error': e})

        # Validate node capabilities
        deploy_utils.validate_capabilities(node)

        validate_image_proxies(node)
Example #51
0
    def deploy(self, task):
        """Start deployment of the task's node.

        Fetches the instance image, prepares the options for the deployment
        ramdisk, sets the node to boot from virtual media cdrom, and reboots
        the given node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: deploy state DEPLOYWAIT.
        :raises: InstanceDeployFailure, if image size if greater than root
            partition.
        :raises: ImageCreationFailed, if it failed while creating the floppy
            image.
        :raises: IloOperationError, if some operation on iLO fails.
        """
        node = task.node

        # Clear ilo_boot_iso if it's a glance image to force recreate
        # another one again (or use existing one in glance).
        # This is mainly for rebuild scenario.
        if service_utils.is_glance_image(
                node.instance_info.get('image_source')):
            instance_info = node.instance_info
            instance_info.pop('ilo_boot_iso', None)
            node.instance_info = instance_info
            node.save()

        # Eject all virtual media devices, as we are going to use them
        # during deploy.
        ilo_common.eject_vmedia_devices(task)

        iscsi_deploy.cache_instance_image(task.context, node)
        iscsi_deploy.check_image_size(task)

        deploy_ramdisk_opts = iscsi_deploy.build_deploy_ramdisk_options(node)
        agent_opts = agent.build_agent_options(node)
        deploy_ramdisk_opts.update(agent_opts)
        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
        deploy_ramdisk_opts['BOOTIF'] = deploy_nic_mac
        deploy_iso = node.driver_info['ilo_deploy_iso']

        _reboot_into(task, deploy_iso, deploy_ramdisk_opts)

        return states.DEPLOYWAIT
Example #52
0
def _build_deploy_pxe_options(task, pxe_info):
    pxe_opts = {}
    node = task.node

    for label, option in (('deploy_kernel', 'deployment_aki_path'),
                          ('deploy_ramdisk', 'deployment_ari_path')):
        if CONF.pxe.ipxe_enabled:
            image_href = pxe_info[label][0]
            if (CONF.pxe.ipxe_use_swift and
                service_utils.is_glance_image(image_href)):
                    pxe_opts[option] = images.get_temp_url_for_glance_image(
                        task.context, image_href)
            else:
                pxe_opts[option] = '/'.join([CONF.deploy.http_url, node.uuid,
                                            label])
        else:
            pxe_opts[option] = pxe_utils.get_path_relative_to_tftp_root(
                pxe_info[label][1])
    return pxe_opts
Example #53
0
def setup_vmedia_for_boot(task, boot_iso, parameters=None):
    """Sets up the node to boot from the given ISO image.

    This method attaches the given boot_iso on the node and passes
    the required parameters to it via virtual floppy image.

    :param task: a TaskManager instance containing the node to act on.
    :param boot_iso: a bootable ISO image to attach to. Should be either
        of below:
        * A Swift object - It should be of format 'swift:<object-name>'.
          It is assumed that the image object is present in
          CONF.ilo.swift_ilo_container;
        * A Glance image - It should be format 'glance://<glance-image-uuid>'
          or just <glance-image-uuid>;
        * An HTTP(S) URL.
    :param parameters: the parameters to pass in the virtual floppy image
        in a dictionary.  This is optional.
    :raises: ImageCreationFailed, if it failed while creating the floppy image.
    :raises: SwiftOperationError, if any operation with Swift fails.
    :raises: IloOperationError, if attaching virtual media failed.
    """
    LOG.info(_LI("Setting up node %s to boot from virtual media"),
             task.node.uuid)

    if parameters:
        floppy_image_temp_url = _prepare_floppy_image(task, parameters)
        attach_vmedia(task.node, 'FLOPPY', floppy_image_temp_url)

    boot_iso_url = None
    parsed_ref = urlparse.urlparse(boot_iso)
    if parsed_ref.scheme == 'swift':
        swift_api = swift.SwiftAPI()
        container = CONF.ilo.swift_ilo_container
        object_name = parsed_ref.path
        timeout = CONF.ilo.swift_object_expiry_timeout
        boot_iso_url = swift_api.get_temp_url(
            container, object_name, timeout)
    elif service_utils.is_glance_image(boot_iso):
        boot_iso_url = (
            images.get_temp_url_for_glance_image(task.context, boot_iso))

    attach_vmedia(task.node, 'CDROM', boot_iso_url or boot_iso)
Example #54
0
def _create_rootfs_link(task):
    """Create Swift temp url for deployment root FS."""
    rootfs = task.node.driver_info['deploy_squashfs']
    if service_utils.is_glance_image(rootfs):
        glance = image_service.GlanceImageService(version=2,
                                                  context=task.context)
        image_info = glance.show(rootfs)
        temp_url = glance.swift_temp_url(image_info)
        temp_url += '&filename=/root.squashfs'
        return temp_url

    try:
        image_service.HttpImageService().validate_href(rootfs)
    except exception.ImageRefValidationFailed:
        with excutils.save_and_reraise_exception():
            LOG.error(_LE("Agent deploy supports only HTTP URLs as "
                          "driver_info['deploy_squashfs']. Either %s "
                          "is not a valid HTTP URL or "
                          "is not reachable."), rootfs)
    return rootfs
Example #55
0
def _validate_instance_image_info(task):
    """Validate instance image information for the task's node.

    :param task: a TaskManager instance containing the node to act on.
    :raises: InvalidParameterValue, if some information is invalid.
    :raises: MissingParameterValue if 'kernel_id' and 'ramdisk_id' are
        missing in the Glance image or 'kernel' and 'ramdisk' not provided
        in instance_info for non-Glance image.
    """

    node = task.node

    d_info = _parse_deploy_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)
Example #56
0
    def prepare_ramdisk(self, task, ramdisk_params):
        """Prepares the boot of deploy ramdisk using virtual media.

        This method prepares the boot of the deploy ramdisk after
        reading relevant information from the node's driver_info and
        instance_info.

        :param task: a task from TaskManager.
        :param ramdisk_params: the parameters to be passed to the ramdisk.
        :returns: None
        :raises: MissingParameterValue, if some information is missing in
            node's driver_info or instance_info.
        :raises: InvalidParameterValue, if some information provided is
            invalid.
        :raises: IronicException, if some power or set boot boot device
            operation failed on the node.
        :raises: IloOperationError, if some operation on iLO failed.
        """

        node = task.node

        # Clear ilo_boot_iso if it's a glance image to force recreate
        # another one again (or use existing one in glance).
        # This is mainly for rebuild scenario.
        if service_utils.is_glance_image(
                node.instance_info.get('image_source')):
            instance_info = node.instance_info
            instance_info.pop('ilo_boot_iso', None)
            node.instance_info = instance_info
            node.save()

        # Eject all virtual media devices, as we are going to use them
        # during deploy.
        ilo_common.eject_vmedia_devices(task)

        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
        ramdisk_params['BOOTIF'] = deploy_nic_mac
        deploy_iso = node.driver_info['ilo_deploy_iso']

        ilo_common.setup_vmedia(task, deploy_iso, ramdisk_params)
Example #57
0
    def validate(self, task):
        """Validate the driver-specific Node deployment info.

        This method validates whether the properties of the supplied node
        contain the required information for this driver to deploy images to
        the node.

        :param task: a TaskManager instance
        :raises: MissingParameterValue
        """
        node = task.node
        params = {}
        if CONF.agent.manage_tftp:
            params['driver_info.deploy_kernel'] = node.driver_info.get(
                'deploy_kernel')
            params['driver_info.deploy_ramdisk'] = node.driver_info.get(
                'deploy_ramdisk')
        image_source = node.instance_info.get('image_source')
        params['instance_info.image_source'] = image_source
        error_msg = _('Node %s failed to validate deploy image info. Some '
                      'parameters were missing') % node.uuid
        deploy_utils.check_for_missing_params(params, error_msg)

        if not service_utils.is_glance_image(image_source):
            if not node.instance_info.get('image_checksum'):
                raise exception.MissingParameterValue(_(
                    "image_source's image_checksum must be provided in "
                    "instance_info for node %s") % node.uuid)

        is_whole_disk_image = node.driver_internal_info.get(
            'is_whole_disk_image')
        # TODO(sirushtim): Remove once IPA has support for partition images.
        if is_whole_disk_image is False:
            raise exception.InvalidParameterValue(_(
                "Node %(node)s is configured to use the %(driver)s driver "
                "which currently does not support deploying partition "
                "images.") % {'node': node.uuid, 'driver': node.driver})

        # Validate the root device hints
        deploy_utils.parse_root_device_hints(node)