def check_action_change_devel(self, request, action):
        advance, result = self.config_validate(action.tgt_project)
        if not advance:
            return result

        source_hash = package_source_hash(self.apiurl, action.tgt_project, action.tgt_package)
        origin_info_old = origin_find(self.apiurl, action.tgt_project, action.tgt_package, source_hash, True)

        with devel_project_simulate(self.apiurl, action.tgt_project, action.tgt_package,
                                    action.src_project, action.src_package):
            origin_info_new = origin_find(self.apiurl, action.tgt_project, action.tgt_package, source_hash)
            result = policy_evaluate(self.apiurl, action.tgt_project, action.tgt_package,
                                     origin_info_new, origin_info_old,
                                     source_hash, source_hash)

        reviews = {}

        # Remove all additional_reviews as there are no source changes.
        for key, comment in result.reviews.items():
            if key in ('fallback', 'maintainer'):
                reviews[key] = comment

        if result.accept:
            config = config_load(self.apiurl, action.tgt_project)
            if request.creator == config['review-user']:
                # Remove all reviews since the request was generated via
                # origin_update() which indicates it was approved already. Acts
                # as workaround for to lack of set devel on a submit request.
                reviews = {}

        if len(reviews) != len(result.reviews):
            result = PolicyResult(result.wait, result.accept, reviews, result.comments)

        return self.policy_result_handle(action.tgt_project, action.tgt_package, origin_info_new, origin_info_old, result)
Ejemplo n.º 2
0
    def check_source_submission(self, src_project, src_package, src_rev, tgt_project, tgt_package):
        if not self.config_validate(tgt_project):
            return False

        source_hash_new = package_source_hash(self.apiurl, src_project, src_package, src_rev)
        origin_info_new = origin_find(self.apiurl, tgt_project, tgt_package, source_hash_new)

        source_hash_old = package_source_hash(self.apiurl, tgt_project, tgt_package)
        origin_info_old = origin_find(self.apiurl, tgt_project, tgt_package, source_hash_old, True)

        result = policy_evaluate(self.apiurl, tgt_project, tgt_package,
                                 origin_info_new, origin_info_old,
                                 source_hash_new, source_hash_old)
        return self.policy_result_handle(tgt_project, tgt_package, origin_info_new, origin_info_old, result)
Ejemplo n.º 3
0
    def check_action_delete_package(self, request, action):
        origin_info_old = origin_find(self.apiurl, action.tgt_project, action.tgt_package)

        reviews = {'fallback': 'Delete requests require fallback review.'}
        self.policy_result_reviews_add(action.tgt_project, action.tgt_package,
                                       reviews, origin_info_old, origin_info_old)

        return True
    def check_action_delete_package(self, request, action):
        origin_info_old = origin_find(self.apiurl, action.tgt_project,
                                      action.tgt_package)

        reviews = {'fallback': 'Delete requests require fallback review.'}
        self.policy_result_reviews_add(action.tgt_project, action.tgt_package,
                                       reviews, origin_info_old,
                                       origin_info_old)

        return True
    def check_action_delete_package(self, request, action):
        advance, result = self.config_validate(action.tgt_project)
        if not advance:
            return result

        origin_info_old = origin_find(self.apiurl, action.tgt_project, action.tgt_package)

        reviews = {'fallback': 'Delete requests require fallback review.'}
        self.policy_result_reviews_add(action.tgt_project, action.tgt_package,
                                       reviews, origin_info_old, origin_info_old)

        return True
    def check_source_submission(self, src_project, src_package, src_rev,
                                tgt_project, tgt_package):
        if not self.config_validate(tgt_project):
            return False

        source_hash_new = package_source_hash(self.apiurl, src_project,
                                              src_package, src_rev)
        origin_info_new = origin_find(self.apiurl, tgt_project, tgt_package,
                                      source_hash_new)

        source_hash_old = package_source_hash(self.apiurl, tgt_project,
                                              tgt_package)
        origin_info_old = origin_find(self.apiurl, tgt_project, tgt_package,
                                      source_hash_old, True)

        result = policy_evaluate(self.apiurl, tgt_project, tgt_package,
                                 origin_info_new, origin_info_old,
                                 source_hash_new, source_hash_old)
        return self.policy_result_handle(tgt_project, tgt_package,
                                         origin_info_new, origin_info_old,
                                         result)
    def check_source_submission(self, src_project, src_package, src_rev, tgt_project, tgt_package):
        kind = package_kind(self.apiurl, tgt_project, tgt_package)
        if not (kind is None or kind == 'source'):
            self.review_messages['accepted'] = 'skipping {} package since not source'.format(kind)
            return True

        advance, result = self.config_validate(tgt_project)
        if not advance:
            return result

        if self.request_age_wait():
            # Allow for parallel submission to be created.
            return None

        source_hash_new = package_source_hash(self.apiurl, src_project, src_package, src_rev)
        origin_info_new = origin_find(self.apiurl, tgt_project, tgt_package, source_hash_new)

        source_hash_old = package_source_hash(self.apiurl, tgt_project, tgt_package)
        origin_info_old = origin_find(self.apiurl, tgt_project, tgt_package, source_hash_old, True)

        # Check if simulating the devel project is appropriate.
        devel_project, reason = self.devel_project_simulate_check(src_project, tgt_project)
        if devel_project and (reason.startswith('change_devel command') or origin_info_new is None):
            self.logger.debug(f'reevaluate considering {devel_project} as devel since {reason}')

            try:
                with devel_project_simulate(self.apiurl, tgt_project, tgt_package, src_project, src_package):
                    # Recurse with simulated devel project.
                    ret = self.check_source_submission(
                        src_project, src_package, src_rev, tgt_project, tgt_package)
                    self.review_messages['accepted']['comment'] = reason
                    return ret
            except devel_project_simulate_exception:
                # Invalid infinite recursion so fallback to normal behavior.
                pass

        result = policy_evaluate(self.apiurl, tgt_project, tgt_package,
                                 origin_info_new, origin_info_old,
                                 source_hash_new, source_hash_old)
        return self.policy_result_handle(tgt_project, tgt_package, origin_info_new, origin_info_old, result)
Ejemplo n.º 8
0
def osrt_origin_lookup(apiurl,
                       project,
                       force_refresh=False,
                       previous=False,
                       quiet=False):
    locked = project_locked(apiurl, project)
    if locked:
        force_refresh = False

    lookup_path = osrt_origin_lookup_file(project, previous)
    if not force_refresh and os.path.exists(lookup_path):
        if not locked and not previous:
            # Force refresh of lookup information if expried.
            if time.time() - os.stat(
                    lookup_path).st_mtime > OSRT_ORIGIN_LOOKUP_TTL:
                return osrt_origin_lookup(apiurl, project, True)

        with open(lookup_path, 'r') as lookup_stream:
            lookup = yaml.safe_load(lookup_stream)

            if not isinstance(next(iter(lookup.values())), dict):
                # Convert flat format to dictionary.
                for package, origin in lookup.items():
                    lookup[package] = {'origin': origin}
    else:
        if previous:
            return None

        packages = package_list_kind_filtered(apiurl, project)

        lookup = {}
        for package in packages:
            origin_info = origin_find(apiurl, project, package)
            lookup[str(package)] = {
                'origin':
                str(origin_info),
                'revisions':
                origin_revision_state(apiurl, project, package, origin_info),
            }

        if os.path.exists(lookup_path):
            lookup_path_previous = osrt_origin_lookup_file(project, True)
            copyfile(lookup_path, lookup_path_previous)

        with open(lookup_path, 'w+') as lookup_stream:
            yaml.dump(lookup, lookup_stream, default_flow_style=False)

    if not previous and not quiet:
        dt = timedelta(seconds=time.time() - os.stat(lookup_path).st_mtime)
        print('# generated {} ago'.format(dt), file=sys.stderr)

    return lookup
Ejemplo n.º 9
0
def osrt_origin_lookup(apiurl, project, force_refresh=False, previous=False, quiet=False):
    locked = project_locked(apiurl, project)
    if locked:
        force_refresh = False

    lookup_path = osrt_origin_lookup_file(project, previous)
    if not force_refresh and os.path.exists(lookup_path):
        if not locked and not previous:
            # Force refresh of lookup information if expried.
            if time.time() - os.stat(lookup_path).st_mtime > OSRT_ORIGIN_LOOKUP_TTL:
                return osrt_origin_lookup(apiurl, project, True)

        with open(lookup_path, 'r') as lookup_stream:
            lookup = yaml.safe_load(lookup_stream)

            if not isinstance(next(iter(lookup.values())), dict):
                # Convert flat format to dictionary.
                for package, origin in lookup.items():
                    lookup[package] = {'origin': origin}
    else:
        if previous:
            return None

        packages = package_list_kind_filtered(apiurl, project)

        lookup = {}
        for package in packages:
            origin_info = origin_find(apiurl, project, package)
            lookup[str(package)] = {
                'origin': str(origin_info),
                'revisions': origin_revision_state(apiurl, project, package, origin_info),
            }

        if os.path.exists(lookup_path):
            lookup_path_previous = osrt_origin_lookup_file(project, True)
            copyfile(lookup_path, lookup_path_previous)

        with open(lookup_path, 'w+') as lookup_stream:
            yaml.dump(lookup, lookup_stream, default_flow_style=False)

    if not previous and not quiet:
        dt = timedelta(seconds=time.time() - os.stat(lookup_path).st_mtime)
        print('# generated {} ago'.format(dt), file=sys.stderr)

    return lookup
Ejemplo n.º 10
0
def osrt_origin_package(apiurl, opts, *packages):
    origin_info = origin_find(apiurl, opts.project, packages[0])
    print(origin_info)
Ejemplo n.º 11
0
    def test_split_product(self):
        self.remote_config_set_age_minimum()

        upstream1_project = self.randomString('upstream1')
        upstream2_project = self.randomString('upstream2')
        devel_project = self.randomString('devel')
        package = self.randomString('package')

        target_package = self.wf.create_package(self.target_project, package)
        upstream1_package = self.wf.create_package(upstream1_project, package)
        upstream2_package = self.wf.create_package(upstream2_project, package)
        devel_package = self.wf.create_package(devel_project, package)

        upstream1_package.create_commit()
        upstream2_package.create_commit()
        devel_package.create_commit()

        attribute_value_save(self.wf.apiurl, upstream1_project, 'ApprovedRequestSource', '', 'OBS')
        attribute_value_save(self.wf.apiurl, upstream2_project, 'ApprovedRequestSource', '', 'OBS')
        attribute_value_save(self.wf.apiurl, devel_project, 'ApprovedRequestSource', '', 'OBS')

        self.origin_config_write([
            {'<devel>': {}},
            {upstream1_project: {}},
            {upstream2_project: { 'pending_submission_consider': True }},
            {'*~': {}},
        ], {'unknown_origin_wait': True})

        # Simulate branch project from upstream1.
        copy_package(self.wf.apiurl, upstream1_project, package,
                     self.wf.apiurl, self.target_project, package)

        memoize_session_reset()
        origin_info = origin_find(self.wf.apiurl, self.target_project, package)
        self.assertEqual(str(origin_info), upstream1_project)

        # Create request against upstream2 which considers pending submissions.
        request_upstream2 = self.wf.submit_package(devel_package, upstream2_project)
        request_target = self.wf.submit_package(devel_package, self.target_project)

        self.assertReviewBot(request_target.reqid, self.bot_user, 'new', 'new')
        comment = [
            '<!-- OriginManager state=seen result=None -->',
            f'Waiting on acceptance of request#{request_upstream2.reqid}.',
        ]
        self.assertComment(request_target.reqid, comment)

        request_upstream2.change_state('accepted')

        self.assertReviewBot(request_target.reqid, self.bot_user, 'new', 'accepted')
        self.assertAnnotation(request_target.reqid, {
            'origin': upstream2_project,
            'origin_old': upstream1_project,
        })

        # Accept fallback review for changing to lower priority origin.
        self.accept_fallback_review(request_target.reqid)
        request_target.change_state('accepted')

        memoize_session_reset()
        origin_info = origin_find(self.wf.apiurl, self.target_project, package)
        self.assertEqual(str(origin_info), upstream2_project)

        # Simulate upstream1 incorporating upstream2 version of package.
        copy_package(self.wf.apiurl, upstream2_project, package,
                     self.wf.apiurl, upstream1_project, package)

        memoize_session_reset()
        origin_info = origin_find(self.wf.apiurl, self.target_project, package)
        self.assertEqual(str(origin_info), upstream1_project)
Ejemplo n.º 12
0
    def devel_workflow(self, only_devel):
        self.remote_config_set_age_minimum()

        devel_project = self.randomString('devel')
        package = self.randomString('package')
        request = self.wf.create_submit_request(devel_project, package)
        attribute_value_save(self.wf.apiurl, devel_project, 'ApprovedRequestSource', '', 'OBS')

        if not only_devel:
            self.assertReviewBot(request.reqid, self.bot_user, 'new', 'new')

            comment = [
                '<!-- OriginManager state=seen result=None -->',
                'Source not found in allowed origins:',
                f'- {self.product_project}',
                f'Decision may be overridden via `@{self.bot_user} override`.',
            ]
            self.assertComment(request.reqid, comment)

            CommentAPI(self.wf.api.apiurl).add_comment(
                request_id=request.reqid, comment=f'@{self.bot_user} change_devel')

            comment = 'change_devel command by {}'.format('Admin')
        else:
            comment = 'only devel origin allowed'

        self.assertReviewBot(request.reqid, self.bot_user, 'new', 'accepted')
        self.assertAnnotation(request.reqid, {
            'comment': comment,
            'origin': devel_project,
        })

        request.change_state('accepted')

        memoize_session_reset()
        self.osc_user(self.bot_user)
        request_future = origin_update(self.wf.apiurl, self.wf.project, package)
        self.assertNotEqual(request_future, False)
        if request_future:
            request_id_change_devel = request_future.print_and_create()

        # Ensure a second request is not triggered.
        request_future = origin_update(self.wf.apiurl, self.wf.project, package)
        self.assertEqual(request_future, False)
        self.osc_user_pop()

        memoize_session_reset()
        origin_info = origin_find(self.wf.apiurl, self.wf.project, package)
        self.assertEqual(origin_info, None)

        self.assertReviewBot(request_id_change_devel, self.bot_user, 'new', 'accepted')
        self.assertAnnotation(request_id_change_devel, {
            'origin': devel_project,
        })

        # Origin should change before request is accepted since it is properly
        # annotated and without fallback review.
        memoize_session_reset()
        origin_info = origin_find(self.wf.apiurl, self.wf.project, package)
        self.assertEqual(str(origin_info), devel_project)

        self.wf.projects[devel_project].packages[0].create_commit()

        self.osc_user(self.bot_user)
        request_future = origin_update(self.wf.apiurl, self.wf.project, package)
        self.assertNotEqual(request_future, False)
        if request_future:
            request_id_update = request_future.print_and_create()

        request_future = origin_update(self.wf.apiurl, self.wf.project, package)
        self.assertEqual(request_future, False)
        self.osc_user_pop()

        self.assertReviewBot(request_id_update, self.bot_user, 'new', 'accepted')
        self.assertAnnotation(request_id_update, {
            'origin': devel_project,
        })

        memoize_session_reset()
        devel_project_actual, _ = devel_project_get(self.wf.apiurl, self.wf.project, package)
        self.assertEqual(devel_project_actual, None)

        request = get_request(self.wf.apiurl, request_id_change_devel)
        request_state_change(self.wf.apiurl, request_id_change_devel, 'accepted')

        memoize_session_reset()
        devel_project_actual, devel_package_actual = devel_project_get(
            self.wf.apiurl, self.wf.project, package)
        self.assertEqual(devel_project_actual, devel_project)
        self.assertEqual(devel_package_actual, package)

        request = get_request(self.wf.apiurl, request_id_update)
        request_state_change(self.wf.apiurl, request_id_update, 'accepted')

        devel_project_new = self.randomString('develnew')
        self.wf.create_package(devel_project_new, package)
        attribute_value_save(self.wf.apiurl, devel_project_new, 'ApprovedRequestSource', '', 'OBS')

        copy_package(self.wf.apiurl, devel_project, package,
                     self.wf.apiurl, devel_project_new, package)

        request_future = request_create_change_devel(
            self.wf.apiurl, devel_project_new, package, self.wf.project)
        self.assertNotEqual(request_future, False)
        if request_future:
            request_id_change_devel_new = request_future.print_and_create()

        self.assertReviewBot(request_id_change_devel_new, self.bot_user, 'new', 'accepted')
        self.assertAnnotation(request_id_change_devel_new, {
            'origin': devel_project_new,
            'origin_old': devel_project,
        })

        self.accept_fallback_review(request_id_change_devel_new)
        request_state_change(self.wf.apiurl, request_id_change_devel_new, 'accepted')

        memoize_session_reset()
        origin_info = origin_find(self.wf.apiurl, self.wf.project, package)
        self.assertEqual(str(origin_info), devel_project_new)