def testDecodeList(self): strlist = ['Test1', 'Test2', 'Test3'] mixlist = ['Test1', b'Test2', 'Test3'] byteslist = [b'Test1', b'Test2', b'Test3'] out = decode_list(strlist) self.assertListEqual(out, strlist) out = decode_list(mixlist) self.assertListEqual(out, strlist) out = decode_list(byteslist) self.assertListEqual(out, strlist)
def get_support_package_list(self, project, repository): f = decode_list(osc.core.get_buildconfig(self.apiurl, project, repository).splitlines()) pkg_list = [] for line in f: if re.match('Preinstall', line) or re.match('VM[Ii]nstall', line) or re.match('Support', line): content = line.split(':') variables = [x.strip() for x in content[1].split(' ')] for var in variables: if var != '' and var not in pkg_list: if var.startswith('!') and var[1:] in pkg_list: pkg_list.remove(var[1:]) else: pkg_list.append(var) return pkg_list
def __check_diff(self, p, exp, revision=None): got = '' for i in p.get_diff(revision): got += ''.join(decode_list(i)) # When a hunk header refers to a single line in the "from" # file and/or the "to" file, e.g. # # @@ -37,37 +41,43 @@ # @@ -37,39 +41,41 @@ # @@ -37,37 +41,41 @@ # # some systems will avoid repeating the line number: # # @@ -37 +41,43 @@ # @@ -37,39 +41 @@ # @@ -37 +41 @@ # # so we need to canonise the output to avoid false negative # test failures. # TODO: Package.get_diff should return a consistent format # (regardless of the used python version) def __canonise_diff(diff): # we cannot use re.M because python 2.6's re.sub does # not support a flags argument diff = [ re.sub('^@@ -(\d+) ', '@@ -\\1,\\1 ', line) for line in diff.split('\n') ] diff = [ re.sub('^(@@ -\d+,\d+) \+(\d+) ', '\\1 +\\2,\\2 ', line) for line in diff ] return '\n'.join(diff) got = __canonise_diff(got) exp = __canonise_diff(exp) self.assertEqualMultiline(got, exp)
def check_source_submission(self, source_project, source_package, source_revision, target_project, target_package): super(CheckSource, self).check_source_submission(source_project, source_package, source_revision, target_project, target_package) self.target_project_config(target_project) if self.single_action_require and len(self.request.actions) != 1: self.review_messages[ 'declined'] = 'Only one action per request allowed' return False kind = package_kind(self.apiurl, target_project, target_package) if kind == 'meta': self.review_messages[ 'accepted'] = 'Skipping all checks for meta packages' return True elif (kind is not None and kind != 'source'): self.review_messages[ 'declined'] = 'May not modify a non-source package of type {}'.format( kind) return False inair_renamed = target_package != source_package if not self.ignore_devel: self.logger.info( 'checking if target package exists and has devel project') devel_project, devel_package = devel_project_get( self.apiurl, target_project, target_package) if devel_project: if (source_project != devel_project or source_package != devel_package) and \ not(source_project == target_project and source_package == target_package): # Not from proper devel project/package and not self-submission. self.review_messages[ 'declined'] = 'Expected submission from devel package %s/%s' % ( devel_project, devel_package) return False else: # Check to see if other packages exist with the same source project # which indicates that the project has already been used as devel. if not self.is_devel_project(source_project, target_project): self.review_messages['declined'] = ( '%s is not a devel project of %s, submit the package to a devel project first. ' 'See https://en.opensuse.org/openSUSE:How_to_contribute_to_Factory#How_to_request_a_new_devel_project for details.' ) % (source_project, target_project) return False else: if source_project.endswith(':Update'): # Allow for submission like: # - source: openSUSE:Leap:15.0:Update/google-compute-engine.8258 # - target: openSUSE:Leap:15.1/google-compute-engine # Note: home:jberry:Update would also be allowed via this condition, # but that should be handled by leaper and human review. # Ignore a dot in package name (ex. tpm2.0-abrmd) and instead # only look for ending in dot number. match = re.match(r'(.*)\.\d+$', source_package) if match: inair_renamed = target_package != match.group(1) if not self.in_air_rename_allow and inair_renamed: self.review_messages[ 'declined'] = 'Source and target package names must match' return False # Checkout and see if renaming package screws up version parsing. dir = os.path.expanduser('~/co/%s' % self.request.reqid) if os.path.exists(dir): self.logger.warning('directory %s already exists' % dir) shutil.rmtree(dir) os.makedirs(dir) os.chdir(dir) old_info = {'version': None} try: CheckSource.checkout_package(self.apiurl, target_project, target_package, pathname=dir, server_service_files=True, expand_link=True) shutil.rmtree(os.path.join(target_package, '.osc')) os.rename(target_package, '_old') old_info = self.package_source_parse(target_project, target_package) except HTTPError as e: if e.code == 404: self.logger.info('target package does not exist %s/%s' % (target_project, target_package)) else: raise e CheckSource.checkout_package(self.apiurl, source_project, source_package, revision=source_revision, pathname=dir, server_service_files=True, expand_link=True) os.rename(source_package, target_package) shutil.rmtree(os.path.join(target_package, '.osc')) new_info = self.package_source_parse(source_project, source_package, source_revision, target_package) filename = new_info.get('filename', '') if not (filename.endswith('.kiwi') or filename == 'Dockerfile') and new_info['name'] != target_package: shutil.rmtree(dir) self.review_messages[ 'declined'] = "A package submitted as %s has to build as 'Name: %s' - found Name '%s'" % ( target_package, target_package, new_info['name']) return False # Run check_source.pl script and interpret output. source_checker = os.path.join(CheckSource.SCRIPT_PATH, 'check_source.pl') civs = '' new_version = None if old_info['version'] and old_info['version'] != new_info['version']: new_version = new_info['version'] civs += "NEW_VERSION='{}' ".format(new_version) civs += 'LC_ALL=C perl %s _old %s 2>&1' % (source_checker, target_package) p = subprocess.Popen(civs, shell=True, stdout=subprocess.PIPE, close_fds=True) ret = os.waitpid(p.pid, 0)[1] checked = decode_list(p.stdout.readlines()) output = ' '.join(checked).replace('\033', '') os.chdir('/tmp') # ret = 0 : Good # ret = 1 : Bad # ret = 2 : Bad but can be non-fatal in some cases if ret > 1 and target_project.startswith('openSUSE:Leap:') and ( source_project.startswith('SUSE:SLE-15:') or source_project.startswith('openSUSE:Factory')): pass elif ret != 0: shutil.rmtree(dir) self.review_messages[ 'declined'] = "Output of check script:\n" + output return False shutil.rmtree(dir) self.review_messages['accepted'] = 'Check script succeeded' if len(checked): self.review_messages[ 'accepted'] += "\n\nOutput of check script (non-fatal):\n" + output if not self.skip_add_reviews: if self.add_review_team and self.review_team is not None: self.add_review(self.request, by_group=self.review_team, msg='Please review sources') if self.only_changes(): self.logger.debug('only .changes modifications') if self.staging_group and self.review_user in group_members( self.apiurl, self.staging_group): if not self.dryrun: osc.core.change_review_state( self.apiurl, str(self.request.reqid), 'accepted', by_group=self.staging_group, message= 'skipping the staging process since only .changes modifications' ) else: self.logger.debug( 'unable to skip staging review since not a member of staging group' ) elif self.repo_checker is not None: self.add_review(self.request, by_user=self.repo_checker, msg='Please review build success') if self.bad_rpmlint_entries: if self.has_whitelist_warnings(source_project, source_package, target_project, target_package): # if there are any add a review for the security team # maybe add the found warnings to the message for the review self.add_review(self.request, by_group=self.security_review_team, msg=CheckSource.AUDIT_BUG_MESSAGE) if self.suppresses_whitelist_warnings(source_project, source_package): self.add_review(self.request, by_group=self.security_review_team, msg=CheckSource.AUDIT_BUG_MESSAGE) return True