diff --git a/doc/reposync.rst b/doc/reposync.rst index 71a435d..de40957 100644 --- a/doc/reposync.rst +++ b/doc/reposync.rst @@ -39,36 +39,40 @@ 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). +``-a , --arch=`` + Download only packages of given architectures (default is all architectures). Can be used multiple times. + +``--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. -``-a , --arch=`` - Download only packages of given architectures (default is all architectures). Can be used multiple times. - -``--source`` - Operate on source packages. +``-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. +``--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 7556e7e..c891bfa 100644 --- a/plugins/reposync.py +++ b/plugins/reposync.py @@ -24,6 +24,7 @@ from __future__ import unicode_literals import hawkey import os import shutil +import types from dnfpluginscore import _, logger from dnf.cli.option_parser import OptionParser @@ -63,24 +64,27 @@ class RepoSyncCommand(dnf.cli.Command): 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('-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', + 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")) @@ -114,6 +118,7 @@ class RepoSyncCommand(dnf.cli.Command): 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 @@ class RepoSyncCommand(dnf.cli.Command): 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,