def test_config(self): attribute_value_save(self.wf.apiurl, self.target_project, 'OriginConfig', 'origins: []') config = config_load(self.wf.apiurl, self.wf.project) self.assertEqual(config['unknown_origin_wait'], False) self.assertEqual(config['review-user'], NAME) memoize_session_reset() self.origin_config_write([{'fakeProject': {}}, {'*~': {}}]) config = config_load(self.wf.apiurl, self.wf.project) self.assertEqual(config_origin_list(config), ['fakeProject', 'fakeProject~']) for _, values in config_origin_generator(config['origins']): self.assertEqual(values['automatic_updates'], True)
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)
def osrt_origin_config(apiurl, opts, *args): config = config_load(apiurl, opts.project) if opts.origins_only: print('\n'.join(config_origin_list(config))) else: yaml.Dumper.ignore_aliases = lambda *args : True print(yaml.dump(config))
def do_origin(self, subcmd, opts, *args): """${cmd_name}: tools for working with origin information ${cmd_option_list} config: print expanded OSRT:OriginConfig cron: update the lookup for all projects with an OSRT:OriginConfig attribute history: list requests containing an origin annotation list: print all packages and their origin package: print the origin of package potentials: list potential origins of a package projects: list all projects with an OSRT:OriginConfig attribute report: print origin summary report update: handle package source changes as either delete or submit requests Usage: osc origin config [--origins-only] osc origin cron osc origin history [--format json|yaml] PACKAGE osc origin list [--force-refresh] [--format json|yaml] osc origin package [--debug] PACKAGE osc origin potentials [--format json|yaml] PACKAGE osc origin projects [--format json|yaml] osc origin report [--diff] [--force-refresh] [--mail] osc origin update [--listen] [--listen-seconds] [PACKAGE...] """ if len(args) == 0: raise oscerr.WrongArgs('A command must be indicated.') command = args[0] if command not in [ 'config', 'cron', 'history', 'list', 'package', 'potentials', 'projects', 'report', 'update' ]: raise oscerr.WrongArgs('Unknown command: {}'.format(command)) if command == 'package' and len(args) < 2: raise oscerr.WrongArgs('A package must be indicated.') level = logging.DEBUG if opts.debug else None logging.basicConfig(level=level, format='[%(levelname).1s] %(message)s') # Allow for determining project from osc store. if not opts.project and core.is_project_dir('.'): opts.project = core.store_read_project('.') Cache.init() apiurl = self.get_api_url() if command not in ['cron', 'projects', 'update']: if not opts.project: raise oscerr.WrongArgs('A project must be indicated.') config = config_load(apiurl, opts.project) if not config: raise oscerr.WrongArgs( 'OSRT:OriginConfig attribute missing from {}'.format( opts.project)) function = 'osrt_origin_{}'.format(command) globals()[function](apiurl, opts, *args[1:])
def policy_result_reviews_add(self, project, package, reviews, origin_info_new, origin_info_old): for key, comment in reviews.items(): if key == 'maintainer': self.devel_project_review_ensure(self.request, project, package, comment) elif key == 'fallback': fallback_group = config_load(self.apiurl, project).get('fallback-group') comment += '\n\n' + origin_annotation_dump(origin_info_new, origin_info_old) self.add_review(self.request, by_group=fallback_group, msg=comment) else: self.add_review(self.request, by_group=key, msg=comment)
def policy_result_reviews_add(self, project, package, reviews, origin_info_new, origin_info_old): for key, comment in reviews.items(): if key == 'maintainer': self.origin_maintainer_review_ensure(origin_info_new, package, message=comment) elif key == 'fallback': fallback_group = config_load(self.apiurl, project).get('fallback-group') comment += '\n\n' + origin_annotation_dump(origin_info_new, origin_info_old) self.add_review(self.request, by_group=fallback_group, msg=comment) else: self.add_review(self.request, by_group=key, msg=comment)
def osrt_origin_history(apiurl, opts, *packages): config = config_load(apiurl, opts.project) history = origin_history(apiurl, opts.project, packages[0], config['review-user']) if osrt_origin_dump(opts.format, history): return line_format = '{:<50} {:<10} {:>7}' print(line_format.format('origin', 'state', 'request')) for record in history: print(line_format.format(record['origin'], record['state'], record['request']))
def do_origin(self, subcmd, opts, *args): """${cmd_name}: tools for working with origin information ${cmd_option_list} config: print expanded OSRT:OriginConfig cron: update the lookup for all projects with an OSRT:OriginConfig attribute history: list requests containing an origin annotation list: print all packages and their origin package: print the origin of package potentials: list potential origins of a package projects: list all projects with an OSRT:OriginConfig attribute report: print origin summary report Usage: osc origin config [--origins-only] osc origin cron osc origin history [--format json|yaml] PACKAGE osc origin list [--force-refresh] [--format json|yaml] osc origin package [--debug] PACKAGE osc origin potentials [--format json|yaml] PACKAGE osc origin projects [--format json|yaml] osc origin report [--diff] [--force-refresh] [--mail] """ if len(args) == 0: raise oscerr.WrongArgs('A command must be indicated.') command = args[0] if command not in ['config', 'cron', 'history', 'list', 'package', 'potentials', 'projects', 'report']: raise oscerr.WrongArgs('Unknown command: {}'.format(command)) if command == 'package' and len(args) < 2: raise oscerr.WrongArgs('A package must be indicated.') level = logging.DEBUG if opts.debug else None logging.basicConfig(level=level, format='[%(levelname).1s] %(message)s') # Allow for determining project from osc store. if not opts.project and core.is_project_dir('.'): opts.project = core.store_read_project('.') Cache.init() apiurl = self.get_api_url() if command not in ['cron', 'projects']: if not opts.project: raise oscerr.WrongArgs('A project must be indicated.') config = config_load(apiurl, opts.project) if not config: raise oscerr.WrongArgs('OSRT:OriginConfig attribute missing from {}'.format(opts.project)) function = 'osrt_origin_{}'.format(command) globals()[function](apiurl, opts, *args[1:])
def config_validate(self, target_project): config = config_load(self.apiurl, target_project) if not config: self.review_messages['declined'] = 'OSRT:OriginConfig attribute missing' return False if not config.get('fallback-group'): self.review_messages['declined'] = 'OSRT:OriginConfig.fallback-group missing' return False if not self.dryrun and config['review-user'] != self.review_user: self.logger.warning( 'OSRT:OriginConfig.review-user ({}) does not match ReviewBot.review_user ({})'.format( config['review-user'], self.review_user)) return True
def config_validate(self, target_project): config = config_load(self.apiurl, target_project) if not config: self.review_messages[ 'declined'] = 'OSRT:OriginConfig attribute missing' return False if not config.get('fallback-group'): self.review_messages[ 'declined'] = 'OSRT:OriginConfig.fallback-group missing' return False if not self.dryrun and config['review-user'] != self.review_user: self.logger.warning( 'OSRT:OriginConfig.review-user ({}) does not match ReviewBot.review_user ({})' .format(config['review-user'], self.review_user)) return True
def devel_project_simulate_check(self, source_project, target_project): config = config_load(self.apiurl, target_project) origin_list = config_origin_list(config, self.apiurl, target_project, skip_workarounds=True) if '<devel>' not in origin_list: return False, None if len(origin_list) == 1: return source_project, 'only devel origin allowed' if source_project in origin_devel_projects(self.apiurl, target_project): return source_project, 'familiar devel origin' override, who = self.devel_project_simulate_check_command(source_project, target_project) if override: return override, 'change_devel command by {}'.format(who) return False, None
def config_validate(self, target_project): config = config_load(self.apiurl, target_project) if not config: # No perfect solution for lack of a config. For normal projects a # decline seems best, but in the event of failure to return proper # config no good behavior. For maintenance the situation is further # complicated since multiple actions some of which are not intended # to be reviewed, but not always guaranteed to see multiple actions. self.review_messages['accepted'] = 'skipping since no OSRT:OriginConfig' return False, True if not config.get('fallback-group'): self.review_messages['declined'] = 'OSRT:OriginConfig.fallback-group missing' return False, False if not self.dryrun and config['review-user'] != self.review_user: self.logger.warning( 'OSRT:OriginConfig.review-user ({}) does not match ReviewBot.review_user ({})'.format( config['review-user'], self.review_user)) return True, True