Esempio n. 1
0
def _write_related_bundles_file(bundle_metadata, request_id):
    """
    Get bundle images in the CSV files of the bundle being regenerated and store them in a file.

    :param dict bundle_metadata: the dictionary of CSV's and relatedImages pull specifications
    :param int request_id: the ID of the IIB build request
    """
    worker_config = get_worker_config()
    related_bundles_dir = worker_config['iib_request_related_bundles_dir']
    related_bundles_file = os.path.join(related_bundles_dir, f'{request_id}_related_bundles.json')

    related_bundle_images = []
    for related_pullspec_obj in bundle_metadata['found_pullspecs']:
        related_pullspec = related_pullspec_obj.to_str()
        if yaml.load(
            get_image_label(related_pullspec, 'com.redhat.delivery.operator.bundle') or 'false'
        ):
            related_bundle_images.append(related_pullspec)

    log.debug('Writing related bundle images to %s', related_bundles_file)
    with open(related_bundles_file, 'w') as output_file:
        json.dump(related_bundle_images, output_file)

    if worker_config['iib_aws_s3_bucket_name']:
        upload_file_to_s3_bucket(
            related_bundles_file, 'related_bundles', f'{request_id}_related_bundles.json'
        )
Esempio n. 2
0
def is_bundle_version_valid(bundle_path, valid_ocp_version):
    """
    Check if the version label of the bundle satisfies the index ocp_version.

    :param str bundle_path: pull specification of the bundle to be validated.
    :param str valid_ocp_version: the index ocp version against which the bundles will be validated.
    :return: a boolean indicating if the bundle_path satisfies the index ocp_version
    :rtype: bool

           |  "v4.5"   |   "=v4.6"    | "v4.5-v4.7" | "v4.5,v4.6"  | "v4.6,v4.5"
    -------------------------------------------------------------------------------
    v4.5   | included  | NOT included |  included   |  included    |  NOT included
    -------------------------------------------------------------------------------
    v4.6   | included  |   included   |  included   |  included    |  included
    -------------------------------------------------------------------------------
    v4.7   | included  | NOT included |  included   |  included    |  included
    """
    try:
        float_valid_ocp_version = float(valid_ocp_version.replace('v', ''))
    except ValueError:
        raise IIBError(
            f'Invalid OCP version, "{valid_ocp_version}", specified in Index Image'
        )
    try:
        bundle_version_label = get_image_label(
            bundle_path, 'com.redhat.openshift.versions')
        bundle_version = bundle_version_label.replace('v', '')
        if bundle_version_label.startswith('='):
            if float(bundle_version.strip('=')) == float_valid_ocp_version:
                return True
        elif '-' in bundle_version_label:
            min_version, max_version = [
                float(version) for version in bundle_version.split('-')
            ]
            if min_version <= float_valid_ocp_version <= max_version:
                return True
        elif "," in bundle_version_label:
            versions = [
                float(version) for version in bundle_version.split(",")
            ]
            if float_valid_ocp_version >= versions[0]:
                return True
        elif float_valid_ocp_version >= float(bundle_version):
            return True
    except ValueError:
        log.warning(
            'Bundle %s has an invalid `com.redhat.openshift.versions` label value set: %s',
            bundle_path,
            bundle_version_label,
        )

    return False
Esempio n. 3
0
def handle_regenerate_bundle_request(
    from_bundle_image, organization, request_id, registry_auths=None
):
    """
    Coordinate the work needed to regenerate the operator bundle image.

    :param str from_bundle_image: the pull specification of the bundle image to be regenerated.
    :param str organization: the name of the organization the bundle should be regenerated for.
    :param int request_id: the ID of the IIB build request
    :param dict registry_auths: Provide the dockerconfig.json for authentication to private
      registries, defaults to ``None``.
    :raises IIBError: if the regenerate bundle image build fails.
    """
    _cleanup()

    set_request_state(request_id, 'in_progress', 'Resolving from_bundle_image')

    with set_registry_auths(registry_auths):
        from_bundle_image_resolved = get_resolved_image(from_bundle_image)

        arches = get_image_arches(from_bundle_image_resolved)
        if not arches:
            raise IIBError(
                'No arches were found in the resolved from_bundle_image '
                f'{from_bundle_image_resolved}'
            )

        pinned_by_iib = yaml.load(
            get_image_label(from_bundle_image_resolved, 'com.redhat.iib.pinned') or 'false'
        )

        arches_str = ', '.join(sorted(arches))
        log.debug('Set to regenerate the bundle image for the following arches: %s', arches_str)

        payload = {
            'from_bundle_image_resolved': from_bundle_image_resolved,
            'state': 'in_progress',
            'state_reason': f'Regenerating the bundle image for the following arches: {arches_str}',
        }
        exc_msg = 'Failed setting the resolved "from_bundle_image" on the request'
        update_request(request_id, payload, exc_msg=exc_msg)

        # Pull the from_bundle_image to ensure steps later on don't fail due to registry timeouts
        podman_pull(from_bundle_image_resolved)

        with tempfile.TemporaryDirectory(prefix='iib-') as temp_dir:
            manifests_path = os.path.join(temp_dir, 'manifests')
            _copy_files_from_image(from_bundle_image_resolved, '/manifests', manifests_path)
            metadata_path = os.path.join(temp_dir, 'metadata')
            _copy_files_from_image(from_bundle_image_resolved, '/metadata', metadata_path)
            new_labels = _adjust_operator_bundle(
                manifests_path, metadata_path, request_id, organization, pinned_by_iib
            )

            with open(os.path.join(temp_dir, 'Dockerfile'), 'w') as dockerfile:
                dockerfile.write(
                    textwrap.dedent(
                        f"""\
                            FROM {from_bundle_image_resolved}
                            COPY ./manifests /manifests
                            COPY ./metadata /metadata
                        """
                    )
                )
                for name, value in new_labels.items():
                    dockerfile.write(f'LABEL {name}={value}\n')

            for arch in sorted(arches):
                _build_image(temp_dir, 'Dockerfile', request_id, arch)
                _push_image(request_id, arch)

    set_request_state(request_id, 'in_progress', 'Creating the manifest list')
    output_pull_spec = _create_and_push_manifest_list(request_id, arches, [])

    conf = get_worker_config()
    if conf['iib_index_image_output_registry']:
        old_output_pull_spec = output_pull_spec
        output_pull_spec = output_pull_spec.replace(
            conf['iib_registry'], conf['iib_index_image_output_registry'], 1
        )
        log.info(
            'Changed the bundle_image pull specification from %s to %s',
            old_output_pull_spec,
            output_pull_spec,
        )

    payload = {
        'arches': list(arches),
        'bundle_image': output_pull_spec,
        'state': 'complete',
        'state_reason': 'The request completed successfully',
    }
    update_request(request_id, payload, exc_msg='Failed setting the bundle image on the request')
Esempio n. 4
0
def test_get_image_label(mock_si, label, expected):
    mock_si.return_value = {'Labels': {'some_label': 'value'}}
    assert build.get_image_label('some-image:latest', label) == expected