def find_in_data(self, data): return ImageName.parse(chain_get(data, self.path))
def _adjust_operator_bundle(manifests_path, metadata_path, organization=None): """ Apply modifications to the operator manifests at the given location. For any container image pull spec found in the Operator CSV files, replace floating tags with pinned digests, e.g. `image:latest` becomes `image@sha256:...`. If spec.relatedImages is not set, it will be set with the pinned digests. If it is set but there are also RELATED_IMAGE_* environment variables set, an exception will be raised. This method relies on the OperatorManifest class to properly identify and apply the modifications as needed. :param str manifests_path: the full path to the directory containing the operator manifests. :param str metadata_path: the full path to the directory containing the bundle metadata files. :param str organization: the organization this bundle is for. If no organization is provided, no custom behavior will be applied. :raises IIBError: if the operator manifest has invalid entries :return: a dictionary of labels to set on the bundle :rtype: dict """ package_name, labels = _apply_package_name_suffix(metadata_path, organization) operator_manifest = OperatorManifest.from_directory(manifests_path) found_pullspecs = set() operator_csvs = [] for operator_csv in operator_manifest.files: if operator_csv.has_related_images(): csv_file_name = os.path.basename(operator_csv.path) if operator_csv.has_related_image_envs(): raise IIBError( f'The ClusterServiceVersion file {csv_file_name} has entries in ' 'spec.relatedImages and one or more containers have RELATED_IMAGE_* ' 'environment variables set. This is not allowed for bundles regenerated with ' 'IIB.') log.debug( 'Skipping pinning since the ClusterServiceVersion file %s has entries in ' 'spec.relatedImages', csv_file_name, ) continue operator_csvs.append(operator_csv) for pullspec in operator_csv.get_pullspecs(): found_pullspecs.add(pullspec) conf = get_worker_config() registry_replacements = (conf['iib_organization_customizations'].get( organization, {}).get('registry_replacements', {})) # Resolve pull specs to container image digests replacement_pullspecs = {} for pullspec in found_pullspecs: replacement_needed = False if ':' not in ImageName.parse(pullspec).tag: replacement_needed = True # Always resolve the image to make sure it's valid resolved_image = ImageName.parse(_get_resolved_image( pullspec.to_str())) if registry_replacements.get(resolved_image.registry): replacement_needed = True resolved_image.registry = registry_replacements[ resolved_image.registry] if replacement_needed: log.debug( '%s will be replaced with %s', pullspec, resolved_image.to_str(), ) replacement_pullspecs[pullspec] = resolved_image # Apply modifications to the operator bundle image metadata for operator_csv in operator_csvs: csv_file_name = os.path.basename(operator_csv.path) log.info('Replacing the pull specifications on %s', csv_file_name) operator_csv.replace_pullspecs_everywhere(replacement_pullspecs) log.info('Setting spec.relatedImages on %s', csv_file_name) operator_csv.set_related_images() operator_csv.dump() if organization: _adjust_csv_annotations(operator_manifest.files, package_name, organization) return labels
def __init__(self, name, value, replace, path): self._name = name self._value = ImageName.parse(value) self._replace = ImageName.parse(replace) self._path = path
def _overwrite_from_index( request_id, output_pull_spec, from_index, resolved_prebuild_from_index, overwrite_from_index_token=None, ): """ Overwrite the ``from_index`` image. :param int request_id: the ID of the request this index image is for. :param str output_pull_spec: the pull specification of the manifest list for the index image that IIB built. :param str from_index: the pull specification of the image to overwrite. :param str resolved_prebuild_from_index: resolved index image before starting the build. :param str overwrite_from_index_token: the user supplied token to use when overwriting the ``from_index`` image. If this is not set, IIB's configured credentials will be used. :raises IIBError: if one of the skopeo commands fails or if the index image has changed since IIB build started. """ _verify_index_image(resolved_prebuild_from_index, from_index, overwrite_from_index_token) state_reason = f'Overwriting the index image {from_index} with {output_pull_spec}' log.info(state_reason) set_request_state(request_id, 'in_progress', state_reason) new_index_src = f'docker://{output_pull_spec}' temp_dir = None try: if overwrite_from_index_token: output_pull_spec_registry = ImageName.parse( output_pull_spec).registry from_index_registry = ImageName.parse(from_index).registry # If the registries are the same and `overwrite_from_index_token` was supplied, that # means that IIB's token will likely not have access to read the `from_index` image. # This means IIB must first export the manifest list and all the manifests locally and # then overwrite the `from_index` image with the exported version using the user # supplied token. # # When a newer version of buildah is available in RHEL 8, then that can be used instead # of the manifest-tool to create the manifest list locally which means this workaround # can be removed. if output_pull_spec_registry == from_index_registry: temp_dir = tempfile.TemporaryDirectory(prefix='iib-') new_index_src = f'oci:{temp_dir.name}' log.info( 'The registry used by IIB (%s) is also the registry where from_index (%s) will ' 'be overwritten using the user supplied token. Will perform a workaround which ' 'will cause the manifest digests to change but the content is the same.', output_pull_spec_registry, from_index_registry, ) exc_msg = f'Failed to export {output_pull_spec} to the OCI format' _skopeo_copy(f'docker://{output_pull_spec}', new_index_src, copy_all=True, exc_msg=exc_msg) exc_msg = f'Failed to overwrite the input from_index container image of {from_index}' with set_registry_token(overwrite_from_index_token, from_index): _skopeo_copy(new_index_src, f'docker://{from_index}', copy_all=True, exc_msg=exc_msg) finally: if temp_dir: temp_dir.cleanup()