Ejemplo n.º 1
0
def _copy_files_from_image(image, src_path, dest_path):
    """
    Copy a file from the container image into the given destination path.

    The file may be a directory.

    :param str image: the pull specification of the container image.
    :param str src_path: the full path within the container image to copy from.
    :param str dest_path: the full path on the local host to copy into.
    """
    # Check that image is pullable
    podman_pull(image)

    # One way to copy a file from the image is to create a container from its filesystem
    # so the contents can be read. To create a container, podman always requires that a
    # command for the container is set. In this method, however, the command is not needed
    # because the container is never started, only created. Use a dummy command to satisfy
    # podman.
    container_command = 'unused'
    container_id = run_cmd(
        ['podman', 'create', image, container_command],
        exc_msg=f'Failed to create a container for {image}',
    ).strip()
    try:
        run_cmd(
            ['podman', 'cp', f'{container_id}:{src_path}', dest_path],
            exc_msg=
            f'Failed to copy the contents of {container_id}:{src_path} into {dest_path}',
        )
    finally:
        try:
            run_cmd(
                ['podman', 'rm', container_id],
                exc_msg=
                f'Failed to remove the container {container_id} for image {image}',
            )
        except IIBError as e:
            # Failure to remove the temporary container shouldn't cause the IIB request to fail.
            log.exception(e)
Ejemplo n.º 2
0
def handle_regenerate_bundle_request(from_bundle_image, organization,
                                     request_id):
    """
    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
    :raises IIBError: if the regenerate bundle image build fails.
    """
    _cleanup()

    set_request_state(request_id, 'in_progress', 'Resolving from_bundle_image')
    from_bundle_image_resolved = _get_resolved_image(from_bundle_image)
    arches = _get_image_arches(from_bundle_image_resolved)
    if not arches:
        raise IIBError(
            f'No arches were found in the resolved from_bundle_image {from_bundle_image_resolved}'
        )

    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)
        labels = _adjust_operator_bundle(manifests_path, metadata_path,
                                         organization)

        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 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')
Ejemplo n.º 3
0
def test_podman_pull(mock_run_cmd):
    image = 'some-image:latest'
    utils.podman_pull(image)
    mock_run_cmd.assert_called_once_with(['podman', 'pull', image],
                                         exc_msg=mock.ANY)