Пример #1
0
    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
Пример #2
0
    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()
Пример #5
0
    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)
Пример #9
0
    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])
Пример #12
0
    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
Пример #13
0
    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]
        )