def get_hidden_index_database(from_index, base_dir): """ Get hidden database file from the specified index image and save it locally. :param str from_index: index image to get database file from. :param str base_dir: base directory to which the database file should be saved. :return: path to the copied database file. :rtype: str """ from iib.workers.tasks.build import _copy_files_from_image log.info("Store hidden index.db from %s", from_index) conf = get_worker_config() base_db_file = os.path.join(base_dir, conf['temp_index_db_path']) os.makedirs(os.path.dirname(base_db_file), exist_ok=True) _copy_files_from_image(from_index, conf['hidden_index_db_path'], base_db_file) return base_db_file
def get_catalog_dir(from_index, base_dir): """ Get file-based catalog directory from the specified index image and save it locally. :param str from_index: index image to get file-based catalog directory from. :param str base_dir: base directory to which the database file should be saved. :return: path to the copied file-based catalog directory. :rtype: str :raises IIBError: if any podman command fails. """ from iib.workers.tasks.build import _copy_files_from_image from iib.workers.tasks.utils import get_image_label log.info("Store file-based catalog directory from %s", from_index) fbc_dir_path = get_image_label(from_index, 'operators.operatorframework.io.index.configs.v1') if not fbc_dir_path: error_msg = f'Index image {from_index} does not contain file-based catalog.' log.error(error_msg) raise IIBError(error_msg) _copy_files_from_image(from_index, fbc_dir_path, base_dir) return os.path.join(base_dir, os.path.basename(fbc_dir_path))
def test_copy_files_from_image(mock_run_cmd, fail_rm): image = 'bundle-image:latest' src_path = '/manifests' dest_path = '/destination/path/manifests' container_id = 'df2ff736efeaff598330a128b3dc4875caf254d9f416cefd86ec009b74d1488b' side_effect = [f'{container_id}\n', ''] if fail_rm: side_effect.append(IIBError('Uh oh! Something went wrong.')) else: side_effect.append('') mock_run_cmd.side_effect = side_effect build._copy_files_from_image(image, src_path, dest_path) mock_run_cmd.assert_has_calls([ mock.call(['podman', 'create', image, 'unused'], exc_msg=mock.ANY), mock.call(['podman', 'cp', f'{container_id}:{src_path}', dest_path], exc_msg=mock.ANY), mock.call(['podman', 'rm', container_id], exc_msg=mock.ANY), ])
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')