From 19a1f22cd0a06eeb1cdea8e81ce7871bd5d6d6a2 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 14 Feb 2020 16:28:13 -0500 Subject: [PATCH] repo: rework gpg import for Windows Some versions of gpg on Windows mishandle native paths with homedir. It manifests itself like: gpg: keybox 'C:\Users\.../.repoconfig\gnupg/pubring.kbx' created gpg: C:\Users\.../.repoconfig\gnupg/trustdb.gpg: trustdb created gpg: key 16530D5E920F5C65: public key "Repo Maintainer " imported gpg: can't connect to the agent: Invalid value passed to IPC gpg: Total number processed: 1 gpg: imported: 1 fatal: registering repo maintainer keys failed It seems gpg (at least version 2.2.17) needs paths to be specified in cygwin form (e.g. "/c/Users/.../.repoconfig/gnupg") otherwise it fails to talk to its own processes. We can work around this with a minor trick: we cd to the right path and then invoke gpg with --homedir . and let gpg itself resolve . to whatever form it really wants. This is a bit hacky, but we don't control gpg, and this allows us to avoid having to muck with the environment. Since --homedir has been around since at least gpg-1.4.x from 2004, backwards compat shouldn't be an issue. While we're here, touch up the output a bit: there's no need to dump all the chatty gpg output if things don't fail, so always swallow the output. If things do fail, our exception handler takes care of dumping the full stdout & stderr. Change-Id: I74ab98e1e61e95318fda6faf57c6a8699f775935 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/255120 Reviewed-by: David Pursehouse Tested-by: Mike Frysinger --- repo | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/repo b/repo index 5674be84..30bce52b 100755 --- a/repo +++ b/repo @@ -650,13 +650,19 @@ def SetupGnuPG(quiet): file=sys.stderr) sys.exit(1) - env = os.environ.copy() - _setenv('GNUPGHOME', gpg_dir, env) - - cmd = ['gpg', '--import'] + if not quiet: + print('repo: Updating release signing keys to keyset ver %s' % + ('.'.join(str(x) for x in KEYRING_VERSION),)) + # NB: We use --homedir (and cwd below) because some environments (Windows) do + # not correctly handle full native paths. We avoid the issue by changing to + # the right dir with cwd=gpg_dir before executing gpg, and then telling gpg to + # use the cwd (.) as its homedir which leaves the path resolution logic to it. + cmd = ['gpg', '--homedir', '.', '--import'] try: - run_command(cmd, env=env, stdin=subprocess.PIPE, - capture_output=quiet, + # gpg can be pretty chatty. Always capture the output and if something goes + # wrong, the builtin check failure will dump stdout & stderr for debugging. + run_command(cmd, stdin=subprocess.PIPE, capture_output=True, + cwd=gpg_dir, check=True, input=MAINTAINER_KEYS.encode('utf-8')) except OSError: if not quiet: @@ -665,9 +671,6 @@ def SetupGnuPG(quiet): print(file=sys.stderr) return False - if not quiet: - print() - with open(os.path.join(home_dot_repo, 'keyring-version'), 'w') as fd: fd.write('.'.join(map(str, KEYRING_VERSION)) + '\n') return True