예제 #1
0
파일: build.py 프로젝트: fromanirh/iib
def _get_image_arches(pull_spec):
    """
    Get the architectures this image was built for.

    :param str pull_spec: the pull specification to a v2 manifest list
    :return: a set of architectures of the container images contained in the manifest list
    :rtype: set
    :raises IIBError: if the pull specification is not a v2 manifest list
    """
    log.debug('Get the available arches for %s', pull_spec)
    skopeo_raw = skopeo_inspect(f'docker://{pull_spec}', '--raw')
    arches = set()
    if skopeo_raw.get(
            'mediaType'
    ) == 'application/vnd.docker.distribution.manifest.list.v2+json':
        for manifest in skopeo_raw['manifests']:
            arches.add(manifest['platform']['architecture'])
    elif skopeo_raw.get(
            'mediaType'
    ) == 'application/vnd.docker.distribution.manifest.v2+json':
        skopeo_out = skopeo_inspect(f'docker://{pull_spec}', '--config')
        arches.add(skopeo_out['architecture'])
    else:
        raise IIBError(
            f'The pull specification of {pull_spec} is neither a v2 manifest list nor a v2 manifest'
        )

    return arches
예제 #2
0
파일: build.py 프로젝트: fromanirh/iib
def _push_image(request_id, arch):
    """
    Push the single arch container image to the configured registry.

    :param int request_id: the ID of the IIB build request
    :param str arch: the architecture of the container image to push
    :raises IIBError: if the push fails
    """
    source = _get_local_pull_spec(request_id, arch)
    destination = _get_external_arch_pull_spec(request_id,
                                               arch,
                                               include_transport=True)
    log.info('Pushing the container image %s to %s', source, destination)
    run_cmd(
        ['podman', 'push', '-q', source, destination],
        exc_msg=
        f'Failed to push the container image to {destination} for the arch {arch}',
    )

    log.debug(
        f'Verifying that {destination} was pushed as a v2 manifest due to RHBZ#1810768'
    )
    skopeo_raw = skopeo_inspect(destination, '--raw')
    if skopeo_raw['schemaVersion'] != 2:
        log.warning(
            'The manifest for %s ended up using schema version 1 due to RHBZ#1810768. Manually '
            'fixing it with skopeo.',
            destination,
        )
        exc_msg = f'Failed to fix the manifest schema version on {destination}'
        _skopeo_copy(destination, destination, exc_msg=exc_msg)
예제 #3
0
파일: test_utils.py 프로젝트: pbortlov/iib
def test_skopeo_inspect(mock_run_cmd):
    mock_run_cmd.return_value = '{"Name": "some-image"}'
    image = 'docker://some-image:latest'
    rv = utils.skopeo_inspect(image)
    assert rv == {"Name": "some-image"}
    skopeo_args = mock_run_cmd.call_args[0][0]
    expected = ['skopeo', '--command-timeout', '300s', 'inspect', image]
    assert skopeo_args == expected
예제 #4
0
def test_skopeo_inspect_cache(mock_run_cmd, moc_dpr_get):
    mock_run_cmd.return_value = '{"Name": "some-image-cache"}'
    image = 'docker://some-image-cache@sha256:129bfb6af3e03997eb_not_real_sha_c7c18d89b40d97'
    rv_expected = {'Name': 'some-image-cache'}
    moc_dpr_get.return_value = rv_expected

    rv = utils.skopeo_inspect(image)
    assert rv == rv_expected
    assert mock_run_cmd.called is False

    assert mock_run_cmd.call_args is None
예제 #5
0
def test_skopeo_inspect_no_cache(mock_run_cmd, moc_dpr_get):
    mock_run_cmd.return_value = '{"Name": "some-image-cache"}'
    image = 'docker://some-image-no-cache:tag'
    rv_expected = {"Name": "some-image-cache"}

    rv = utils.skopeo_inspect(image)
    assert rv == rv_expected
    assert mock_run_cmd.called is True
    assert moc_dpr_get.called is False

    skopeo_args = mock_run_cmd.call_args[0][0]
    args_expected = ['skopeo', '--command-timeout', '300s', 'inspect', image]
    assert skopeo_args == args_expected
예제 #6
0
파일: build.py 프로젝트: chandwanitulsi/iib
def _get_resolved_image(pull_spec):
    """
    Get the pull specification of the container image using its digest.

    :param str pull_spec: the pull specification of the container image to resolve
    :return: the resolved pull specification
    :rtype: str
    """
    log.debug('Resolving %s', pull_spec)
    skopeo_output = skopeo_inspect(f'docker://{pull_spec}')
    pull_spec_resolved = f'{skopeo_output["Name"]}@{skopeo_output["Digest"]}'
    log.debug('%s resolved to %s', pull_spec, pull_spec_resolved)
    return pull_spec_resolved
예제 #7
0
파일: build.py 프로젝트: fromanirh/iib
def _get_resolved_image(pull_spec):
    """
    Get the pull specification of the container image using its digest.

    :param str pull_spec: the pull specification of the container image to resolve
    :return: the resolved pull specification
    :rtype: str
    """
    log.debug('Resolving %s', pull_spec)
    name = _get_container_image_name(pull_spec)
    skopeo_output = skopeo_inspect(f'docker://{pull_spec}',
                                   '--raw',
                                   return_json=False)
    digest = hashlib.sha256(skopeo_output.encode('utf-8')).hexdigest()
    pull_spec_resolved = f'{name}@sha256:{digest}'
    log.debug('%s resolved to %s', pull_spec, pull_spec_resolved)
    return pull_spec_resolved
예제 #8
0
파일: build.py 프로젝트: chandwanitulsi/iib
def _get_resolved_bundles(bundles):
    """
    Get the pull specification of the bundle images using their digests.

    Determine if the pull spec refers to a manifest list.
    If so, simply use the digest of the first item in the manifest list.
    If not a manifest list, it must be a v2s2 image manifest and should be used as it is.

    :param list bundles: the list of bundle images to be resolved.
    :return: the list of bundle images resolved to their digests.
    :rtype: list
    :raises IIBError: if unable to resolve a bundle image.
    """
    log.info('Resolving bundles %s', ', '.join(bundles))
    resolved_bundles = set()
    for bundle_pull_spec in bundles:
        skopeo_raw = skopeo_inspect(f'docker://{bundle_pull_spec}', '--raw')
        if (skopeo_raw.get('mediaType') ==
                'application/vnd.docker.distribution.manifest.list.v2+json'):
            # Get the digest of the first item in the manifest list
            digest = skopeo_raw['manifests'][0]['digest']
            if '@' in bundle_pull_spec:
                repo = bundle_pull_spec.split('@', 1)[0]
            else:
                repo = bundle_pull_spec.rsplit(':', 1)[0]
            resolved_bundles.add(f'{repo}@{digest}')
        elif (skopeo_raw.get('mediaType')
              == 'application/vnd.docker.distribution.manifest.v2+json'
              and skopeo_raw.get('schemaVersion') == 2):
            resolved_bundles.add(_get_resolved_image(bundle_pull_spec))
        else:
            error_msg = (
                f'The pull specification of {bundle_pull_spec} is neither '
                f'a v2 manifest list nor a v2s2 manifest. Type {skopeo_raw.get("mediaType")}'
                f' and schema version {skopeo_raw.get("schemaVersion")} is not supported by IIB.'
            )
            raise IIBError(error_msg)

    return list(resolved_bundles)
예제 #9
0
파일: test_utils.py 프로젝트: pbortlov/iib
def test_rasise_exception_on_none_mediatype_skopeo_inspect(mock_run_cmd):
    mock_run_cmd.return_value = '{"Name": "some-image"}'
    image = 'docker://some-image:latest'
    with pytest.raises(IIBError, match='mediaType not found'):
        utils.skopeo_inspect(image, '--raw', require_media_type=True)