示例#1
0
class SourceScanTraitTransformer(TraitTransformer):
    name = 'scan_sources'

    def __init__(self, trait, *args, **kwargs):
        self.trait = trait
        super().__init__(*args, **kwargs)

    def inject_steps(self):
        self.source_scan_step = PipelineStep(
            name='scan_sources',
            raw_dict={},
            is_synthetic=True,
            notification_policy=StepNotificationPolicy.NO_NOTIFICATION,
            script_type=ScriptType.PYTHON3)
        self.source_scan_step.add_input(
            name=concourse.model.traits.component_descriptor.DIR_NAME,
            variable_name=concourse.model.traits.component_descriptor.
            ENV_VAR_NAME,
        )
        self.source_scan_step.set_timeout(duration_string='18h')
        yield self.source_scan_step

    def process_pipeline_args(self, pipeline_args: JobVariant):
        # our step depends on dependency descriptor step
        component_descriptor_step = pipeline_args.step('component_descriptor')
        self.source_scan_step._add_dependency(component_descriptor_step)

    @classmethod
    def dependencies(cls):
        return {'component_descriptor'}
示例#2
0
class ImageScanTraitTransformer(TraitTransformer):
    name = 'image_scan'

    def __init__(self, trait, *args, **kwargs):
        self.trait = trait
        super().__init__(*args, **kwargs)

    def inject_steps(self):
        self.image_scan_step = PipelineStep(
            name='scan_container_images',
            raw_dict={},
            is_synthetic=True,
            notification_policy=StepNotificationPolicy.NO_NOTIFICATION,
            script_type=ScriptType.PYTHON3)
        self.image_scan_step.add_input(*COMPONENT_DESCRIPTOR_DIR_INPUT)
        self.image_scan_step.set_timeout(duration_string='12h')
        yield self.image_scan_step

    def process_pipeline_args(self, pipeline_args: 'JobVariant'):
        # our step depends on dependency descriptor step
        component_descriptor_step = pipeline_args.step('component_descriptor')
        self.image_scan_step._add_dependency(component_descriptor_step)

    @classmethod
    def dependencies(cls):
        return {'component_descriptor'}
示例#3
0
class ImageScanTraitTransformer(TraitTransformer):
    name = 'image_scan'

    def __init__(self, trait, *args, **kwargs):
        self.trait = trait
        super().__init__(*args, **kwargs)

    def inject_steps(self):
        self.image_scan_step = PipelineStep(
            name='scan_container_images',
            raw_dict={},
            is_synthetic=True,
            notification_policy=StepNotificationPolicy.NO_NOTIFICATION,
            script_type=ScriptType.PYTHON3)
        self.image_scan_step.add_input(
            name=concourse.model.traits.component_descriptor.DIR_NAME,
            variable_name=concourse.model.traits.component_descriptor.
            ENV_VAR_NAME,
        )
        self.image_scan_step.set_timeout(duration_string='12h')
        yield self.image_scan_step

    def process_pipeline_args(self, pipeline_args: JobVariant):
        # our step depends on dependency descriptor step
        component_descriptor_step = pipeline_args.step('component_descriptor')
        self.image_scan_step._add_dependency(component_descriptor_step)

        for trait_name in self.trait.trait_depends():
            if not pipeline_args.has_trait(trait_name):
                raise ModelValidationError(
                    f'dependency towards absent trait: {trait_name}')

            depended_on_trait = pipeline_args.trait(trait_name)
            # XXX refactor Trait/TraitTransformer
            transformer = depended_on_trait.transformer()
            # XXX step-injection may have (unintended) side-effects :-/
            depended_on_step_names = {
                step.name
                for step in transformer.inject_steps()
            }

            for step in pipeline_args.steps():
                if not step.name in depended_on_step_names:
                    continue
                self.image_scan_step._add_dependency(step)
                # prevent cyclic dependencies (from auto-injected depends)
                if self.image_scan_step.name in step.depends():
                    step._remove_dependency(self.image_scan_step)

    @classmethod
    def dependencies(cls):
        return {'component_descriptor'}

    @classmethod
    def order_dependencies(cls):
        # required in case image-scanning should be done after publish
        # (-> auto-injected dependency for "prepare"-step towards _all_ steps)
        return {'publish'}
示例#4
0
class UpdateComponentDependenciesTraitTransformer(TraitTransformer):
    name = 'update_component_deps'

    def __init__(self, trait, *args, **kwargs):
        self.trait = trait
        super().__init__(*args, **kwargs)

    @classmethod
    def order_dependencies(cls):
        return {'component_descriptor'}

    @classmethod
    def dependencies(cls):
        return {'component_descriptor'}

    def inject_steps(self):
        if self.trait.set_dependency_version_script_container_image():
            privilege_mode = PrivilegeMode.PRIVILEGED
        else:
            privilege_mode = PrivilegeMode.UNPRIVILEGED

        # declare no dependencies --> run asap, but do not block other steps
        self.update_component_deps_step = PipelineStep(
            name='update_component_dependencies',
            raw_dict={
                'privilege_mode': privilege_mode,
            },
            is_synthetic=True,
            pull_request_notification_policy=PullRequestNotificationPolicy.
            NO_NOTIFICATION,
            injecting_trait_name=self.name,
            script_type=ScriptType.PYTHON3)
        self.update_component_deps_step.add_input(
            name=concourse.model.traits.component_descriptor.DIR_NAME,
            variable_name=concourse.model.traits.component_descriptor.
            ENV_VAR_NAME,
        )
        self.update_component_deps_step.set_timeout(duration_string='30m')

        for name, value in self.trait.vars().items():
            self.update_component_deps_step.variables()[name] = value

        yield self.update_component_deps_step

    def process_pipeline_args(self, pipeline_args: JobVariant):
        # our step depends on dependendency descriptor step
        component_descriptor_step = pipeline_args.step(
            concourse.model.traits.component_descriptor.
            DEFAULT_COMPONENT_DESCRIPTOR_STEP_NAME)
        self.update_component_deps_step._add_dependency(
            component_descriptor_step)

        upstream_component_name = self.trait.upstream_component_name()
        if upstream_component_name:
            self.update_component_deps_step.variables(
            )['UPSTREAM_COMPONENT_NAME'] = '"{cn}"'.format(
                cn=upstream_component_name, )
示例#5
0
class UpdateComponentDependenciesTraitTransformer(TraitTransformer):
    name = 'update_component_deps'

    def __init__(self, trait, *args, **kwargs):
        self.trait = trait
        super().__init__(*args, **kwargs)

    @classmethod
    def order_dependencies(cls):
        return {'component_descriptor'}

    @classmethod
    def dependencies(cls):
        return {'component_descriptor'}

    def inject_steps(self):
        # declare no dependencies --> run asap, but do not block other steps
        self.update_component_deps_step = PipelineStep(
                name='update_component_dependencies',
                raw_dict={},
                is_synthetic=True,
                notification_policy=StepNotificationPolicy.NO_NOTIFICATION,
                script_type=ScriptType.PYTHON3
        )
        self.update_component_deps_step.add_input(
            name=concourse.model.traits.component_descriptor.DIR_NAME,
            variable_name=concourse.model.traits.component_descriptor.ENV_VAR_NAME,
        )
        self.update_component_deps_step.set_timeout(duration_string='30m')

        for name, value in self.trait.vars().items():
            self.update_component_deps_step.variables()[name] = value

        yield self.update_component_deps_step

    def process_pipeline_args(self, pipeline_args: JobVariant):
        # our step depends on dependendency descriptor step
        component_descriptor_step = pipeline_args.step('component_descriptor')
        self.update_component_deps_step._add_dependency(component_descriptor_step)

        upstream_component_name = self.trait.upstream_component_name()
        if upstream_component_name:
            self.update_component_deps_step.variables()['UPSTREAM_COMPONENT_NAME'] = '"{cn}"'.format(
                cn=upstream_component_name,
            )
示例#6
0
class ComponentDescriptorTraitTransformer(TraitTransformer):
    name = 'component_descriptor'

    def __init__(self, trait: ComponentDescriptorTrait, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.trait = not_none(trait)

    def inject_steps(self):
        self.descriptor_step = PipelineStep(
            name=self.trait.step_name(),
            raw_dict={},
            is_synthetic=True,
            notification_policy=StepNotificationPolicy.NO_NOTIFICATION,
            injected_by_trait=self.name,
            script_type=ScriptType.PYTHON3,
        )
        self.descriptor_step.add_output(
            name=DIR_NAME,
            variable_name=ENV_VAR_NAME,
        )
        self.descriptor_step.set_timeout(duration_string='45m')

        yield self.descriptor_step

    def process_pipeline_args(self, pipeline_args: 'JobVariant'):
        if pipeline_args.has_step('release'):
            release_step = pipeline_args.step('release')
            release_step.add_input(
                name=DIR_NAME,
                variable_name=ENV_VAR_NAME,
            )
        if pipeline_args.has_trait('draft_release'):
            draft_release_step = pipeline_args.step(
                'create_draft_release_notes')
            draft_release_step.add_input(
                name=DIR_NAME,
                variable_name=ENV_VAR_NAME,
            )

        # inject component_name if not configured
        if not self.trait.raw.get('component_name'):
            main_repo = pipeline_args.main_repository()
            component_name = '/'.join((
                main_repo.repo_hostname(),
                main_repo.repo_path(),
            ))
            self.trait.raw['component_name'] = component_name

        # add configured (step-)inputs
        for step_input in self.trait.inputs():
            if not step_input.type == 'step':
                raise NotImplementedError(step_input.type)

            try:
                step: PipelineStep = pipeline_args.step(step_input.step_name)
            except KeyError as ke:
                raise ValueError(
                    f'no such step: {step_input.step_name=}') from ke

            self.descriptor_step._add_dependency(step)

            if step_input.output_name:
                output_name = step_input.output_name
            else:
                # choose only output if omitted
                outputs = {
                    name: v
                    for name, v in step.outputs().items()
                    if not name == 'on_error_dir'  # XXX hack hack hack
                }
                if len(outputs) < 1:
                    raise ValueError(f'{step.name=} does not have any outputs')
                elif len(outputs) > 1:
                    raise ValueError(
                        f'{step.name=} has more than one output (need to tell step_name)'
                    )
                output_name = next(outputs.keys().__iter__())

            self.descriptor_step.add_input(
                name=output_name,
                variable_name=output_name,
            )

    @classmethod
    def dependencies(cls):
        return {'version'}

    @classmethod
    def order_dependencies(cls):
        # dependency is required, as we need to patch the 'release' step
        return {'release'}