From a4f21266a6dab9e77913d56c04aba1e579f0e0c1 Mon Sep 17 00:00:00 2001 From: Marek Blaha Date: Fri, 23 Oct 2020 09:06:35 +0200 Subject: [PATCH 1/2] [reposync] Reorder options alphabetically --- doc/reposync.rst | 30 +++++++++++++++--------------- plugins/reposync.py | 18 +++++++++--------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/doc/reposync.rst b/doc/reposync.rst index 71a435dc..3b820f33 100644 --- a/doc/reposync.rst +++ b/doc/reposync.rst @@ -39,36 +39,36 @@ Options All general DNF options are accepted. Namely, the ``--repoid`` option can be used to specify the repositories to synchronize. See `Options` in :manpage:`dnf(8)` for details. -``-p , --download-path=`` - Root path under which the downloaded repositories are stored, relative to the current working directory. Defaults to the current working directory. Every downloaded repository has a subdirectory named after its ID under this path. - -``--norepopath`` - Don't add the reponame to the download path. Can only be used when syncing a single repository (default is to add the reponame). - -``--download-metadata`` - Download all repository metadata. Downloaded copy is instantly usable as a repository, no need to run createrepo_c on it. - ``-a , --arch=`` Download only packages of given architectures (default is all architectures). Can be used multiple times. -``--source`` - Operate on source packages. +``--delete`` + Delete local packages no longer present in repository. + +``--download-metadata`` + Download all repository metadata. Downloaded copy is instantly usable as a repository, no need to run createrepo_c on it. ``-m, --downloadcomps`` Also download and uncompress comps.xml. Consider using ``--download-metadata`` option which will download all available repository metadata. +``--metadata-path`` + Root path under which the downloaded metadata are stored. It defaults to ``--download-path`` value if not given. + ``-n, --newest-only`` Download only newest packages per-repo. -``--delete`` - Delete local packages no longer present in repository. +``--norepopath`` + Don't add the reponame to the download path. Can only be used when syncing a single repository (default is to add the reponame). -``--metadata-path`` - Root path under which the downloaded metadata are stored. It defaults to ``--download-path`` value if not given. +``-p , --download-path=`` + Root path under which the downloaded repositories are stored, relative to the current working directory. Defaults to the current working directory. Every downloaded repository has a subdirectory named after its ID under this path. ``--remote-time`` Try to set the timestamps of the downloaded files to those on the remote side. +``--source`` + Operate on source packages. + ``-u, --urls`` Just print urls of what would be downloaded, don't download. diff --git a/plugins/reposync.py b/plugins/reposync.py index 7556e7eb..6f572cac 100644 --- a/plugins/reposync.py +++ b/plugins/reposync.py @@ -63,24 +63,24 @@ def set_argparser(parser): help=_('download only packages for this ARCH')) parser.add_argument('--delete', default=False, action='store_true', help=_('delete local packages no longer present in repository')) - parser.add_argument('-m', '--downloadcomps', default=False, action='store_true', - help=_('also download and uncompress comps.xml')) parser.add_argument('--download-metadata', default=False, action='store_true', help=_('download all the metadata.')) + parser.add_argument('-m', '--downloadcomps', default=False, action='store_true', + help=_('also download and uncompress comps.xml')) + parser.add_argument('--metadata-path', + help=_('where to store downloaded repository metadata. ' + 'Defaults to the value of --download-path.')) parser.add_argument('-n', '--newest-only', default=False, action='store_true', help=_('download only newest packages per-repo')) - parser.add_argument('-p', '--download-path', default='./', - help=_('where to store downloaded repositories')) parser.add_argument('--norepopath', default=False, action='store_true', help=_("Don't add the reponame to the download path.")) - parser.add_argument('--metadata-path', - help=_('where to store downloaded repository metadata. ' - 'Defaults to the value of --download-path.')) - parser.add_argument('--source', default=False, action='store_true', - help=_('operate on source packages')) + parser.add_argument('-p', '--download-path', default='./', + help=_('where to store downloaded repositories')) parser.add_argument('--remote-time', default=False, action='store_true', help=_('try to set local timestamps of local files by ' 'the one on the server')) + parser.add_argument('--source', default=False, action='store_true', + help=_('operate on source packages')) parser.add_argument('-u', '--urls', default=False, action='store_true', help=_("Just list urls of what would be downloaded, " "don't download")) From 978b7f2b1c654fed7b1b4cf45cb607143226804c Mon Sep 17 00:00:00 2001 From: Marek Blaha Date: Fri, 23 Oct 2020 09:14:02 +0200 Subject: [PATCH 2/2] [reposync] Check GPG signatures of downloaded packages (RhBug:1856818) YUMv3 reposync used to have --gpgcheck option to remove packages that fail GPG signature checking after downloading. This patch implements the option for DNF. = changelog = msg: Add --gpgcheck option to reposync (RhBug:1856818) type: enhancement resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1856818 --- doc/reposync.rst | 4 ++++ plugins/reposync.py | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/doc/reposync.rst b/doc/reposync.rst index 3b820f33..de40957f 100644 --- a/doc/reposync.rst +++ b/doc/reposync.rst @@ -48,6 +48,10 @@ All general DNF options are accepted. Namely, the ``--repoid`` option can be use ``--download-metadata`` Download all repository metadata. Downloaded copy is instantly usable as a repository, no need to run createrepo_c on it. +``-g, --gpgcheck`` + Remove packages that fail GPG signature checking after downloading. Exit code is ``1`` if at least one package was removed. + Note that for repositories with ``gpgcheck=0`` set in their configuration the GPG signature is not checked even with this option used. + ``-m, --downloadcomps`` Also download and uncompress comps.xml. Consider using ``--download-metadata`` option which will download all available repository metadata. diff --git a/plugins/reposync.py b/plugins/reposync.py index 6f572cac..c891bfa2 100644 --- a/plugins/reposync.py +++ b/plugins/reposync.py @@ -24,6 +24,7 @@ import hawkey import os import shutil +import types from dnfpluginscore import _, logger from dnf.cli.option_parser import OptionParser @@ -65,6 +66,9 @@ def set_argparser(parser): help=_('delete local packages no longer present in repository')) parser.add_argument('--download-metadata', default=False, action='store_true', help=_('download all the metadata.')) + parser.add_argument('-g', '--gpgcheck', default=False, action='store_true', + help=_('Remove packages that fail GPG signature checking ' + 'after downloading')) parser.add_argument('-m', '--downloadcomps', default=False, action='store_true', help=_('also download and uncompress comps.xml')) parser.add_argument('--metadata-path', @@ -114,6 +118,7 @@ def configure(self): def run(self): self.base.conf.keepcache = True + gpgcheck_ok = True for repo in self.base.repos.iter_enabled(): if self.opts.remote_time: repo._repo.setPreserveRemoteTime(True) @@ -150,8 +155,24 @@ def run(self): self.print_urls(pkglist) else: self.download_packages(pkglist) + if self.opts.gpgcheck: + for pkg in pkglist: + local_path = self.pkg_download_path(pkg) + # base.package_signature_check uses pkg.localPkg() to determine + # the location of the package rpm file on the disk. + # Set it to the correct download path. + pkg.localPkg = types.MethodType( + lambda s, local_path=local_path: local_path, pkg) + result, error = self.base.package_signature_check(pkg) + if result != 0: + logger.warning(_("Removing {}: {}").format( + os.path.basename(local_path), error)) + os.unlink(local_path) + gpgcheck_ok = False if self.opts.delete: self.delete_old_local_packages(repo, pkglist) + if not gpgcheck_ok: + raise dnf.exceptions.Error(_("GPG signature check failed.")) def repo_target(self, repo): return _pkgdir(self.opts.destdir or self.opts.download_path,