示例#1
0
文件: agent.py 项目: zhaofeidl/ironic
    def continue_deploy(self, task):
        task.process_event('resume')
        node = task.node
        image_source = node.instance_info.get('image_source')
        LOG.debug('Continuing deploy for node %(node)s with image %(img)s', {
            'node': node.uuid,
            'img': image_source
        })

        image_info = {
            'id': image_source.split('/')[-1],
            'urls': [node.instance_info['image_url']],
            'checksum': node.instance_info['image_checksum'],
            # NOTE(comstud): Older versions of ironic do not set
            # 'disk_format' nor 'container_format', so we use .get()
            # to maintain backwards compatibility in case code was
            # upgraded in the middle of a build request.
            'disk_format': node.instance_info.get('image_disk_format'),
            'container_format':
            node.instance_info.get('image_container_format'),
            'stream_raw_images': CONF.agent.stream_raw_images,
        }

        if (node.instance_info.get('image_os_hash_algo')
                and node.instance_info.get('image_os_hash_value')):
            image_info['os_hash_algo'] = node.instance_info[
                'image_os_hash_algo']
            image_info['os_hash_value'] = node.instance_info[
                'image_os_hash_value']

        proxies = {}
        for scheme in ('http', 'https'):
            proxy_param = 'image_%s_proxy' % scheme
            proxy = node.driver_info.get(proxy_param)
            if proxy:
                proxies[scheme] = proxy
        if proxies:
            image_info['proxies'] = proxies
            no_proxy = node.driver_info.get('image_no_proxy')
            if no_proxy is not None:
                image_info['no_proxy'] = no_proxy

        image_info['node_uuid'] = node.uuid
        iwdi = node.driver_internal_info.get('is_whole_disk_image')
        if not iwdi:
            for label in PARTITION_IMAGE_LABELS:
                image_info[label] = node.instance_info.get(label)
            boot_option = deploy_utils.get_boot_option(node)
            image_info['deploy_boot_mode'] = (
                boot_mode_utils.get_boot_mode(node))
            image_info['boot_option'] = boot_option
            disk_label = deploy_utils.get_disk_label(node)
            if disk_label is not None:
                image_info['disk_label'] = disk_label

        # Tell the client to download and write the image with the given args
        self._client.prepare_image(node, image_info)

        task.process_event('wait')
示例#2
0
def get_deploy_info(node, address, iqn, port=None, lun='1', conv_flags=None):
    """Returns the information required for doing iSCSI deploy in a dictionary.

    :param node: ironic node object
    :param address: iSCSI address
    :param iqn: iSCSI iqn for the target disk
    :param port: iSCSI port, defaults to one specified in the configuration
    :param lun: iSCSI lun, defaults to '1'
    :param conv_flags: flag that will modify the behaviour of the image copy
        to disk.
    :raises: MissingParameterValue, if some required parameters were not
        passed.
    :raises: InvalidParameterValue, if any of the parameters have invalid
        value.
    """
    i_info = deploy_utils.parse_instance_info(node)

    params = {
        'address': address,
        'port': port or CONF.iscsi.portal_port,
        'iqn': iqn,
        'lun': lun,
        'image_path': deploy_utils._get_image_file_path(node.uuid),
        'node_uuid': node.uuid}

    is_whole_disk_image = node.driver_internal_info['is_whole_disk_image']
    if not is_whole_disk_image:
        params.update({'root_mb': i_info['root_mb'],
                       'swap_mb': i_info['swap_mb'],
                       'ephemeral_mb': i_info['ephemeral_mb'],
                       'preserve_ephemeral': i_info['preserve_ephemeral'],
                       'boot_option': deploy_utils.get_boot_option(node),
                       'boot_mode': _get_boot_mode(node),
                       'cpu_arch': node.properties.get('cpu_arch')})

        # Append disk label if specified
        disk_label = deploy_utils.get_disk_label(node)
        if disk_label is not None:
            params['disk_label'] = disk_label

    missing = [key for key in params if params[key] is None]
    if missing:
        raise exception.MissingParameterValue(
            _("Parameters %s were not passed to ironic"
              " for deploy.") % missing)

    # configdrive is nullable
    params['configdrive'] = i_info.get('configdrive')
    if is_whole_disk_image:
        return params

    if conv_flags:
        params['conv_flags'] = conv_flags

    # ephemeral_format is nullable
    params['ephemeral_format'] = i_info.get('ephemeral_format')

    return params
示例#3
0
def _parse_partitioning_info(node):

    info = node.instance_info
    i_info = {}
    partitions = []
    i_info['label'] = deploy_utils.get_disk_label(node) or 'msdos'

    # prepend 1MiB bios_grub partition for GPT so that grub(2) installs
    if i_info['label'] == 'gpt':
        bios_partition = {'name': 'bios',
                          'size': 1,
                          'unit': 'MiB',
                          'flags': {'bios_grub': 'yes'}}
        partitions.append(bios_partition)

    ephemeral_mb = info['ephemeral_mb']
    if ephemeral_mb:
        i_info['ephemeral_format'] = info['ephemeral_format']
        ephemeral_partition = {'name': 'ephemeral',
                               'size': ephemeral_mb,
                               'unit': 'MiB',
                               'format': i_info['ephemeral_format']}
        partitions.append(ephemeral_partition)

        i_info['preserve_ephemeral'] = (
            'yes' if info['preserve_ephemeral'] else 'no')

    swap_mb = info['swap_mb']
    if swap_mb:
        swap_partition = {'name': 'swap',
                          'size': swap_mb,
                          'unit': 'MiB',
                          'format': 'linux-swap'}
        partitions.append(swap_partition)

    # pre-create partition for configdrive
    configdrive = info.get('configdrive')
    if configdrive:
        configdrive_partition = {'name': 'configdrive',
                                 'size': 64,
                                 'unit': 'MiB',
                                 'format': 'fat32'}
        partitions.append(configdrive_partition)

    # NOTE(pas-ha) make the root partition last so that
    # e.g. cloud-init can grow it on first start
    root_partition = {'name': 'root',
                      'size': info['root_mb'],
                      'unit': 'MiB'}
    if i_info['label'] == 'msdos':
        root_partition['flags'] = {'boot': 'yes'}

    partitions.append(root_partition)

    i_info['partitions'] = partitions
    return {'partition_info': i_info}
示例#4
0
def get_deploy_info(node, **kwargs):
    """Returns the information required for doing iSCSI deploy in a dictionary.

    :param node: ironic node object
    :param kwargs: the keyword args passed from the conductor node.
    :raises: MissingParameterValue, if some required parameters were not
        passed.
    :raises: InvalidParameterValue, if any of the parameters have invalid
        value.
    """
    deploy_key = kwargs.get('key')
    i_info = deploy_utils.parse_instance_info(node)
    if i_info['deploy_key'] != deploy_key:
        raise exception.InvalidParameterValue(_("Deploy key does not match"))

    params = {
        'address': kwargs.get('address'),
        'port': kwargs.get('port', CONF.iscsi.portal_port),
        'iqn': kwargs.get('iqn'),
        'lun': kwargs.get('lun', '1'),
        'image_path': _get_image_file_path(node.uuid),
        'node_uuid': node.uuid
    }

    is_whole_disk_image = node.driver_internal_info['is_whole_disk_image']
    if not is_whole_disk_image:
        params.update({
            'root_mb': 1024 * int(i_info['root_gb']),
            'swap_mb': int(i_info['swap_mb']),
            'ephemeral_mb': 1024 * int(i_info['ephemeral_gb']),
            'preserve_ephemeral': i_info['preserve_ephemeral'],
            'boot_option': deploy_utils.get_boot_option(node),
            'boot_mode': _get_boot_mode(node)
        })

        # Append disk label if specified
        disk_label = deploy_utils.get_disk_label(node)
        if disk_label is not None:
            params['disk_label'] = disk_label

    missing = [key for key in params if params[key] is None]
    if missing:
        raise exception.MissingParameterValue(
            _("Parameters %s were not passed to ironic"
              " for deploy.") % missing)

    if is_whole_disk_image:
        return params

    # configdrive and ephemeral_format are nullable
    params['ephemeral_format'] = i_info.get('ephemeral_format')
    params['configdrive'] = i_info.get('configdrive')

    return params
示例#5
0
文件: agent.py 项目: pshchelo/ironic
    def continue_deploy(self, task):
        task.process_event('resume')
        node = task.node
        image_source = node.instance_info.get('image_source')
        LOG.debug('Continuing deploy for node %(node)s with image %(img)s',
                  {'node': node.uuid, 'img': image_source})

        image_info = {
            'id': image_source.split('/')[-1],
            'urls': [node.instance_info['image_url']],
            'checksum': node.instance_info['image_checksum'],
            # NOTE(comstud): Older versions of ironic do not set
            # 'disk_format' nor 'container_format', so we use .get()
            # to maintain backwards compatibility in case code was
            # upgraded in the middle of a build request.
            'disk_format': node.instance_info.get('image_disk_format'),
            'container_format': node.instance_info.get(
                'image_container_format'),
            'stream_raw_images': CONF.agent.stream_raw_images,
        }

        proxies = {}
        for scheme in ('http', 'https'):
            proxy_param = 'image_%s_proxy' % scheme
            proxy = node.driver_info.get(proxy_param)
            if proxy:
                proxies[scheme] = proxy
        if proxies:
            image_info['proxies'] = proxies
            no_proxy = node.driver_info.get('image_no_proxy')
            if no_proxy is not None:
                image_info['no_proxy'] = no_proxy

        image_info['node_uuid'] = node.uuid
        iwdi = node.driver_internal_info.get('is_whole_disk_image')
        if not iwdi:
            for label in PARTITION_IMAGE_LABELS:
                image_info[label] = node.instance_info.get(label)
            boot_option = deploy_utils.get_boot_option(node)
            boot_mode = deploy_utils.get_boot_mode_for_deploy(node)
            if boot_mode:
                image_info['deploy_boot_mode'] = boot_mode
            else:
                image_info['deploy_boot_mode'] = 'bios'
            image_info['boot_option'] = boot_option
            disk_label = deploy_utils.get_disk_label(node)
            if disk_label is not None:
                image_info['disk_label'] = disk_label

        # Tell the client to download and write the image with the given args
        self._client.prepare_image(node, image_info)

        task.process_event('wait')
示例#6
0
def get_deploy_info(node, address, iqn, port=None, lun='1'):
    """Returns the information required for doing iSCSI deploy in a dictionary.

    :param node: ironic node object
    :param address: iSCSI address
    :param iqn: iSCSI iqn for the target disk
    :param port: iSCSI port, defaults to one specified in the configuration
    :param lun: iSCSI lun, defaults to '1'
    :raises: MissingParameterValue, if some required parameters were not
        passed.
    :raises: InvalidParameterValue, if any of the parameters have invalid
        value.
    """
    i_info = deploy_utils.parse_instance_info(node)

    params = {
        'address': address,
        'port': port or CONF.iscsi.portal_port,
        'iqn': iqn,
        'lun': lun,
        'image_path': _get_image_file_path(node.uuid),
        'node_uuid': node.uuid}

    is_whole_disk_image = node.driver_internal_info['is_whole_disk_image']
    if not is_whole_disk_image:
        params.update({'root_mb': i_info['root_mb'],
                       'swap_mb': i_info['swap_mb'],
                       'ephemeral_mb': i_info['ephemeral_mb'],
                       'preserve_ephemeral': i_info['preserve_ephemeral'],
                       'boot_option': deploy_utils.get_boot_option(node),
                       'boot_mode': _get_boot_mode(node)})

        # Append disk label if specified
        disk_label = deploy_utils.get_disk_label(node)
        if disk_label is not None:
            params['disk_label'] = disk_label

    missing = [key for key in params if params[key] is None]
    if missing:
        raise exception.MissingParameterValue(
            _("Parameters %s were not passed to ironic"
              " for deploy.") % missing)

    # configdrive is nullable
    params['configdrive'] = i_info.get('configdrive')
    if is_whole_disk_image:
        return params

    # ephemeral_format is nullable
    params['ephemeral_format'] = i_info.get('ephemeral_format')

    return params
示例#7
0
def _parse_partitioning_info(node):

    info = node.instance_info
    i_info = {'label': deploy_utils.get_disk_label(node) or 'msdos'}
    is_gpt = i_info['label'] == 'gpt'
    unit = 'MiB'
    partitions = {}

    def add_partition(name, start, end):
        partitions[name] = {
            'number': len(partitions) + 1,
            'part_start': '%i%s' % (start, unit),
            'part_end': '%i%s' % (end, unit)
        }
        if is_gpt:
            partitions[name]['name'] = name

    end = 1
    if is_gpt:
        # prepend 1MiB bios_grub partition for GPT so that grub(2) installs
        start, end = end, end + 1
        add_partition('bios', start, end)
        partitions['bios']['flags'] = ['bios_grub']

    ephemeral_mb = info['ephemeral_mb']
    if ephemeral_mb:
        start, end = end, end + ephemeral_mb
        add_partition('ephemeral', start, end)
        i_info['ephemeral_format'] = info['ephemeral_format']
        i_info['preserve_ephemeral'] = ('yes' if info['preserve_ephemeral']
                                        else 'no')

    swap_mb = info['swap_mb']
    if swap_mb:
        start, end = end, end + swap_mb
        add_partition('swap', start, end)

    configdrive = info.get('configdrive')
    if configdrive:
        # pre-create 64MiB partition for configdrive
        start, end = end, end + 64
        add_partition('configdrive', start, end)

    # NOTE(pas-ha) make the root partition last so that
    # e.g. cloud-init can grow it on first start
    start, end = end, end + info['root_mb']
    add_partition('root', start, end)
    if not is_gpt:
        partitions['root']['flags'] = ['boot']
    i_info['partitions'] = partitions
    return {'partition_info': i_info}
示例#8
0
def get_deploy_info(node, **kwargs):
    """Returns the information required for doing iSCSI deploy in a dictionary.

    :param node: ironic node object
    :param kwargs: the keyword args passed from the conductor node.
    :raises: MissingParameterValue, if some required parameters were not
        passed.
    :raises: InvalidParameterValue, if any of the parameters have invalid
        value.
    """
    deploy_key = kwargs.get('key')
    i_info = parse_instance_info(node)
    if i_info['deploy_key'] != deploy_key:
        raise exception.InvalidParameterValue(_("Deploy key does not match"))

    params = {
        'address': kwargs.get('address'),
        'port': kwargs.get('port', '3260'),
        'iqn': kwargs.get('iqn'),
        'lun': kwargs.get('lun', '1'),
        'image_path': _get_image_file_path(node.uuid),
        'node_uuid': node.uuid}

    is_whole_disk_image = node.driver_internal_info['is_whole_disk_image']
    if not is_whole_disk_image:
        params.update({'root_mb': 1024 * int(i_info['root_gb']),
                       'swap_mb': int(i_info['swap_mb']),
                       'ephemeral_mb': 1024 * int(i_info['ephemeral_gb']),
                       'preserve_ephemeral': i_info['preserve_ephemeral'],
                       'boot_option': deploy_utils.get_boot_option(node),
                       'boot_mode': _get_boot_mode(node)})

        # Append disk label if specified
        disk_label = deploy_utils.get_disk_label(node)
        if disk_label is not None:
            params['disk_label'] = disk_label

    missing = [key for key in params if params[key] is None]
    if missing:
        raise exception.MissingParameterValue(
            _("Parameters %s were not passed to ironic"
              " for deploy.") % missing)

    if is_whole_disk_image:
        return params

    # configdrive and ephemeral_format are nullable
    params['ephemeral_format'] = i_info.get('ephemeral_format')
    params['configdrive'] = i_info.get('configdrive')

    return params
示例#9
0
def _parse_partitioning_info(node):

    info = node.instance_info
    i_info = {'label': deploy_utils.get_disk_label(node) or 'msdos'}
    is_gpt = i_info['label'] == 'gpt'
    unit = 'MiB'
    partitions = {}

    def add_partition(name, start, end):
        partitions[name] = {'number': len(partitions) + 1,
                            'part_start': '%i%s' % (start, unit),
                            'part_end': '%i%s' % (end, unit)}
        if is_gpt:
            partitions[name]['name'] = name

    end = 1
    if is_gpt:
        # prepend 1MiB bios_grub partition for GPT so that grub(2) installs
        start, end = end, end + 1
        add_partition('bios', start, end)
        partitions['bios']['flags'] = ['bios_grub']

    ephemeral_mb = info['ephemeral_mb']
    if ephemeral_mb:
        start, end = end, end + ephemeral_mb
        add_partition('ephemeral', start, end)
        i_info['ephemeral_format'] = info['ephemeral_format']
        i_info['preserve_ephemeral'] = (
            'yes' if info['preserve_ephemeral'] else 'no')

    swap_mb = info['swap_mb']
    if swap_mb:
        start, end = end, end + swap_mb
        add_partition('swap', start, end)

    configdrive = info.get('configdrive')
    if configdrive:
        # pre-create 64MiB partition for configdrive
        start, end = end, end + 64
        add_partition('configdrive', start, end)

    # NOTE(pas-ha) make the root partition last so that
    # e.g. cloud-init can grow it on first start
    start, end = end, end + info['root_mb']
    add_partition('root', start, end)
    if not is_gpt:
        partitions['root']['flags'] = ['boot']
    i_info['partitions'] = partitions
    return {'partition_info': i_info}
示例#10
0
文件: agent.py 项目: younkun/ironic
    def write_image(self, task):
        if not task.driver.storage.should_write_image(task):
            return
        node = task.node
        image_source = node.instance_info.get('image_source')
        LOG.debug('Continuing deploy for node %(node)s with image %(img)s', {
            'node': node.uuid,
            'img': image_source
        })

        image_info = {
            'id': image_source.split('/')[-1],
            'urls': [node.instance_info['image_url']],
            # NOTE(comstud): Older versions of ironic do not set
            # 'disk_format' nor 'container_format', so we use .get()
            # to maintain backwards compatibility in case code was
            # upgraded in the middle of a build request.
            'disk_format': node.instance_info.get('image_disk_format'),
            'container_format':
            node.instance_info.get('image_container_format'),
            'stream_raw_images': CONF.agent.stream_raw_images,
        }

        if node.instance_info.get('image_checksum'):
            image_info['checksum'] = node.instance_info['image_checksum']

        if (node.instance_info.get('image_os_hash_algo')
                and node.instance_info.get('image_os_hash_value')):
            image_info['os_hash_algo'] = node.instance_info[
                'image_os_hash_algo']
            image_info['os_hash_value'] = node.instance_info[
                'image_os_hash_value']

        proxies = {}
        for scheme in ('http', 'https'):
            proxy_param = 'image_%s_proxy' % scheme
            proxy = node.driver_info.get(proxy_param)
            if proxy:
                proxies[scheme] = proxy
        if proxies:
            image_info['proxies'] = proxies
            no_proxy = node.driver_info.get('image_no_proxy')
            if no_proxy is not None:
                image_info['no_proxy'] = no_proxy

        image_info['node_uuid'] = node.uuid
        iwdi = node.driver_internal_info.get('is_whole_disk_image')
        if not iwdi:
            for label in PARTITION_IMAGE_LABELS:
                image_info[label] = node.instance_info.get(label)
            boot_option = deploy_utils.get_boot_option(node)
            image_info['deploy_boot_mode'] = (
                boot_mode_utils.get_boot_mode(node))
            image_info['boot_option'] = boot_option
            disk_label = deploy_utils.get_disk_label(node)
            if disk_label is not None:
                image_info['disk_label'] = disk_label

        has_write_image = agent_base.find_step(task, 'deploy', 'deploy',
                                               'write_image') is not None
        if not has_write_image:
            LOG.warning(
                'The agent on node %s does not have the deploy '
                'step deploy.write_image, using the deprecated '
                'synchronous fall-back', task.node.uuid)

        if self.has_decomposed_deploy_steps and has_write_image:
            configdrive = node.instance_info.get('configdrive')
            # Now switch into the corresponding in-band deploy step and let the
            # result be polled normally.
            new_step = {
                'interface': 'deploy',
                'step': 'write_image',
                'args': {
                    'image_info': image_info,
                    'configdrive': configdrive
                }
            }
            return agent_base.execute_step(task,
                                           new_step,
                                           'deploy',
                                           client=self._client)
        else:
            # TODO(dtantsur): remove in W
            command = self._client.prepare_image(node, image_info, wait=True)
            if command['command_status'] == 'FAILED':
                # TODO(jimrollenhagen) power off if using neutron dhcp to
                #                      align with pxe driver?
                msg = (_('node %(node)s command status errored: %(error)s') % {
                    'node': node.uuid,
                    'error': command['command_error']
                })
                LOG.error(msg)
                deploy_utils.set_failed_state(task, msg)
示例#11
0
    def write_image(self, task):
        if not task.driver.storage.should_write_image(task):
            return
        node = task.node
        image_source = node.instance_info.get('image_source')
        LOG.debug('Continuing deploy for node %(node)s with image %(img)s', {
            'node': node.uuid,
            'img': image_source
        })

        image_info = {
            'id': image_source.split('/')[-1],
            'urls': [node.instance_info['image_url']],
            # NOTE(comstud): Older versions of ironic do not set
            # 'disk_format' nor 'container_format', so we use .get()
            # to maintain backwards compatibility in case code was
            # upgraded in the middle of a build request.
            'disk_format': node.instance_info.get('image_disk_format'),
            'container_format':
            node.instance_info.get('image_container_format'),
            'stream_raw_images': CONF.agent.stream_raw_images,
        }

        if node.instance_info.get('image_checksum'):
            image_info['checksum'] = node.instance_info['image_checksum']

        if (node.instance_info.get('image_os_hash_algo')
                and node.instance_info.get('image_os_hash_value')):
            image_info['os_hash_algo'] = node.instance_info[
                'image_os_hash_algo']
            image_info['os_hash_value'] = node.instance_info[
                'image_os_hash_value']

        proxies = {}
        for scheme in ('http', 'https'):
            proxy_param = 'image_%s_proxy' % scheme
            proxy = node.driver_info.get(proxy_param)
            if proxy:
                proxies[scheme] = proxy
        if proxies:
            image_info['proxies'] = proxies
            no_proxy = node.driver_info.get('image_no_proxy')
            if no_proxy is not None:
                image_info['no_proxy'] = no_proxy

        image_info['node_uuid'] = node.uuid
        iwdi = node.driver_internal_info.get('is_whole_disk_image')
        if not iwdi:
            for label in PARTITION_IMAGE_LABELS:
                image_info[label] = node.instance_info.get(label)
            boot_option = deploy_utils.get_boot_option(node)
            image_info['deploy_boot_mode'] = (
                boot_mode_utils.get_boot_mode(node))
            image_info['boot_option'] = boot_option
            disk_label = deploy_utils.get_disk_label(node)
            if disk_label is not None:
                image_info['disk_label'] = disk_label

        configdrive = manager_utils.get_configdrive_image(node)
        if configdrive:
            # FIXME(dtantsur): remove this duplication once IPA is ready:
            # https://review.opendev.org/c/openstack/ironic-python-agent/+/790471
            image_info['configdrive'] = configdrive
        # Now switch into the corresponding in-band deploy step and let the
        # result be polled normally.
        new_step = {
            'interface': 'deploy',
            'step': 'write_image',
            'args': {
                'image_info': image_info,
                'configdrive': configdrive
            }
        }
        return agent_base.execute_step(task,
                                       new_step,
                                       'deploy',
                                       client=self._client)