Created
May 9, 2018 21:16
-
-
Save robbat2/551fc8ea56408ee48e99909f9c26c13e to your computer and use it in GitHub Desktop.
portage --refresh-keys
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/cnf/repos.conf b/cnf/repos.conf | |
index 987be6462..f720dc906 100644 | |
--- a/cnf/repos.conf | |
+++ b/cnf/repos.conf | |
@@ -10,6 +10,7 @@ sync-rsync-verify-jobs = 1 | |
sync-rsync-verify-metamanifest = yes | |
sync-rsync-verify-max-age = 24 | |
sync-openpgp-key-path = /var/lib/gentoo/gkeys/keyrings/gentoo/release/pubring.gpg | |
+sync-openpgp-key-refresh = true | |
sync-openpgp-key-refresh-retry-count = 40 | |
sync-openpgp-key-refresh-retry-overall-timeout = 1200 | |
sync-openpgp-key-refresh-retry-delay-exp-base = 2 | |
diff --git a/man/emerge.1 b/man/emerge.1 | |
index f53ba92f5..fef3e390a 100644 | |
--- a/man/emerge.1 | |
+++ b/man/emerge.1 | |
@@ -746,6 +746,14 @@ matching packages due to \fB\-\-rebuild\fR. | |
A space separated list of package names or slot atoms. Emerge will not rebuild | |
packages that depend on matching packages due to \fB\-\-rebuild\fR. | |
.TP | |
+.BR "\-\-refresh\-keys [ y | n ]" | |
+If specified as a standalone action, starts a OpenPGP key refresh. | |
+ | |
+If combined with the \fB\-\-sync\fR action , allows the user to globally | |
+disable OpenPGP key refresh during repositories sync. See also | |
+\fBsync\-openpgp\-key\-refresh\fR in \fBportage\fR(5) for more finely grained | |
+control. | |
+.TP | |
.BR \-\-oneshot ", " \-1 | |
Emerge as normal, but do not add the packages to the world file | |
for later updating. | |
diff --git a/man/portage.5 b/man/portage.5 | |
index 5adb07d82..c2a19e1f2 100644 | |
--- a/man/portage.5 | |
+++ b/man/portage.5 | |
@@ -1081,6 +1081,9 @@ only for protocols supporting cryptographic verification, provided | |
that the respective verification option is enabled. If unset, the user's | |
keyring is used. | |
.TP | |
+.B sync\-openpgp\-key\-refresh = true|false | |
+Controls automatic OpenPGP key refresh for this repository. Defaults to true. | |
+.TP | |
.B sync\-openpgp\-key\-refresh\-retry\-count = 40 | |
Maximum number of times to retry key refresh if it fails. Between each | |
key refresh attempt, there is an exponential delay with a constant | |
diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py | |
index 70fb8d3b4..61497274c 100644 | |
--- a/pym/_emerge/actions.py | |
+++ b/pym/_emerge/actions.py | |
@@ -1976,6 +1976,10 @@ def action_info(settings, trees, myopts, myfiles): | |
tree="bintree") | |
shutil.rmtree(tmpdir) | |
+def action_refresh_keys(emerge_config): | |
+ # TODO | |
+ pass | |
+ | |
def action_regen(settings, portdb, max_jobs, max_load): | |
xterm_titles = "notitles" not in settings.features | |
emergelog(xterm_titles, " === regen") | |
@@ -3201,6 +3205,9 @@ def run_action(emerge_config): | |
emerge_config.target_config.trees['porttree'].dbapi, | |
emerge_config.opts.get("--jobs"), | |
emerge_config.opts.get("--load-average")) | |
+ # REFRESH_KEYS action | |
+ elif "refresh_keys" == emerge_config.action: | |
+ return action_refresh_keys(emerge_config) | |
# HELP action | |
elif "config" == emerge_config.action: | |
validate_ebuild_environment(emerge_config.trees) | |
diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py | |
index e8b2c2e13..fd7ed8438 100644 | |
--- a/pym/_emerge/main.py | |
+++ b/pym/_emerge/main.py | |
@@ -162,6 +162,7 @@ def insert_optional_args(args): | |
'--rebuild-if-new-ver' : y_or_n, | |
'--rebuild-if-unbuilt' : y_or_n, | |
'--rebuilt-binaries' : y_or_n, | |
+ '--refresh-keys' : y_or_n, | |
'--root-deps' : ('rdeps',), | |
'--select' : y_or_n, | |
'--selective' : y_or_n, | |
@@ -306,6 +307,9 @@ def parse_opts(tmpcmdline, silent=False): | |
"info", "list-sets", "metadata", "moo", | |
"prune", "rage-clean", "regen", "search", | |
"sync", "unmerge", "version", | |
+ # The following are both valid options AND actions: | |
+ # --refresh-keys | |
+ # --deselect | |
]) | |
longopt_aliases = {"--cols":"--columns", "--skip-first":"--skipfirst"} | |
@@ -692,6 +696,11 @@ def parse_opts(tmpcmdline, silent=False): | |
"action" : "store" | |
}, | |
+ "--refresh-keys": { | |
+ "help" : "refresh OpenPGP keys as needed to verify repos", | |
+ "choices" : true_y_or_n | |
+ }, | |
+ | |
"--root": { | |
"help" : "specify the target root filesystem for merging packages", | |
"action" : "store" | |
@@ -915,6 +924,9 @@ def parse_opts(tmpcmdline, silent=False): | |
parser.error("Invalid Atom(s) in --rebuild-ignore parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ | |
(",".join(bad_atoms),)) | |
+ if myoptions.refresh_keys is None or myoptions.refresh_keys in true_y: | |
+ myoptions.refresh_keys = True # refresh keys by default, or if set to true/yes | |
+ | |
if myoptions.usepkg_exclude: | |
bad_atoms = _find_bad_atoms(myoptions.usepkg_exclude) | |
if bad_atoms and not silent: | |
@@ -1155,6 +1167,9 @@ def parse_opts(tmpcmdline, silent=False): | |
if myaction is None and myoptions.deselect is True: | |
myaction = 'deselect' | |
+ if myaction is None and '--refresh-keys' in tmpcmdline and myoptions.refresh_keys is True: | |
+ myaction = 'refresh_keys' | |
+ | |
myfiles += myargs | |
return myaction, myopts, myfiles | |
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py | |
index 1d897bb90..f82fc16e3 100644 | |
--- a/pym/portage/repository/config.py | |
+++ b/pym/portage/repository/config.py | |
@@ -87,6 +87,7 @@ class RepoConfig(object): | |
'update_changelog', '_eapis_banned', '_eapis_deprecated', | |
'_masters_orig', 'module_specific_options', 'manifest_required_hashes', | |
'sync_openpgp_key_path', | |
+ 'sync_openpgp_key_refresh', | |
'sync_openpgp_key_refresh_retry_count', | |
'sync_openpgp_key_refresh_retry_delay_max', | |
'sync_openpgp_key_refresh_retry_delay_exp_base', | |
@@ -191,6 +192,9 @@ class RepoConfig(object): | |
self.sync_openpgp_key_path = repo_opts.get( | |
'sync-openpgp-key-path', None) | |
+ self.sync_openpgp_key_refresh = repo_opts.get( | |
+ 'sync-openpgp-key-refresh', 'true').lower() == 'true' | |
+ | |
for k in ('sync_openpgp_key_refresh_retry_count', | |
'sync_openpgp_key_refresh_retry_delay_max', | |
'sync_openpgp_key_refresh_retry_delay_exp_base', | |
diff --git a/pym/portage/sync/modules/git/git.py b/pym/portage/sync/modules/git/git.py | |
index 160137a6d..9b9d566f1 100644 | |
--- a/pym/portage/sync/modules/git/git.py | |
+++ b/pym/portage/sync/modules/git/git.py | |
@@ -147,6 +147,9 @@ class GitSync(NewBase): | |
return (os.EX_OK, current_rev != previous_rev) | |
def verify_head(self): | |
+ opts = self.options.get('emerge_config').opts | |
+ openpgp_refresh = '--refresh-keys' in opts | |
+ | |
if (self.repo.module_specific_options.get( | |
'sync-git-verify-commit-signature', 'false') != 'true'): | |
return True | |
@@ -168,9 +171,10 @@ class GitSync(NewBase): | |
out.einfo('Using keys from %s' % (self.repo.sync_openpgp_key_path,)) | |
with io.open(self.repo.sync_openpgp_key_path, 'rb') as f: | |
openpgp_env.import_key(f) | |
- out.ebegin('Refreshing keys from keyserver') | |
- openpgp_env.refresh_keys() | |
- out.eend(0) | |
+ if self.repo.sync_openpgp_key_refresh and openpgp_refresh: | |
+ out.ebegin('Refreshing keys from keyserver') | |
+ openpgp_env.refresh_keys() | |
+ out.eend(0) | |
except GematoException as e: | |
writemsg_level("!!! Verification impossible due to keyring problem:\n%s\n" | |
% (e,), | |
diff --git a/pym/portage/sync/modules/rsync/rsync.py b/pym/portage/sync/modules/rsync/rsync.py | |
index 382a1eaae..6d7108721 100644 | |
--- a/pym/portage/sync/modules/rsync/rsync.py | |
+++ b/pym/portage/sync/modules/rsync/rsync.py | |
@@ -67,6 +67,7 @@ class RsyncSync(NewBase): | |
opts = self.options.get('emerge_config').opts | |
self.usersync_uid = self.options.get('usersync_uid', None) | |
enter_invalid = '--ask-enter-invalid' in opts | |
+ openpgp_refresh = '--refresh-keys' in opts | |
quiet = '--quiet' in opts | |
out = portage.output.EOutput(quiet=quiet) | |
syncuri = self.repo.sync_uri | |
@@ -154,34 +155,35 @@ class RsyncSync(NewBase): | |
out.einfo('Using keys from %s' % (self.repo.sync_openpgp_key_path,)) | |
with io.open(self.repo.sync_openpgp_key_path, 'rb') as f: | |
openpgp_env.import_key(f) | |
- out.ebegin('Refreshing keys from keyserver') | |
- retry_decorator = self._key_refresh_retry_decorator() | |
- if retry_decorator is None: | |
- openpgp_env.refresh_keys() | |
- else: | |
- def noisy_refresh_keys(): | |
- """ | |
- Since retry does not help for some types of | |
- errors, display errors as soon as they occur. | |
- """ | |
- try: | |
- openpgp_env.refresh_keys() | |
- except Exception as e: | |
- writemsg_level("%s\n" % (e,), | |
- level=logging.ERROR, noiselevel=-1) | |
- raise # retry | |
- | |
- # The ThreadPoolExecutor that asyncio uses by default | |
- # does not support cancellation of tasks, therefore | |
- # use ForkExecutor for task cancellation support, in | |
- # order to enforce timeouts. | |
- loop = global_event_loop() | |
- with ForkExecutor(loop=loop) as executor: | |
- func_coroutine = functools.partial(loop.run_in_executor, | |
- executor, noisy_refresh_keys) | |
- decorated_func = retry_decorator(func_coroutine, loop=loop) | |
- loop.run_until_complete(decorated_func()) | |
- out.eend(0) | |
+ if self.repo.sync_openpgp_key_refresh and openpgp_refresh: | |
+ out.ebegin('Refreshing keys from keyserver') | |
+ retry_decorator = self._key_refresh_retry_decorator() | |
+ if retry_decorator is None: | |
+ openpgp_env.refresh_keys() | |
+ else: | |
+ def noisy_refresh_keys(): | |
+ """ | |
+ Since retry does not help for some types of | |
+ errors, display errors as soon as they occur. | |
+ """ | |
+ try: | |
+ openpgp_env.refresh_keys() | |
+ except Exception as e: | |
+ writemsg_level("%s\n" % (e,), | |
+ level=logging.ERROR, noiselevel=-1) | |
+ raise # retry | |
+ | |
+ # The ThreadPoolExecutor that asyncio uses by default | |
+ # does not support cancellation of tasks, therefore | |
+ # use ForkExecutor for task cancellation support, in | |
+ # order to enforce timeouts. | |
+ loop = global_event_loop() | |
+ with ForkExecutor(loop=loop) as executor: | |
+ func_coroutine = functools.partial(loop.run_in_executor, | |
+ executor, noisy_refresh_keys) | |
+ decorated_func = retry_decorator(func_coroutine, loop=loop) | |
+ loop.run_until_complete(decorated_func()) | |
+ out.eend(0) | |
except (GematoException, asyncio.TimeoutError) as e: | |
writemsg_level("!!! Manifest verification impossible due to keyring problem:\n%s\n" | |
% (e,), |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment