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' )
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
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_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