def source_get_unique_image(self): source_result = self.workflow.prebuild_results[ PLUGIN_FETCH_SOURCES_KEY] koji_build_id = source_result['sources_for_koji_build_id'] kojisession = get_koji_session(self.workflow, NO_FALLBACK) timestamp = osbs.utils.utcnow().strftime('%Y%m%d%H%M%S') random.seed() current_platform = platform.processor() or 'x86_64' tag_segments = [ self.koji_target or 'none', str(random.randrange(10**(RAND_DIGITS - 1), 10**RAND_DIGITS)), timestamp, current_platform ] tag = '-'.join(tag_segments) get_build_meta = kojisession.getBuild(koji_build_id) pull_specs = get_build_meta['extra']['image']['index']['pull'] source_image_spec = ImageName.parse(pull_specs[0]) source_image_spec.tag = tag organization = get_registries_organization(self.workflow) if organization: source_image_spec.enclose(organization) source_image_spec.registry = None return source_image_spec
def adjust_new_parent_image(self): organization = get_registries_organization(self.workflow) new_parent_image = ImageName.parse(self._new_parent_image) if new_parent_image.registry != self.workflow.builder.base_image.registry: new_parent_image.registry = self.workflow.builder.base_image.registry if organization: self.workflow.builder.base_image.enclose(organization) new_parent_image.enclose(organization) self._new_parent_image = new_parent_image.to_str()
def adjust_new_parent_image(self): organization = get_registries_organization(self.workflow) new_parent_image = ImageName.parse(self._new_parent_image) if new_parent_image.registry != self.workflow.builder.base_image.registry: new_parent_image.registry = self.workflow.builder.base_image.registry if organization: self.workflow.builder.base_image.enclose(organization) new_parent_image.enclose(organization) self._new_parent_image = new_parent_image.to_str()
def adjust_new_parent_image(self): new_parent_image = ImageName.parse(self._new_parent_image) organization = get_registries_organization(self.workflow) source_registry_docker_uri = get_source_registry( self.workflow)['uri'].docker_uri if new_parent_image.registry != source_registry_docker_uri: new_parent_image.registry = source_registry_docker_uri if organization: new_parent_image.enclose(organization) self._new_parent_image = new_parent_image.to_str()
def get_component_name(self): try: labels = Labels(self.labels) _, name = labels.get_name_and_value(Labels.LABEL_TYPE_NAME) except KeyError: self.log.error('Unable to determine component from "Labels"') raise organization = get_registries_organization(self.workflow) if organization: image = ImageName.parse(name) image.enclose(organization) name = image.get_repo() return name
def get_component_name(self): try: labels = Labels(self.labels) _, name = labels.get_name_and_value(Labels.LABEL_TYPE_NAME) except KeyError: self.log.error('Unable to determine component from "Labels"') raise organization = get_registries_organization(self.workflow) if organization: image = ImageName.parse(name) image.enclose(organization) name = image.get_repo() return name
def run(self): """ run the plugin """ if not is_flatpak_build(self.workflow): self.log.info('not flatpak build, skipping plugin') return self._load_source_spec() source_spec = get_flatpak_source_spec(self.workflow) module_info = ModuleSpec.from_str(source_spec) # Load additional information from the flatpak section flatpak_yaml = self.workflow.source.config.flatpak base_image = flatpak_yaml.get('base_image', self.default_base_image) name = flatpak_yaml.get('name', module_info.name) component = flatpak_yaml.get('component', module_info.name) # Create the dockerfile df_path = os.path.join(self.workflow.builder.df_dir, DOCKERFILE_FILENAME) with open(df_path, 'w') as fp: fp.write( DOCKERFILE_TEMPLATE.format( name=name, component=component, cleanupscript=FLATPAK_CLEANUPSCRIPT_FILENAME, includepkgs=FLATPAK_INCLUDEPKGS_FILENAME, stream=module_info.stream.replace('-', '_'), base_image=base_image, relative_repos_path=RELATIVE_REPOS_PATH, rpm_qf_args=rpm_qf_args(), yum_repos_dir=YUM_REPOS_DIR)) self.workflow.builder.set_df_path(df_path) # set source registry and organization source_registry_docker_uri = get_source_registry( self.workflow)['uri'].docker_uri organization = get_registries_organization(self.workflow) self.workflow.builder.dockerfile_images.set_source_registry( source_registry_docker_uri, organization)
def run(self): """ Pull parent images and retag them uniquely for this build. """ build_json = get_build_json() current_platform = platform.processor() or 'x86_64' self.manifest_list_cache = {} organization = get_registries_organization(self.workflow) for nonce, parent in enumerate(sorted(self.workflow.builder.parent_images.keys(), key=str)): image = parent is_base_image = False # original_base_image is an ImageName, so compare parent as an ImageName also if image == self.workflow.builder.original_base_image: is_base_image = True image = self._resolve_base_image(build_json) image = self._ensure_image_registry(image) if organization: image.enclose(organization) parent.enclose(organization) if self.check_platforms: self._validate_platforms_in_image(image) new_arch_image = self._get_image_for_different_arch(image, current_platform) if new_arch_image: image = new_arch_image if self.inspect_only: new_image = image else: new_image = self._pull_and_tag_image(image, build_json, str(nonce)) self.workflow.builder.recreate_parent_images() self.workflow.builder.parent_images[parent] = new_image if is_base_image: if organization: # we want to be sure we have original_base_image enclosed as well self.workflow.builder.original_base_image.enclose(organization) self.workflow.builder.set_base_image(str(new_image), parents_pulled=not self.inspect_only, insecure=self.parent_registry_insecure)
def resolve_docker_image_repo(self): # The plugin parameter docker_image_repo is actually a combination # of source_registry_uri and name label. Thus, the fallback case must # be handled in a non-generic way. try: source_registry = get_source_registry(self.workflow) except KeyError: image = ImageName.parse(self.docker_image_repo_fallback) else: registry = source_registry['uri'].docker_uri image = self.floating_images[0] image.registry = registry organization = get_registries_organization(self.workflow) if organization: image.enclose(organization) self.docker_image_repo = image.to_str(registry=True, tag=False)
def resolve_docker_image_repo(self): # The plugin parameter docker_image_repo is actually a combination # of source_registry_uri and name label. Thus, the fallback case must # be handled in a non-generic way. try: source_registry = get_source_registry(self.workflow) except KeyError: image = ImageName.parse(self.docker_image_repo_fallback) else: registry = source_registry['uri'].docker_uri image = self.floating_images[0] image.registry = registry organization = get_registries_organization(self.workflow) if organization: image.enclose(organization) self.docker_image_repo = image.to_str(registry=True, tag=False)
def run(self): builder = self.workflow.builder dfp = df_parser(builder.df_path) organization = get_registries_organization(self.workflow) df_base = ImageName.parse(dfp.baseimage) if organization and not base_image_is_custom(dfp.baseimage): df_base.enclose(organization) build_base = builder.base_image if not self.workflow.builder.base_from_scratch: # do some sanity checks to defend against bugs and rogue plugins self._sanity_check(df_base, build_base, builder) self.log.info("parent_images '%s'", builder.parent_images) unresolved = [ key for key, val in builder.parent_images.items() if not val ] if unresolved: # this would generally mean pull_base_image didn't run and/or # custom plugins modified parent_images; treat it as an error. raise ParentImageUnresolved( "Parent image(s) unresolved: {}".format(unresolved)) # enclose images from dfp enclosed_parent_images = [] for df_img in dfp.parent_images: if base_image_is_scratch(df_img): enclosed_parent_images.append(df_img) continue parent = ImageName.parse(df_img) if organization and not base_image_is_custom(df_img): parent.enclose(organization) enclosed_parent_images.append(parent) missing = [ df_img for df_img in enclosed_parent_images if df_img not in builder.parent_images ] missing_set = set(missing) if SCRATCH_FROM in missing_set: missing_set.remove(SCRATCH_FROM) if missing_set: # this would indicate another plugin modified parent_images out of sync # with the Dockerfile or some other code bug raise ParentImageMissing( "Lost parent image(s) from Dockerfile: {}".format(missing_set)) # docker inspect all parent images so we can address them by Id parent_image_ids = {} for img, new_img in builder.parent_images.items(): inspection = builder.parent_image_inspect(new_img) try: parent_image_ids[img] = inspection['Id'] except KeyError: # unexpected code bugs or maybe docker weirdness self.log.error( "Id for image %s is missing in inspection: '%s'", new_img, inspection) raise NoIdInspection("Could not inspect Id for image " + str(new_img)) # update the parents in Dockerfile new_parents = [] for parent in enclosed_parent_images: if base_image_is_scratch(parent): new_parents.append(parent) continue pid = parent_image_ids[parent] self.log.info("changed FROM: '%s' -> '%s'", parent, pid) new_parents.append(pid) dfp.parent_images = new_parents # update builder's representation of what will be built builder.parent_images = parent_image_ids if self.workflow.builder.base_from_scratch: return builder.set_base_image(parent_image_ids[df_base]) self.log.debug("for base image '%s' using local image '%s', id '%s'", df_base, build_base, parent_image_ids[df_base])
def run(self): """ Pull parent images and retag them uniquely for this build. """ build_json = get_build_json() current_platform = platform.processor() or 'x86_64' self.manifest_list_cache = {} organization = get_registries_organization(self.workflow) for nonce, parent in enumerate( sorted(self.workflow.builder.parent_images.keys(), key=str)): image = parent is_base_image = False # original_base_image is an ImageName, so compare parent as an ImageName also if image == self.workflow.builder.original_base_image: is_base_image = True image = self._resolve_base_image(build_json) image = self._ensure_image_registry(image) if organization: image.enclose(organization) parent.enclose(organization) if self.check_platforms: # run only at orchestrator self._validate_platforms_in_image(image) self._collect_image_digests(image) # try to stay with digests image_with_digest = self._get_image_with_digest( image, current_platform) if image_with_digest is None: self.log.warning( "Cannot resolve platform '%s' specific digest for image '%s'", current_platform, image) else: self.log.info("Replacing image '%s' with '%s'", image, image_with_digest) image = image_with_digest if self.check_platforms: new_arch_image = self._get_image_for_different_arch( image, current_platform) if new_arch_image: image = new_arch_image if self.inspect_only: new_image = image else: new_image = self._pull_and_tag_image(image, build_json, str(nonce)) self.workflow.builder.recreate_parent_images() self.workflow.builder.parent_images[parent] = new_image if is_base_image: if organization: # we want to be sure we have original_base_image enclosed as well self.workflow.builder.original_base_image.enclose( organization) self.workflow.builder.set_base_image( str(new_image), insecure=self.parent_registry_insecure) self.workflow.builder.parents_pulled = not self.inspect_only self.workflow.builder.base_image_insecure = self.parent_registry_insecure
def run(self): """ Pull parent images and retag them uniquely for this build. """ self.manifest_list_cache.clear() build_json = get_build_json() organization = get_registries_organization(self.workflow) digest_fetching_exceptions = [] for nonce, parent in enumerate( sorted(self.workflow.builder.parent_images.keys(), key=str)): if base_image_is_custom(parent.to_str()): continue image = parent is_base_image = False use_original_tag = False # original_base_image is an ImageName, so compare parent as an ImageName also if image == self.workflow.builder.original_base_image: is_base_image = True use_original_tag = True image = self._resolve_base_image(build_json) image = self._ensure_image_registry(image) if organization: image.enclose(organization) parent.enclose(organization) if self.check_platforms: # run only at orchestrator self._validate_platforms_in_image(image) try: self._store_manifest_digest( image, use_original_tag=use_original_tag) except RuntimeError as exc: digest_fetching_exceptions.append(exc) image_with_digest = self._get_image_with_digest(image) if image_with_digest is None: self.log.warning( "Cannot resolve manifest digest for image '%s'", image) else: self.log.info("Replacing image '%s' with '%s'", image, image_with_digest) image = image_with_digest if not self.inspect_only: image = self._pull_and_tag_image(image, build_json, str(nonce)) self.workflow.builder.recreate_parent_images() self.workflow.builder.parent_images[parent] = image if is_base_image: if organization: # we want to be sure we have original_base_image enclosed as well self.workflow.builder.original_base_image.enclose( organization) self.workflow.builder.set_base_image( str(image), insecure=self.parent_registry_insecure, dockercfg_path=self.parent_registry_dockercfg_path) if digest_fetching_exceptions: raise RuntimeError( 'Error when extracting parent images manifest digests: {}'. format(digest_fetching_exceptions)) self.workflow.builder.parents_pulled = not self.inspect_only self.workflow.builder.base_image_insecure = self.parent_registry_insecure
def run(self): builder = self.workflow.builder dfp = df_parser(builder.df_path) organization = get_registries_organization(self.workflow) df_base = ImageName.parse(dfp.baseimage) if organization and not base_image_is_custom(dfp.baseimage): df_base.enclose(organization) build_base = builder.base_image if not self.workflow.builder.base_from_scratch: # do some sanity checks to defend against bugs and rogue plugins self._sanity_check(df_base, build_base, builder) self.log.info("parent_images '%s'", builder.parent_images) unresolved = [key for key, val in builder.parent_images.items() if not val] if unresolved: # this would generally mean pull_base_image didn't run and/or # custom plugins modified parent_images; treat it as an error. raise ParentImageUnresolved("Parent image(s) unresolved: {}".format(unresolved)) # enclose images from dfp enclosed_parent_images = [] for df_img in dfp.parent_images: if base_image_is_scratch(df_img): enclosed_parent_images.append(df_img) continue parent = ImageName.parse(df_img) if organization and not base_image_is_custom(df_img): parent.enclose(organization) enclosed_parent_images.append(parent) missing = [df_img for df_img in enclosed_parent_images if df_img not in builder.parent_images] missing_set = set(missing) if SCRATCH_FROM in missing_set: missing_set.remove(SCRATCH_FROM) if missing_set: # this would indicate another plugin modified parent_images out of sync # with the Dockerfile or some other code bug raise ParentImageMissing("Lost parent image(s) from Dockerfile: {}".format(missing_set)) # docker inspect all parent images so we can address them by Id parent_image_ids = {} for img, new_img in builder.parent_images.items(): inspection = builder.parent_image_inspect(new_img) try: parent_image_ids[img] = inspection['Id'] except KeyError: # unexpected code bugs or maybe docker weirdness self.log.error( "Id for image %s is missing in inspection: '%s'", new_img, inspection) raise NoIdInspection("Could not inspect Id for image " + str(new_img)) # update the parents in Dockerfile new_parents = [] for parent in enclosed_parent_images: if base_image_is_scratch(parent): new_parents.append(parent) continue pid = parent_image_ids[parent] self.log.info("changed FROM: '%s' -> '%s'", parent, pid) new_parents.append(pid) dfp.parent_images = new_parents # update builder's representation of what will be built builder.parent_images = parent_image_ids if self.workflow.builder.base_from_scratch: return builder.set_base_image(parent_image_ids[df_base]) self.log.debug( "for base image '%s' using local image '%s', id '%s'", df_base, build_base, parent_image_ids[df_base] )