From 13623dbfc85ad5200db677dec70095d7d72e76c1 Mon Sep 17 00:00:00 2001 From: Ondřej Nosek Date: Oct 24 2023 20:54:03 +0000 Subject: *pkg import: check specfile matches the repo name Specfile in SRPM is check whether has the same name as the dist-git repository name. It should prevent having multiple similar repositories accidentally created. This behavior can be omitted by adding argument after `import` command: '--do-not-check-specfile-name'. JIRA: RHELCMP-12669 Fixes: https://pagure.io/fedpkg/issue/529 Relates: https://pagure.io/releng/issue/7523 Signed-off-by: Ondřej Nosek --- diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py index 0dcd46b..1dfb82b 100644 --- a/pyrpkg/__init__.py +++ b/pyrpkg/__init__.py @@ -46,8 +46,8 @@ from six.moves.urllib.parse import urljoin from pyrpkg import layout from pyrpkg.errors import (AlreadyUploadedError, HashtypeMixingError, - NoSourcesError, UnknownTargetError, rpkgAuthError, - rpkgError) + NoSourcesError, SpecfileDoesntMatchRepoNameError, + UnknownTargetError, rpkgAuthError, rpkgError) from pyrpkg.lookaside import CGILookasideCache from pyrpkg.sources import SourcesFile from pyrpkg.spec import SpecFile @@ -2001,13 +2001,15 @@ class Commands(object): raise rpkgError('Could not find hash of build %s' % build) return (hash) - def import_srpm(self, srpm): + def import_srpm(self, srpm, check_specfile_matches_repo_name=True): """Import the contents of an srpm into a repo. This function will add/remove content to match the srpm, upload new files to the lookaside, and stage the changes. :param str srpm: file to import contents from. + :param bool check_specfile_matches_repo_name: check specfile + in SRPM matches the repository name :return: a list of files to upload. :rtype: list """ @@ -2059,6 +2061,18 @@ class Commands(object): self.repo.index.remove([file]) os.remove(file) + specfile_matches_repo_name = False + for file in files: + if self.repo_name + '.spec' == file: + specfile_matches_repo_name = True + if check_specfile_matches_repo_name and not specfile_matches_repo_name: + raise SpecfileDoesntMatchRepoNameError( + "Error: Specfile '{0}' doesn't match repo name '{1}'. This check " + "can be omitted by adding argument '--do-not-check-specfile-name'".format( + ", ".join(file for file in files if file.endswith('.spec')), + self.repo_name) + ) + try: self.log.debug("Extracting srpm '{0}'".format(srpm)) output, err = extract_srpm(srpm) diff --git a/pyrpkg/cli.py b/pyrpkg/cli.py index c60548a..6fd6df0 100644 --- a/pyrpkg/cli.py +++ b/pyrpkg/cli.py @@ -991,6 +991,12 @@ class cliClient(object): import_srpm_parser.add_argument( '--offline', help='Do not upload files into lookaside cache', action='store_true') + import_srpm_parser.add_argument( + '--do-not-check-specfile-name', + action='store_true', + default=False, + help="Do not check whether specfile in SRPM matches " + "the repository name") import_srpm_parser.add_argument('srpm', help='Source rpm to import') import_srpm_parser.set_defaults(command=self.import_srpm) @@ -2385,7 +2391,9 @@ class cliClient(object): print(self.cmd.giturl()) def import_srpm(self): - uploadfiles = self.cmd.import_srpm(self.args.srpm) + uploadfiles = self.cmd.import_srpm( + self.args.srpm, + check_specfile_matches_repo_name=not self.args.do_not_check_specfile_name) if uploadfiles: try: self.cmd.upload(uploadfiles, replace=True, offline=self.args.offline) diff --git a/pyrpkg/errors.py b/pyrpkg/errors.py index bde502b..caba963 100644 --- a/pyrpkg/errors.py +++ b/pyrpkg/errors.py @@ -78,3 +78,10 @@ class AlreadyUploadedError(rpkgError): class NoSourcesError(rpkgError): """Raised when there are no sources""" pass + + +class SpecfileDoesntMatchRepoNameError(rpkgError): + """Raised when srpm doesn't contain specfile that matches + with repository name + """ + pass diff --git a/pyrpkg/lookaside.py b/pyrpkg/lookaside.py index 77eeab3..1f01c9b 100644 --- a/pyrpkg/lookaside.py +++ b/pyrpkg/lookaside.py @@ -128,7 +128,7 @@ class CGILookasideCache(object): def raise_upload_error(self, http_status): messages = { - http_client.UNAUTHORIZED: 'Request is unauthorized.', + http_client.UNAUTHORIZED: 'Dist-git request is unauthorized.', http_client.INTERNAL_SERVER_ERROR: 'Error occurs inside the server.', } default = 'Fail to upload files. Server returns status {0}'.format(http_status) @@ -194,7 +194,7 @@ class CGILookasideCache(object): if status != 200: self.log.info('Remove downloaded invalid file %s', outfile) os.remove(outfile) - raise DownloadError('Server returned status code %d' % status) + raise DownloadError('Dist-git server returned status code %d' % status) os.utime(outfile, (tstamp, tstamp)) @@ -406,7 +406,7 @@ class CGILookasideCache(object): try: return function(*args, **kwargs) except wait_on as e: - self.log.warn("Network error: %s" % (e)) + self.log.warning("Network error: %s" % (e)) attempts_left -= 1 self.log.debug("Attempt %d/%d has failed." % (attempts_all - attempts_left, attempts_all)) diff --git a/tests/test_cli.py b/tests/test_cli.py index 04eba43..712a395 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1840,7 +1840,7 @@ class TestImportSrpm(LookasideCacheMock, CliTestCase): cli.import_srpm() # no exception should be raised def test_import_srpm_processed_by_rpmautospec(self): - cli_cmd = ['rpkg', '--path', self.chaos_repo, '--name', 'docpkg', + cli_cmd = ['rpkg', '--path', self.chaos_repo, '--name', 'docpkg-rpmautospec', 'import', '--skip-diffs', self.srpm_file_rpmautospec] with patch('sys.argv', new=cli_cmd):