Ejemplo n.º 1
0
def abandon_release(name):
    session = flask.g.db.session
    try:
        release = session.query(Release).filter(Release.name == name).one()
        # Cancel all submitted task groups first
        for phase in filter(lambda x: x.submitted, release.phases):
            actions = fetch_actions_json(phase.task_id)
            hook = generate_action_hook(
                decision_task_id=phase.task_id,
                action_name='cancel-all',
                actions=actions,
            )
            # some parameters contain a lot of entries, so we hit the payload
            # size limit. We don't use this parameter in any case, safe to
            # remove
            for long_param in ('existing_tasks', 'release_history', 'release_partner_config'):
                del hook['context']['parameters'][long_param]
            log.info('Cancel phase %s by hook %s', phase.name, hook)
            res = _hooks().triggerHook(hook['hook_group_id'], hook['hook_id'], hook['hook_payload'])
            log.debug('Done: %s', res)

        release.status = 'aborted'
        session.commit()
        return release.json
    except NoResultFound:
        flask.abort(404)
Ejemplo n.º 2
0
def abandon_release(name):
    session = current_app.db.session
    try:
        release = session.query(Release).filter(Release.name == name).one()

        # we must require scope which depends on product
        required_permission = f"{SCOPE_PREFIX}/abandon_release/{release.product}"
        if not current_user.has_permissions(required_permission):
            user_permissions = ", ".join(current_user.get_permissions())
            abort(
                401,
                f"required permission: {required_permission}, user permissions: {user_permissions}"
            )

        # Cancel all submitted task groups first
        for phase in filter(lambda x: x.submitted and not x.skipped,
                            release.phases):
            try:
                actions = fetch_artifact(phase.task_id, "public/actions.json")
                parameters = fetch_artifact(phase.task_id,
                                            "public/parameters.yml")
            except ArtifactNotFound:
                logger.info("Ignoring not completed action task %s",
                            phase.task_id)
                continue

            hook = generate_action_hook(task_group_id=phase.task_id,
                                        action_name="cancel-all",
                                        actions=actions,
                                        parameters=parameters,
                                        input_={})
            hooks = get_service("hooks")
            client_id = hooks.options["credentials"]["clientId"].decode(
                "utf-8")
            hook["context"]["clientId"] = client_id
            hook_payload_rendered = render_action_hook(
                payload=hook["hook_payload"],
                context=hook["context"],
                delete_params=[
                    "existing_tasks", "release_history",
                    "release_partner_config"
                ])
            logger.info("Cancel phase %s by hook %s with payload: %s",
                        phase.name, hook["hook_id"], hook_payload_rendered)
            res = hooks.triggerHook(hook["hook_group_id"], hook["hook_id"],
                                    hook_payload_rendered)
            logger.debug("Done: %s", res)

        release.status = "aborted"
        session.commit()
        release_json = release.json
    except NoResultFound:
        abort(404)

    notify_via_irc(
        release.product,
        f"Release {release.product} {release.version} build{release.build_number} was just canceled."
    )

    return release_json
Ejemplo n.º 3
0
def abandon_release(name):
    session = current_app.db.session
    try:
        release = session.query(Release).filter(Release.name == name).one()

        # we must require scope which depends on product
        required_permission = f'{SCOPE_PREFIX}/abandon_release/{release.product}'
        if not current_user.has_permissions(required_permission):
            user_permissions = ', '.join(current_user.get_permissions())
            abort(
                401,
                f'required permission: {required_permission}, user permissions: {user_permissions}'
            )

        # Cancel all submitted task groups first
        for phase in filter(lambda x: x.submitted, release.phases):
            try:
                actions = fetch_actions_json(phase.task_id)
            except ActionsJsonNotFound:
                logger.info('Ignoring not completed action task %s',
                            phase.task_id)
                continue

            hook = generate_action_hook(
                task_group_id=phase.task_id,
                action_name='cancel-all',
                actions=actions,
                input_={},
            )
            hooks = get_service('hooks')
            client_id = hooks.options['credentials']['clientId'].decode(
                'utf-8')
            hook['context']['clientId'] = client_id
            hook_payload_rendered = render_action_hook(
                payload=hook['hook_payload'],
                context=hook['context'],
                delete_params=[
                    'existing_tasks', 'release_history',
                    'release_partner_config'
                ],
            )
            logger.info('Cancel phase %s by hook %s with payload: %s',
                        phase.name, hook['hook_id'], hook_payload_rendered)
            res = hooks.triggerHook(hook['hook_group_id'], hook['hook_id'],
                                    hook_payload_rendered)
            logger.debug('Done: %s', res)

        release.status = 'aborted'
        session.commit()
        release_json = release.json
    except NoResultFound:
        abort(404)

    notify_via_irc(
        release.product,
        f'Release {release.product} {release.version} build{release.build_number} was just canceled.'
    )

    return release_json
Ejemplo n.º 4
0
    def generate_phases(self, partner_urls=None, github_token=None):
        phases = []
        previous_graph_ids = [self.decision_task_id]
        next_version = bump_version(self.version.replace('esr', ''))
        input_common = {
            'build_number': self.build_number,
            'next_version': next_version,
            # specify version rather than relying on in-tree version,
            # so if a version bump happens between the build and an action task
            # revision, we still use the correct version.
            'version': self.version,
            'release_eta': self.release_eta
        }
        if not is_partner_enabled(self.product, self.version):
            input_common['release_enable_partners'] = False
        if not is_eme_free_enabled(self.product, self.version):
            input_common['release_enable_emefree'] = False

        if self.partial_updates:
            input_common['partial_updates'] = {}
            for partial_version, info in self.partial_updates.items():
                input_common['partial_updates'][partial_version] = {
                    'buildNumber': info['buildNumber'],
                    'locales': info['locales']
                }
        target_action = find_action('release-promotion', self.actions)
        kind = target_action['kind']
        if kind != 'hook':
            raise ValueError(f'Unsupported kind: {kind}')

        for phase in self.release_promotion_flavors():
            input_ = copy.deepcopy(input_common)
            input_['release_promotion_flavor'] = phase['name']
            input_['previous_graph_ids'] = list(previous_graph_ids)

            hook = generate_action_hook(
                task_group_id=self.decision_task_id,
                action_name='release-promotion',
                actions=self.actions,
                parameters=self.parameters,
                input_=input_,
            )
            hook_no_context = {k: v for k, v in hook.items() if k != 'context'}
            phase_obj = Phase(
                name=phase['name'],
                task_id='',
                task=json.dumps(hook_no_context),
                context=json.dumps(hook['context']),
            )
            # we need to update input_['previous_graph_ids'] later, because
            # the task IDs cannot be set for hooks in advance
            if phase['in_previous_graph_ids']:
                previous_graph_ids.append(phase['name'])

            phase_obj.signoffs = self.phase_signoffs(self.branch, self.product,
                                                     phase['name'])
            phases.append(phase_obj)
        self.phases = phases
Ejemplo n.º 5
0
    def generate_phases(self, partner_urls=None, github_token=None):
        phases = []
        previous_graph_ids = [self.decision_task_id]
        next_version = bump_version(self.version.replace("esr", ""))
        input_common = {
            "build_number": self.build_number,
            "next_version": next_version,
            # specify version rather than relying on in-tree version,
            # so if a version bump happens between the build and an action task
            # revision, we still use the correct version.
            "version": self.version,
            "release_eta": self.release_eta,
        }
        if not is_partner_enabled(self.product, self.version):
            input_common["release_enable_partners"] = False
        if not is_eme_free_enabled(self.product, self.version):
            input_common["release_enable_emefree"] = False

        if self.partial_updates:
            input_common["partial_updates"] = {}
            for partial_version, info in self.partial_updates.items():
                input_common["partial_updates"][partial_version] = {
                    "buildNumber": info["buildNumber"],
                    "locales": info["locales"]
                }
        target_action = find_action("release-promotion", self.actions)
        kind = target_action["kind"]
        if kind != "hook":
            raise ValueError(f"Unsupported kind: {kind}")

        for phase in self.release_promotion_flavors():
            input_ = copy.deepcopy(input_common)
            input_["release_promotion_flavor"] = phase["name"]
            input_["previous_graph_ids"] = list(previous_graph_ids)

            hook = generate_action_hook(task_group_id=self.decision_task_id,
                                        action_name="release-promotion",
                                        actions=self.actions,
                                        parameters=self.parameters,
                                        input_=input_)
            hook_no_context = {k: v for k, v in hook.items() if k != "context"}
            phase_obj = Phase(name=phase["name"],
                              task_id="",
                              task=json.dumps(hook_no_context),
                              context=json.dumps(hook["context"]))
            # we need to update input_['previous_graph_ids'] later, because
            # the task IDs cannot be set for hooks in advance
            if phase["in_previous_graph_ids"]:
                previous_graph_ids.append(phase["name"])

            phase_obj.signoffs = self.phase_signoffs(self.branch, self.product,
                                                     phase["name"])
            phases.append(phase_obj)
        self.phases = phases
Ejemplo n.º 6
0
def abandon_release(name):
    session = g.db.session
    try:
        r = session.query(Release).filter(Release.name == name).one()
        # Cancel all submitted task groups first
        for phase in filter(lambda x: x.submitted, r.phases):
            try:
                actions = fetch_actions_json(phase.task_id)
            except ActionsJsonNotFound:
                logger.info('Ignoring not completed action task %s',
                            phase.task_id)
                continue

            hook = generate_action_hook(
                task_group_id=phase.task_id,
                action_name='cancel-all',
                actions=actions,
                input_={},
            )
            hooks = get_service('hooks')
            client_id = hooks.options['credentials']['clientId'].decode(
                'utf-8')
            hook['context']['clientId'] = client_id
            hook_payload_rendered = render_action_hook(
                payload=hook['hook_payload'],
                context=hook['context'],
                delete_params=[
                    'existing_tasks', 'release_history',
                    'release_partner_config'
                ],
            )
            logger.info('Cancel phase %s by hook %s with payload: %s',
                        phase.name, hook['hook_id'], hook_payload_rendered)
            res = hooks.triggerHook(hook['hook_group_id'], hook['hook_id'],
                                    hook_payload_rendered)
            logger.debug('Done: %s', res)

        r.status = 'aborted'
        session.commit()
        release = r.json
    except NoResultFound:
        abort(404)

    notify_via_irc(
        f'Release {r.product} {r.version} build{r.build_number} was just canceled.'
    )

    return release
Ejemplo n.º 7
0
def abandon_release(name):
    session = g.db.session
    try:
        r = session.query(Release).filter(Release.name == name).one()
        # Cancel all submitted task groups first
        for phase in filter(lambda x: x.submitted, r.phases):
            try:
                actions = fetch_actions_json(phase.task_id)
            except ActionsJsonNotFound:
                logger.info('Ignoring not completed action task %s',
                            phase.task_id)
                continue

            hook = generate_action_hook(
                decision_task_id=phase.task_id,
                action_name='cancel-all',
                actions=actions,
            )
            # some parameters contain a lot of entries, so we hit the payload
            # size limit. We don't use this parameter in any case, safe to
            # remove
            for long_param in ('existing_tasks', 'release_history',
                               'release_partner_config'):
                del hook['context']['parameters'][long_param]
            logger.info('Cancel phase %s by hook %s', phase.name, hook)
            hooks = get_service('hooks')
            res = hooks.triggerHook(hook['hook_group_id'], hook['hook_id'],
                                    hook['hook_payload'])
            logger.debug('Done: %s', res)

        r.status = 'aborted'
        session.commit()
        release = r.json
    except NoResultFound:
        abort(404)

    notify_via_irc(
        f'Release {r.product} {r.version} build{r.build_number} was just canceled.'
    )

    return release
Ejemplo n.º 8
0
    def generate_phases(self):
        phases = []
        previous_graph_ids = [self.decision_task_id]
        for phase in self.release_promotion_flavors():
            input_ = copy.deepcopy(self.common_input)
            input_["release_promotion_flavor"] = phase["name"]
            input_["previous_graph_ids"] = list(previous_graph_ids)

            hook = generate_action_hook(
                task_group_id=self.decision_task_id, action_name="release-promotion", actions=self.actions, parameters=self.parameters, input_=input_
            )
            hook_no_context = {k: v for k, v in hook.items() if k != "context"}
            phase_obj = self.phase_class(name=phase["name"], task_id="", task=json.dumps(hook_no_context), context=json.dumps(hook["context"]))
            # we need to update input_['previous_graph_ids'] later, because
            # the task IDs cannot be set for hooks in advance
            if phase["in_previous_graph_ids"]:
                previous_graph_ids.append(phase["name"])

            phase_obj.signoffs = self.phase_signoffs(phase["name"])
            phases.append(phase_obj)
        self.phases = phases
Ejemplo n.º 9
0
    def generate_phases(self, partner_urls=None, github_token=None):
        phases = []
        previous_graph_ids = [self.decision_task_id]
        next_version = bump_version(self.version.replace('esr', ''))
        input_common = {
            'build_number': self.build_number,
            'next_version': next_version,
            # specify version rather than relying on in-tree version,
            # so if a version bump happens between the build and an action task
            # revision, we still use the correct version.
            'version': self.version,
            'release_eta': self.release_eta
        }
        if not is_partner_enabled(self.product, self.version):
            input_common['release_enable_partners'] = False
        if not is_eme_free_enabled(self.product, self.version):
            input_common['release_enable_emefree'] = False

        if self.partial_updates:
            input_common['partial_updates'] = {}
            for partial_version, info in self.partial_updates.items():
                input_common['partial_updates'][partial_version] = {
                    'buildNumber': info['buildNumber'],
                    'locales': info['locales']
                }
        target_action = find_action('release-promotion', self.actions)
        kind = target_action['kind']
        for phase in self.release_promotion_flavors():
            input_ = copy.deepcopy(input_common)
            input_['release_promotion_flavor'] = phase['name']
            input_['previous_graph_ids'] = list(previous_graph_ids)
            if kind == 'task':
                action_task_id, action_task, context = generate_action_task(
                    decision_task_id=self.decision_task_id,
                    action_name='release-promotion',
                    input_=input_,
                    actions=self.actions,
                )
                if phase['in_previous_graph_ids']:
                    previous_graph_ids.append(action_task_id)
                phase_obj = Phase(
                    phase['name'], action_task_id, json.dumps(action_task), json.dumps(context))
            elif kind == 'hook':
                hook = generate_action_hook(
                    task_group_id=self.decision_task_id,
                    action_name='release-promotion',
                    actions=self.actions,
                    input_=input_,
                )
                hook_no_context = {k: v for k, v in hook.items() if k != 'context'}
                phase_obj = Phase(
                    name=phase['name'],
                    task_id='',
                    task=json.dumps(hook_no_context),
                    context=json.dumps(hook['context']),
                )
                # we need to update input_['previous_graph_ids'] later, because
                # the task IDs cannot be set for hooks in advance
                if phase['in_previous_graph_ids']:
                    previous_graph_ids.append(phase['name'])
            else:
                raise ValueError(f'Unsupported kind: {kind}')

            phase_obj.signoffs = self.phase_signoffs(self.branch, self.product, phase['name'])
            phases.append(phase_obj)
        self.phases = phases