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')
def test_set_registry_auths( mock_rdc, mock_json_dump, mock_open, mock_exists, mock_remove, mock_expanduser, config_exists, template_exists, ): mock_expanduser.return_value = '/home/iib-worker' if not config_exists: mock_remove.side_effect = FileNotFoundError() mock_exists.return_value = template_exists mock_open.side_effect = mock.mock_open(read_data=( r'{"auths": {"quay.io": {"auth": "IkhlbGxvIE9wZXJhdG9yLCBnaXZlIG1lIHRoZSBudW1iZXIg' r'Zm9yIDkxMSEiIC0gSG9tZXIgSi4gU2ltcHNvbgo="}, "quay.overwrite.io": ' r'{"auth": "foo_bar"}}}')) registry_auths = { 'auths': { 'registry.redhat.io': { 'auth': 'YOLO' }, 'registry.redhat.stage.io': { 'auth': 'YOLO_FOO' }, 'quay.overwrite.io': { 'auth': 'YOLO_QUAY' }, } } with utils.set_registry_auths(registry_auths): pass mock_remove.assert_called_once_with('/home/iib-worker/.docker/config.json') if template_exists: mock_open.assert_has_calls(( mock.call('/home/iib-worker/.docker/config.json.template', 'r'), mock.call('/home/iib-worker/.docker/config.json', 'w'), )) assert mock_open.call_count == 2 assert mock_json_dump.call_args[0][0] == { 'auths': { 'quay.io': { 'auth': ('IkhlbGxvIE9wZXJhdG9yLCBnaXZlIG1lIHRoZSBudW1iZXIgZm9yIDkxMSEiIC0gSG9tZXIgSi' '4gU2ltcHNvbgo=') }, 'quay.overwrite.io': { 'auth': 'YOLO_QUAY' }, 'registry.redhat.io': { 'auth': 'YOLO' }, 'registry.redhat.stage.io': { 'auth': 'YOLO_FOO' }, } } else: mock_open.assert_called_once_with( '/home/iib-worker/.docker/config.json', 'w') assert mock_open.call_count == 1 assert mock_json_dump.call_args[0][0] == registry_auths mock_rdc.assert_called_once_with()