def render(self, validate=True):
        super(BuildRequestV2, self).render(validate=validate)

        self.template['spec']['source']['git'][
            'uri'] = self.user_params.git_uri.value
        self.template['spec']['source']['git'][
            'ref'] = self.user_params.git_ref.value

        if self.has_ist_trigger():
            imagechange = self.template['spec']['triggers'][0]['imageChange']
            imagechange['from']['name'] = self.trigger_imagestreamtag

        # Set git-repo-name and git-full-name labels
        repo_name = git_repo_humanish_part_from_uri(
            self.user_params.git_uri.value)
        # Use the repo name to differentiate different repos, but include the full url as an
        # optional filter.
        self.set_label('git-repo-name', repo_name)
        self.set_label('git-branch', self.user_params.git_branch.value)
        self.set_label('git-full-repo', self.user_params.git_uri.value)

        koji_task_id = self.user_params.koji_task_id.value
        if koji_task_id is not None:
            # keep also original task for all manual builds with task
            # that way when delegated task for autorebuild will be used
            # we will still keep track of it
            if self.user_params.triggered_after_koji_task.value is None:
                self.set_label('original-koji-task-id', str(koji_task_id))

        # Set template.spec.strategy.customStrategy.env[] USER_PARAMS
        # Adjust triggers for custom base image
        if (self.template['spec'].get('triggers', []) and
            (self.is_custom_base_image() or self.is_from_scratch_image())):
            if self.is_custom_base_image():
                logger.info(
                    "removing triggers from request because custom base image")
            elif self.is_from_scratch_image():
                logger.info('removing from request because FROM scratch image')
            del self.template['spec']['triggers']

        self.adjust_for_repo_info()
        self.adjust_for_isolated(self.user_params.release)
        self.render_node_selectors(self.user_params.build_type.value)

        self._set_deadline()

        # Log build json
        # Return build json
        self.build_json = self.template
        logger.debug(self.build_json)
        return self.build_json
Example #2
0
    def _set_binary_container_pipeline_data(self, pipeline_run_name,
                                            pipeline_run_data, user_params):
        # set pipeline run name
        pipeline_run_data['metadata']['name'] = pipeline_run_name

        # set user params
        for param in pipeline_run_data['spec']['params']:
            if param['name'] == PRUN_TEMPLATE_USER_PARAMS:
                param['value'] = user_params.to_json()

        for ws in pipeline_run_data['spec']['workspaces']:
            # set reactor config map name
            if ws['name'] == PRUN_TEMPLATE_REACTOR_CONFIG_WS:
                ws['configmap']['name'] = user_params.reactor_config_map

            # set namespace for volume claim template
            if ws['name'] in [
                    PRUN_TEMPLATE_BUILD_DIR_WS, PRUN_TEMPLATE_CONTEXT_DIR_WS
            ]:
                ws['volumeClaimTemplate']['metadata'][
                    'namespace'] = self.os_conf.get_namespace()

        # set labels
        all_labels = {}

        if user_params.koji_task_id is not None:
            all_labels['koji-task-id'] = str(user_params.koji_task_id)

        if user_params.scratch:
            all_labels['scratch'] = 'true'

        if user_params.isolated:
            all_labels['isolated'] = 'true'
            all_labels['isolated-release'] = user_params.release

        repo_name = utils.git_repo_humanish_part_from_uri(user_params.git_uri)
        # Use the repo name to differentiate different repos, but include the full url as an
        # optional filter.
        all_labels['git-repo-name'] = repo_name
        all_labels['git-branch'] = user_params.git_branch
        all_labels['git-full-repo'] = user_params.git_uri

        pipeline_run_data['metadata']['labels'] = all_labels
Example #3
0
 def set_params(self, sources_command=None, architecture=None, vendor=None,
                build_host=None, authoritative_registry=None,
                koji_target=None, kojiroot=None, kojihub=None,
                source_secret=None, # compatibility name for pulp_secret
                pulp_secret=None, pulp_registry=None, nfs_server_path=None,
                nfs_dest_dir=None, git_branch=None, base_image=None,
                name_label=None, git_push_url=None, git_push_username=None,
                **kwargs):
     super(ProdSpec, self).set_params(**kwargs)
     self.sources_command.value = sources_command
     self.architecture.value = architecture
     self.vendor.value = vendor
     self.build_host.value = build_host
     self.authoritative_registry.value = authoritative_registry
     self.koji_target.value = koji_target
     self.kojiroot.value = kojiroot
     self.kojihub.value = kojihub
     self.pulp_secret.value = pulp_secret or source_secret
     self.pulp_registry.value = pulp_registry
     self.nfs_server_path.value = nfs_server_path
     self.nfs_dest_dir.value = nfs_dest_dir
     self.git_push_url.value = git_push_url
     self.git_push_username.value = git_push_username
     self.git_branch.value = git_branch
     repo = git_repo_humanish_part_from_uri(self.git_uri.value)
     self.name.value = "{repo}-{branch}".format(repo=repo,
                                                branch=git_branch)
     self.trigger_imagestreamtag.value = get_imagestreamtag_from_image(base_image)
     self.imagestream_name.value = name_label.replace('/', '-')
     self.imagestream_url.value = os.path.join(self.registry_uri.value,
                                               name_label)
     timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
     self.image_tag.value = "%s/%s:%s-%s" % (
         self.user.value,
         self.component.value,
         self.koji_target.value,
         timestamp
     )
Example #4
0
    def render(self, validate=True):
        if validate:
            self.spec.validate()

        # !IMPORTANT! can't be too long: https://github.com/openshift/origin/issues/733
        self.template['metadata']['name'] = self.spec.name.value
        self.render_resource_limits()
        self.template['spec']['source']['git']['uri'] = self.spec.git_uri.value
        self.template['spec']['source']['git']['ref'] = self.spec.git_ref.value

        if self.spec.registry_uris.value:
            primary_registry_uri = self.spec.registry_uris.value[0].docker_uri
            tag_with_registry = '{0}/{1}'.format(primary_registry_uri,
                                                 self.spec.image_tag.value)
            self.template['spec']['output']['to']['name'] = tag_with_registry
        else:
            self.template['spec']['output']['to']['name'] = self.spec.image_tag.value

        self.render_tag_and_push_registries()

        if 'triggers' in self.template['spec']:
            imagechange = self.template['spec']['triggers'][0]['imageChange']
            imagechange['from']['name'] = self.spec.trigger_imagestreamtag.value

        self.render_add_yum_repo_by_url()

        use_auth = self.spec.use_auth.value
        self.render_check_and_set_rebuild(use_auth=use_auth)
        self.render_store_metadata_in_osv3(use_auth=use_auth)

        # For Origin 1.0.6 we'll use the 'secrets' array; for earlier
        # versions we'll just use 'sourceSecret'
        if self._openshift_required_version < parse_version('1.0.6'):
            if 'secrets' in self.template['spec']['strategy']['customStrategy']:
                del self.template['spec']['strategy']['customStrategy']['secrets']
        else:
            if 'sourceSecret' in self.template['spec']['source']:
                del self.template['spec']['source']['sourceSecret']

        if self.spec.build_imagestream.value:
            self.template['spec']['strategy']['customStrategy']['from']['kind'] = 'ImageStreamTag'
            self.template['spec']['strategy']['customStrategy']['from']['name'] = \
                self.spec.build_imagestream.value
        else:
            self.template['spec']['strategy']['customStrategy']['from']['name'] = \
                self.spec.build_image.value

        repo_name = git_repo_humanish_part_from_uri(self.spec.git_uri.value)
        # NOTE: Since only the repo name is used, a forked repos will have
        # the same git-repo-name tag. This is a known limitation. If this
        # use case must be handled properly, the git URI must be taken into
        # account.
        self.set_label('git-repo-name', repo_name)
        self.set_label('git-branch', self.spec.git_branch.value)

        if self.spec.sources_command.value is not None:
            self.dj.dock_json_set_arg('prebuild_plugins', "distgit_fetch_artefacts",
                                      "command", self.spec.sources_command.value)
        else:
            logger.info("removing distgit_fetch_artefacts, no sources_command was provided")
            self.dj.remove_plugin('prebuild_plugins', 'distgit_fetch_artefacts')

        # pull_base_image wants a docker URI so strip off the scheme part
        source_registry = self.spec.source_registry_uri.value
        self.dj.dock_json_set_arg('prebuild_plugins', "pull_base_image", "parent_registry",
                                  source_registry.docker_uri if source_registry else None)

        # The rebuild trigger requires git_branch and git_push_url
        # parameters, but those parameters are optional. If either was
        # not provided, remove the trigger.
        remove_triggers = False
        for param_name in ['git_branch', 'git_push_url']:
            param = getattr(self.spec, param_name)
            if not param.value:
                logger.info("removing triggers as no %s specified", param_name)
                remove_triggers = True
                # Continue the loop so we log everything that's missing

        if self.is_custom_base_image():
            logger.info('removing triggers for custom base image build')
            remove_triggers = True

        if remove_triggers and 'triggers' in self.template['spec']:
            del self.template['spec']['triggers']

        self.adjust_for_triggers()
        self.adjust_for_scratch()
        self.adjust_for_custom_base_image()

        # Enable/disable plugins as needed for target registry API versions
        self.adjust_for_registry_api_versions()

        self.set_secrets({('postbuild_plugins',
                           'pulp_push',
                           'pulp_secret_path'):
                          self.spec.pulp_secret.value,

                          ('postbuild_plugins',
                           'pulp_sync',
                           'pulp_secret_path'):
                          self.spec.pulp_secret.value,

                          # pulp_sync registry_secret_path set
                          # in render_pulp_sync

                          ('exit_plugins', 'sendmail', 'pdc_secret_path'):
                          self.spec.pdc_secret.value,

                          ('exit_plugins', 'koji_promote', 'koji_ssl_certs'):
                          self.spec.koji_certs_secret.value,

                          ('prebuild_plugins', 'add_filesystem', 'koji_ssl_certs_dir'):
                          self.spec.koji_certs_secret.value,

                          ('postbuild_plugins', 'tag_and_push',
                           # Only set the secrets for the build, don't
                           # add the path to the plugin's
                           # configuration. This is done elsewhere.
                           None):
                          self.spec.registry_secrets.value})

        if self.spec.pulp_secret.value:
            # Don't push to docker registry, we're using pulp here
            # but still construct the unique tag
            self.template['spec']['output']['to']['name'] = \
                self.spec.image_tag.value

        koji_task_id = self.spec.koji_task_id.value
        if koji_task_id is not None:
            self.template['metadata'].setdefault('labels', {})
            self.template['metadata']['labels']['koji-task-id'] = str(koji_task_id)

        use_auth = self.spec.use_auth.value
        self.render_add_filesystem()
        self.render_add_labels_in_dockerfile()
        self.render_koji()
        self.render_bump_release()
        self.render_import_image(use_auth=use_auth)
        self.render_pulp_push()
        self.render_pulp_sync()
        self.render_koji_promote(use_auth=use_auth)
        self.render_sendmail()

        self.dj.write_dock_json()
        self.build_json = self.template
        logger.debug(self.build_json)
        return self.build_json
Example #5
0
    def render(self, validate=True):
        if validate:
            self.spec.validate()

        # !IMPORTANT! can't be too long: https://github.com/openshift/origin/issues/733
        self.template['metadata']['name'] = self.spec.name.value
        self.render_resource_limits()
        self.template['spec']['source']['git']['uri'] = self.spec.git_uri.value
        self.template['spec']['source']['git']['ref'] = self.spec.git_ref.value

        if self.spec.registry_uris.value:
            primary_registry_uri = self.spec.registry_uris.value[0].docker_uri
            tag_with_registry = '{0}/{1}'.format(primary_registry_uri,
                                                 self.spec.image_tag.value)
            self.template['spec']['output']['to']['name'] = tag_with_registry
        else:
            self.template['spec']['output']['to'][
                'name'] = self.spec.image_tag.value

        self.render_tag_and_push_registries()

        if 'triggers' in self.template['spec']:
            imagechange = self.template['spec']['triggers'][0]['imageChange']
            imagechange['from'][
                'name'] = self.spec.trigger_imagestreamtag.value

        self.render_add_yum_repo_by_url()

        use_auth = self.spec.use_auth.value
        self.render_check_and_set_rebuild(use_auth=use_auth)
        self.render_store_metadata_in_osv3(use_auth=use_auth)

        # For Origin 1.0.6 we'll use the 'secrets' array; for earlier
        # versions we'll just use 'sourceSecret'
        if self._openshift_required_version < parse_version('1.0.6'):
            if 'secrets' in self.template['spec']['strategy'][
                    'customStrategy']:
                del self.template['spec']['strategy']['customStrategy'][
                    'secrets']
        else:
            if 'sourceSecret' in self.template['spec']['source']:
                del self.template['spec']['source']['sourceSecret']

        if self.spec.build_imagestream.value:
            self.template['spec']['strategy']['customStrategy']['from'][
                'kind'] = 'ImageStreamTag'
            self.template['spec']['strategy']['customStrategy']['from']['name'] = \
                self.spec.build_imagestream.value
        else:
            self.template['spec']['strategy']['customStrategy']['from']['name'] = \
                self.spec.build_image.value

        repo_name = git_repo_humanish_part_from_uri(self.spec.git_uri.value)
        # NOTE: Since only the repo name is used, a forked repos will have
        # the same git-repo-name tag. This is a known limitation. If this
        # use case must be handled properly, the git URI must be taken into
        # account.
        self.set_label('git-repo-name', repo_name)
        self.set_label('git-branch', self.spec.git_branch.value)

        if self.spec.sources_command.value is not None:
            self.dj.dock_json_set_arg('prebuild_plugins',
                                      "distgit_fetch_artefacts", "command",
                                      self.spec.sources_command.value)
        else:
            logger.info(
                "removing distgit_fetch_artefacts, no sources_command was provided"
            )
            self.dj.remove_plugin('prebuild_plugins',
                                  'distgit_fetch_artefacts')

        # pull_base_image wants a docker URI so strip off the scheme part
        source_registry = self.spec.source_registry_uri.value
        self.dj.dock_json_set_arg(
            'prebuild_plugins', "pull_base_image", "parent_registry",
            source_registry.docker_uri if source_registry else None)

        # The rebuild trigger requires git_branch and git_push_url
        # parameters, but those parameters are optional. If either was
        # not provided, remove the trigger.
        remove_triggers = False
        for param_name in ['git_branch', 'git_push_url']:
            param = getattr(self.spec, param_name)
            if not param.value:
                logger.info("removing triggers as no %s specified", param_name)
                remove_triggers = True
                # Continue the loop so we log everything that's missing

        if self.is_custom_base_image():
            logger.info('removing triggers for custom base image build')
            remove_triggers = True

        if remove_triggers and 'triggers' in self.template['spec']:
            del self.template['spec']['triggers']

        self.adjust_for_triggers()
        self.adjust_for_scratch()
        self.adjust_for_custom_base_image()

        # Enable/disable plugins as needed for target registry API versions
        self.adjust_for_registry_api_versions()

        self.set_secrets({
            ('postbuild_plugins', 'pulp_push', 'pulp_secret_path'):
            self.spec.pulp_secret.value,
            ('postbuild_plugins', 'pulp_sync', 'pulp_secret_path'):
            self.spec.pulp_secret.value,

            # pulp_sync registry_secret_path set
            # in render_pulp_sync
            ('exit_plugins', 'sendmail', 'pdc_secret_path'):
            self.spec.pdc_secret.value,
            ('exit_plugins', 'koji_promote', 'koji_ssl_certs'):
            self.spec.koji_certs_secret.value,
            ('prebuild_plugins', 'add_filesystem', 'koji_ssl_certs_dir'):
            self.spec.koji_certs_secret.value,
            (
                'postbuild_plugins',
                'tag_and_push',
                # Only set the secrets for the build, don't
                # add the path to the plugin's
                # configuration. This is done elsewhere.
                None):
            self.spec.registry_secrets.value
        })

        if self.spec.pulp_secret.value:
            # Don't push to docker registry, we're using pulp here
            # but still construct the unique tag
            self.template['spec']['output']['to']['name'] = \
                self.spec.image_tag.value

        koji_task_id = self.spec.koji_task_id.value
        if koji_task_id is not None:
            self.template['metadata'].setdefault('labels', {})
            self.template['metadata']['labels']['koji-task-id'] = str(
                koji_task_id)

        use_auth = self.spec.use_auth.value
        self.render_add_filesystem()
        self.render_add_labels_in_dockerfile()
        self.render_koji()
        self.render_bump_release()
        self.render_import_image(use_auth=use_auth)
        self.render_pulp_push()
        self.render_pulp_sync()
        self.render_koji_promote(use_auth=use_auth)
        self.render_sendmail()

        self.dj.write_dock_json()
        self.build_json = self.template
        logger.debug(self.build_json)
        return self.build_json
Example #6
0
def test_git_repo_humanish_part_from_uri(uri, humanish):
    assert git_repo_humanish_part_from_uri(uri) == humanish
Example #7
0
def test_git_repo_humanish_part_from_uri(uri, humanish):
    assert git_repo_humanish_part_from_uri(uri) == humanish
Example #8
0
    def render(self, validate=True):
        # the api is required for BuildRequestV2
        # can't check that its an OSBS object because of the circular import
        if not self.osbs_api:
            raise OsbsValidationException

        # Validate BuildUserParams
        if validate:
            self.user_params.validate()

        self.render_name(self.user_params.name.value,
                         self.user_params.image_tag.value,
                         self.user_params.platform.value)
        self.render_resource_limits()

        self.template['spec']['source']['git'][
            'uri'] = self.user_params.git_uri.value
        self.template['spec']['source']['git'][
            'ref'] = self.user_params.git_ref.value

        self.template['spec']['output']['to'][
            'name'] = self.user_params.image_tag.value

        if self.has_ist_trigger():
            imagechange = self.template['spec']['triggers'][0]['imageChange']
            imagechange['from'][
                'name'] = self.user_params.trigger_imagestreamtag.value

        custom_strategy = self.template['spec']['strategy']['customStrategy']
        if self.user_params.build_imagestream.value:
            custom_strategy['from']['kind'] = 'ImageStreamTag'
            custom_strategy['from'][
                'name'] = self.user_params.build_imagestream.value
        else:
            custom_strategy['from'][
                'name'] = self.user_params.build_image.value

        # Set git-repo-name and git-full-name labels
        repo_name = git_repo_humanish_part_from_uri(
            self.user_params.git_uri.value)
        # Use the repo name to differentiate different repos, but include the full url as an
        # optional filter.
        self.set_label('git-repo-name', repo_name)
        self.set_label('git-branch', self.user_params.git_branch.value)
        self.set_label('git-full-repo', self.user_params.git_uri.value)

        koji_task_id = self.user_params.koji_task_id.value
        if koji_task_id is not None:
            self.set_label('koji-task-id', str(koji_task_id))

            # keep also original task for all manual builds with task
            # that way when delegated task for autorebuild will be used
            # we will still keep track of it
            if self.triggered_after_koji_task is None:
                self.set_label('original-koji-task-id', str(koji_task_id))

        # Set template.spec.strategy.customStrategy.env[] USER_PARAMS
        # Set required_secrets based on reactor_config
        # Set worker_token_secrets based on reactor_config, if any
        self.set_reactor_config()
        self.set_data_from_reactor_config()

        # Adjust triggers for custom base image
        if (self.template['spec'].get('triggers', []) and
            (self.is_custom_base_image() or self.is_from_scratch_image())):
            if self.is_custom_base_image():
                logger.info(
                    "removing triggers from request because custom base image")
            elif self.is_from_scratch_image():
                logger.info('removing from request because FROM scratch image')
            del self.template['spec']['triggers']

        self.adjust_for_repo_info()
        self.adjust_for_scratch()
        self.adjust_for_isolated(self.user_params.release)
        self.render_node_selectors(self.user_params.build_type.value)

        self.set_deadline(self.user_params.build_type.value)

        # Set our environment variables
        custom_strategy['env'].append({
            'name': 'USER_PARAMS',
            'value': self.user_params.to_json(),
        })
        # delete the ATOMIC_REACTOR_PLUGINS placeholder
        for (index, env) in enumerate(custom_strategy['env']):
            if env['name'] == 'ATOMIC_REACTOR_PLUGINS':
                del custom_strategy['env'][index]
                break

        # Log build json
        # Return build json
        self.build_json = self.template
        logger.debug(self.build_json)
        return self.build_json
Example #9
0
    def set_params(
            self,
            sources_command=None,
            architecture=None,
            vendor=None,
            build_host=None,
            authoritative_registry=None,
            distribution_scope=None,
            koji_target=None,
            kojiroot=None,
            kojihub=None,
            koji_certs_secret=None,
            source_secret=None,  # compatibility name for pulp_secret
            pulp_secret=None,
            pulp_registry=None,
            pdc_secret=None,
            pdc_url=None,
            smtp_uri=None,
            nfs_server_path=None,
            nfs_dest_dir=None,
            git_branch=None,
            base_image=None,
            name_label=None,
            git_push_url=None,
            git_push_username=None,
            builder_build_json_dir=None,
            registry_api_versions=None,
            **kwargs):
        super(ProdSpec, self).set_params(**kwargs)
        self.sources_command.value = sources_command
        self.architecture.value = architecture
        self.vendor.value = vendor
        self.build_host.value = build_host
        self.authoritative_registry.value = authoritative_registry
        self.distribution_scope.value = distribution_scope
        self.registry_api_versions.value = registry_api_versions
        self.koji_target.value = koji_target
        self.kojiroot.value = kojiroot
        self.kojihub.value = kojihub
        self.koji_certs_secret.value = koji_certs_secret
        self.pulp_secret.value = pulp_secret or source_secret
        self.pulp_registry.value = pulp_registry
        self.pdc_secret.value = pdc_secret
        self.pdc_url.value = pdc_url
        self.smtp_uri.value = smtp_uri
        self.nfs_server_path.value = nfs_server_path
        self.nfs_dest_dir.value = nfs_dest_dir
        self.git_push_url.value = git_push_url
        self.git_push_username.value = git_push_username
        self.git_branch.value = git_branch
        repo = git_repo_humanish_part_from_uri(self.git_uri.value)
        namefmt = "{repo}-{branch}"
        self.name.value = namefmt.format(repo=repo,
                                         branch=git_branch or 'unknown')
        self.trigger_imagestreamtag.value = get_imagestreamtag_from_image(
            base_image)
        self.builder_build_json_dir.value = builder_build_json_dir
        self.imagestream_name.value = name_label.replace('/', '-')
        # The ImageStream should take tags from the source registry
        # or, if no source registry is set, the first listed registry
        imagestream_reg = self.source_registry_uri.value
        if not imagestream_reg:
            try:
                imagestream_reg = self.registry_uris.value[0]
            except IndexError:
                raise OsbsValidationException("No registries specified")

        self.imagestream_url.value = os.path.join(imagestream_reg.docker_uri,
                                                  name_label)
        logger.debug("setting 'imagestream_url' to '%s'",
                     self.imagestream_url.value)
        insecure = imagestream_reg.uri.startswith('http://')
        self.imagestream_insecure_registry.value = insecure
        logger.debug("setting 'imagestream_insecure_registry' to %r", insecure)
        timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        self.image_tag.value = "%s/%s:%s-%s" % (
            self.user.value, self.component.value, self.koji_target.value
            or 'none', timestamp)
Example #10
0
    def render(self, validate=True):
        if validate:
            self.spec.validate()

        self.render_customizations()

        # !IMPORTANT! can't be too long: https://github.com/openshift/origin/issues/733
        self.template['metadata']['name'] = self.spec.name.value
        self.render_resource_limits()
        self.template['spec']['source']['git']['uri'] = self.spec.git_uri.value
        self.template['spec']['source']['git']['ref'] = self.spec.git_ref.value

        if self.spec.registry_uris.value:
            primary_registry_uri = self.spec.registry_uris.value[0].docker_uri
            tag_with_registry = '{0}/{1}'.format(primary_registry_uri,
                                                 self.spec.image_tag.value)
            self.template['spec']['output']['to']['name'] = tag_with_registry
        else:
            self.template['spec']['output']['to']['name'] = self.spec.image_tag.value

        self.render_tag_and_push_registries()

        if 'triggers' in self.template['spec']:
            imagechange = self.template['spec']['triggers'][0]['imageChange']
            imagechange['from']['name'] = self.spec.trigger_imagestreamtag.value

        self.render_add_yum_repo_by_url()

        use_auth = self.spec.use_auth.value
        self.render_check_and_set_rebuild(use_auth=use_auth)
        self.render_store_metadata_in_osv3(use_auth=use_auth)

        # Remove legacy sourceSecret in case an older template is used.
        if 'sourceSecret' in self.template['spec']['source']:
            del self.template['spec']['source']['sourceSecret']

        if self.spec.build_imagestream.value:
            self.template['spec']['strategy']['customStrategy']['from']['kind'] = 'ImageStreamTag'
            self.template['spec']['strategy']['customStrategy']['from']['name'] = \
                self.spec.build_imagestream.value
        else:
            self.template['spec']['strategy']['customStrategy']['from']['name'] = \
                self.spec.build_image.value

        repo_name = git_repo_humanish_part_from_uri(self.spec.git_uri.value)
        # NOTE: Since only the repo name is used, a forked repos will have
        # the same git-repo-name tag. This is a known limitation. If this
        # use case must be handled properly, the git URI must be taken into
        # account.
        self.set_label('git-repo-name', repo_name)
        if self.spec.git_branch.value:
            self.set_label('git-branch', self.spec.git_branch.value)
        else:
            self.set_label('git-branch', 'unknown')

        self.render_distgit_fetch_artefacts()
        self.render_pull_base_image()

        self.adjust_for_triggers()
        self.adjust_for_scratch()
        self.adjust_for_custom_base_image()

        # Enable/disable plugins as needed for target registry API versions
        self.adjust_for_registry_api_versions()

        self.set_secrets({('prebuild_plugins',
                           'reactor_config',
                           'config_path'):
                          self.spec.reactor_config_secret.value,

                          ('postbuild_plugins',
                           'pulp_push',
                           'pulp_secret_path'):
                          self.spec.pulp_secret.value,

                          ('postbuild_plugins',
                           'pulp_sync',
                           'pulp_secret_path'):
                          self.spec.pulp_secret.value,

                          # pulp_sync registry_secret_path set
                          # in render_pulp_sync

                          ('exit_plugins', 'koji_promote', 'koji_ssl_certs'):
                          self.spec.koji_certs_secret.value,

                          ('exit_plugins', 'koji_tag_build', 'koji_ssl_certs'):
                          self.spec.koji_certs_secret.value,

                          ('prebuild_plugins', 'add_filesystem', 'koji_ssl_certs_dir'):
                          self.spec.koji_certs_secret.value,

                          ('prebuild_plugins', 'bump_release', 'koji_ssl_certs_dir'):
                          self.spec.koji_certs_secret.value,

                          ('prebuild_plugins', 'koji', 'koji_ssl_certs_dir'):
                          self.spec.koji_certs_secret.value,

                          ('prebuild_plugins', 'fetch_maven_artifacts', 'koji_ssl_certs_dir'):
                          self.spec.koji_certs_secret.value,

                          ('exit_plugins', 'sendmail', 'koji_ssl_certs_dir'):
                          self.spec.koji_certs_secret.value,

                          ('postbuild_plugins', 'tag_and_push',
                           # Only set the secrets for the build, don't
                           # add the path to the plugin's
                           # configuration. This is done elsewhere.
                           None):
                          self.spec.registry_secrets.value,

                          ('buildstep_plugins', 'orchestrate_build', 'osbs_client_config'):
                          self.spec.client_config_secret.value})

        self.set_kerberos_auth([
            ('prebuild_plugins', 'fetch_maven_artifacts'),
            ('exit_plugins', 'koji_promote'),
            ('exit_plugins', 'koji_tag_build'),
            ('exit_plugins', 'sendmail')
        ])

        for (secret, path) in self.spec.token_secrets.value.items():
            self.set_secret_for_plugin(secret, mount_path=path)

        if self.spec.pulp_secret.value:
            # Don't push to docker registry, we're using pulp here
            # but still construct the unique tag
            self.template['spec']['output']['to']['name'] = \
                self.spec.image_tag.value

        koji_task_id = self.spec.koji_task_id.value
        if koji_task_id is not None:
            self.template['metadata'].setdefault('labels', {})
            self.template['metadata']['labels']['koji-task-id'] = str(koji_task_id)

        use_auth = self.spec.use_auth.value
        self.render_reactor_config()
        self.render_orchestrate_build()
        self.render_add_filesystem()
        self.render_add_labels_in_dockerfile()
        self.render_koji()
        self.render_bump_release()
        self.render_import_image(use_auth=use_auth)
        self.render_pulp_pull()
        self.render_pulp_push()
        self.render_pulp_sync()
        self.render_koji_promote(use_auth=use_auth)
        self.render_koji_tag_build()
        self.render_sendmail()
        self.render_fetch_maven_artifacts()
        self.render_version()

        self.dj.write_dock_json()
        self.build_json = self.template
        logger.debug(self.build_json)
        return self.build_json
Example #11
0
    def render(self, validate=True):
        if validate:
            self.spec.validate()
        super(ProductionBuild, self).render()

        repo_name = git_repo_humanish_part_from_uri(self.spec.git_uri.value)
        # NOTE: Since only the repo name is used, a forked repos will have
        # the same git-repo-name tag. This is a known limitation. If this
        # use case must be handled properly, the git URI must be taken into
        # account.
        self.set_label('git-repo-name', repo_name)
        self.set_label('git-branch', self.spec.git_branch.value)

        self.dj.dock_json_set_arg('prebuild_plugins', "distgit_fetch_artefacts",
                                  "command", self.spec.sources_command.value)

        # pull_base_image wants a docker URI so strip off the scheme part
        source_registry = self.spec.source_registry_uri.value
        self.dj.dock_json_set_arg('prebuild_plugins', "pull_base_image", "parent_registry",
                                  source_registry.docker_uri if source_registry else None)

        # The rebuild trigger requires git_branch and git_push_url
        # parameters, but those parameters are optional. If either was
        # not provided, remove the trigger.
        remove_triggers = False
        for param_name in ['git_branch', 'git_push_url']:
            param = getattr(self.spec, param_name)
            if not param.value:
                logger.info("removing triggers as no %s specified", param_name)
                remove_triggers = True
                # Continue the loop so we log everything that's missing

        if remove_triggers and 'triggers' in self.template['spec']:
            del self.template['spec']['triggers']

        self.adjust_for_triggers()
        self.adjust_for_scratch()

        # Enable/disable plugins as needed for target registry API versions
        self.adjust_for_registry_api_versions()

        self.set_secrets({('postbuild_plugins',
                           'pulp_push',
                           'pulp_secret_path'):
                          self.spec.pulp_secret.value,

                          ('postbuild_plugins',
                           'pulp_sync',
                           'pulp_secret_path'):
                          self.spec.pulp_secret.value,

                          ('exit_plugins', 'sendmail', 'pdc_secret_path'):
                          self.spec.pdc_secret.value,

                          ('exit_plugins', 'koji_promote', 'koji_ssl_certs'):
                          self.spec.koji_certs_secret.value})

        if self.spec.pulp_secret.value:
            # Don't push to docker registry, we're using pulp here
            # but still construct the unique tag
            self.template['spec']['output']['to']['name'] = \
                self.spec.image_tag.value

        kojitask = self.spec.koji_task_id.value
        if kojitask is not None:
            self.template['metadata'].setdefault('labels', {})
            self.template['metadata']['labels']['kojitask'] = kojitask

        use_auth = self.spec.use_auth.value
        self.render_add_labels_in_dockerfile()
        self.render_koji()
        self.render_bump_release()
        self.render_import_image(use_auth=use_auth)
        self.render_pulp_push()
        self.render_pulp_sync()
        self.render_koji_promote(use_auth=use_auth)
        self.render_sendmail()

        self.dj.write_dock_json()
        self.build_json = self.template
        logger.debug(self.build_json)
        return self.build_json
Example #12
0
    def test_create_binary_container_pipeline_run(self, koji_task_id,
                                                  isolated, scratch, release):
        rcm = 'rcm'
        rcm_scratch = 'rcm_scratch'
        with NamedTemporaryFile(mode="wt") as fp:
            fp.write("""
    [general]
    build_json_dir = {build_json_dir}
    [default_binary]
    openshift_url = /
    namespace = {namespace}
    use_auth = false
    pipeline_run_path = {pipeline_run_path}
    reactor_config_map = {rcm}
    reactor_config_map_scratch = {rcm_scratch}
    """.format(build_json_dir=INPUTS_PATH, namespace=TEST_OCP_NAMESPACE,
               pipeline_run_path=TEST_PIPELINE_RUN_TEMPLATE, rcm=rcm, rcm_scratch=rcm_scratch))
            fp.flush()
            dummy_config = Configuration(fp.name, conf_section='default_binary')
            osbs = OSBS(dummy_config)

        random_postfix = 'sha-timestamp'
        (flexmock(utils)
            .should_receive('generate_random_postfix')
            .and_return(random_postfix))

        name = utils.make_name_from_git(TEST_GIT_URI, TEST_GIT_BRANCH)
        pipeline_run_name = utils.make_name_from_git(TEST_GIT_URI, TEST_GIT_BRANCH)
        if isolated:
            pipeline_run_name = f'isolated-{random_postfix}'
        if scratch:
            pipeline_run_name = f'scratch-{random_postfix}'

        (flexmock(utils)
            .should_receive('get_repo_info')
            .with_args(TEST_GIT_URI, TEST_GIT_REF, git_branch=TEST_GIT_BRANCH, depth=None)
            .and_return(self.mock_repo_info()))

        rand = '67890'
        timestr = '20170731111111'
        (flexmock(sys.modules['osbs.build.user_params'])
            .should_receive('utcnow').once()
            .and_return(datetime.datetime.strptime(timestr, '%Y%m%d%H%M%S')))

        (flexmock(random)
            .should_receive('randrange')
            .with_args(10**(len(rand) - 1), 10**len(rand))
            .and_return(int(rand)))

        image_tag = f'{TEST_USER}/{TEST_COMPONENT}:{TEST_TARGET}-{rand}-{timestr}'

        self.mock_start_pipeline()
        signing_intent = 'signing_intent'
        pipeline_run = osbs.create_binary_container_pipeline_run(
            target=TEST_TARGET,
            signing_intent=signing_intent,
            koji_task_id=koji_task_id,
            isolated=isolated,
            scratch=scratch,
            release=release,
            **REQUIRED_BUILD_ARGS
        )
        assert isinstance(pipeline_run, PipelineRun)

        assert pipeline_run.input_data['metadata']['name'] == pipeline_run_name

        for ws in pipeline_run.input_data['spec']['workspaces']:
            if ws['name'] == PRUN_TEMPLATE_REACTOR_CONFIG_WS:
                if scratch:
                    assert ws['configmap']['name'] == rcm_scratch
                else:
                    assert ws['configmap']['name'] == rcm

            if ws['name'] in [PRUN_TEMPLATE_BUILD_DIR_WS, PRUN_TEMPLATE_CONTEXT_DIR_WS]:
                assert ws['volumeClaimTemplate']['metadata']['namespace'] == TEST_OCP_NAMESPACE

        for param in pipeline_run.input_data['spec']['params']:
            if param['name'] == PRUN_TEMPLATE_USER_PARAMS:
                assert param['value'] != {}

                up = json.loads(param['value'])

                expect_up = {}
                expect_up['build_json_dir'] = INPUTS_PATH
                if scratch:
                    expect_up['reactor_config_map'] = rcm_scratch
                    expect_up['scratch'] = True
                else:
                    expect_up['reactor_config_map'] = rcm
                expect_up['base_image'] = MockDfParser.baseimage
                expect_up['component'] = TEST_COMPONENT
                expect_up['git_branch'] = TEST_GIT_BRANCH
                expect_up['git_ref'] = TEST_GIT_REF
                expect_up['git_uri'] = TEST_GIT_URI
                expect_up['kind'] = BuildUserParams.KIND
                if koji_task_id:
                    expect_up['koji_task_id'] = koji_task_id
                expect_up['name'] = name
                expect_up['namespace'] = TEST_OCP_NAMESPACE
                expect_up['pipeline_run_name'] = pipeline_run_name
                expect_up['koji_target'] = TEST_TARGET
                expect_up['user'] = TEST_USER
                expect_up['signing_intent'] = signing_intent
                if isolated:
                    expect_up['isolated'] = True
                if release:
                    expect_up['release'] = release
                expect_up['image_tag'] = image_tag

                assert up == expect_up

        all_labels = {}

        if koji_task_id:
            all_labels['koji-task-id'] = str(koji_task_id)
        if scratch:
            all_labels['scratch'] = 'true'
        if isolated:
            all_labels['isolated'] = 'true'
            all_labels['isolated-release'] = release

        repo_name = utils.git_repo_humanish_part_from_uri(TEST_GIT_URI)
        all_labels['git-repo-name'] = repo_name
        all_labels['git-branch'] = TEST_GIT_BRANCH
        all_labels['git-full-repo'] = TEST_GIT_URI

        assert pipeline_run.input_data['metadata']['labels'] == all_labels
Example #13
0
    def render(self, validate=True):
        # the api is required for BuildRequestV2
        # can't check that its an OSBS object because of the circular import
        if not self.osbs_api:
            raise OsbsValidationException

        # Validate BuildUserParams
        if validate:
            self.user_params.validate()

        self.render_name(self.user_params.name.value,
                         self.user_params.image_tag.value,
                         self.user_params.platform.value)
        self.render_resource_limits()

        self.template['spec']['source']['git'][
            'uri'] = self.user_params.git_uri.value
        self.template['spec']['source']['git'][
            'ref'] = self.user_params.git_ref.value

        self.template['spec']['output']['to'][
            'name'] = self.user_params.image_tag.value

        if self.has_ist_trigger():
            imagechange = self.template['spec']['triggers'][0]['imageChange']
            imagechange['from'][
                'name'] = self.user_params.trigger_imagestreamtag.value

        custom_strategy = self.template['spec']['strategy']['customStrategy']
        if self.user_params.build_imagestream.value:
            custom_strategy['from']['kind'] = 'ImageStreamTag'
            custom_strategy['from'][
                'name'] = self.user_params.build_imagestream.value
        else:
            custom_strategy['from'][
                'name'] = self.user_params.build_image.value

        # Set git-repo-name label
        # NOTE: Since only the repo name is used, a forked repos will have
        # the same git-repo-name tag. This is a known limitation. If this
        # use case must be handled properly, the git URI must be taken into
        # account.
        repo_name = git_repo_humanish_part_from_uri(
            self.user_params.git_uri.value)
        self.set_label('git-repo-name', repo_name)
        self.set_label('git-branch', self.user_params.git_branch.value)
        koji_task_id = self.user_params.koji_task_id.value
        if koji_task_id is not None:
            self.set_label('koji-task-id', str(koji_task_id))

        # Set template.spec.strategy.customStrategy.env[] USER_PARAMS
        # Set required_secrets based on reactor_config
        # Set worker_token_secrets based on reactor_config, if any
        self.set_reactor_config()
        self.set_required_secrets()

        # Adjust triggers for custom base image
        if self.template['spec'].get('triggers',
                                     []) and self.is_custom_base_image():
            del self.template['spec']['triggers']

        self.adjust_for_repo_info()
        self.adjust_for_scratch()
        self.adjust_for_isolated(self.user_params.release)
        self.render_node_selectors(self.user_params.platforms.value)

        # Set our environment variables
        custom_strategy['env'].append({
            'name': 'USER_PARAMS',
            'value': self.user_params.to_json(),
        })
        # delete the ATOMIC_REACTOR_PLUGINS placeholder
        for (index, env) in enumerate(custom_strategy['env']):
            if env['name'] == 'ATOMIC_REACTOR_PLUGINS':
                del custom_strategy['env'][index]
                break
        # Log build json
        # Return build json
        self.build_json = self.template
        logger.debug(self.build_json)
        return self.build_json