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 <repo@android.kernel.org>" 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 <dpursehouse@collab.net>
Tested-by: Mike Frysinger <vapier@google.com>
This commit is contained in:
Mike Frysinger 2020-02-14 16:28:13 -05:00
parent 076512aafa
commit 19a1f22cd0

21
repo
View File

@ -650,13 +650,19 @@ def SetupGnuPG(quiet):
file=sys.stderr) file=sys.stderr)
sys.exit(1) sys.exit(1)
env = os.environ.copy() if not quiet:
_setenv('GNUPGHOME', gpg_dir, env) print('repo: Updating release signing keys to keyset ver %s' %
('.'.join(str(x) for x in KEYRING_VERSION),))
cmd = ['gpg', '--import'] # 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: try:
run_command(cmd, env=env, stdin=subprocess.PIPE, # gpg can be pretty chatty. Always capture the output and if something goes
capture_output=quiet, # 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')) input=MAINTAINER_KEYS.encode('utf-8'))
except OSError: except OSError:
if not quiet: if not quiet:
@ -665,9 +671,6 @@ def SetupGnuPG(quiet):
print(file=sys.stderr) print(file=sys.stderr)
return False return False
if not quiet:
print()
with open(os.path.join(home_dot_repo, 'keyring-version'), 'w') as fd: with open(os.path.join(home_dot_repo, 'keyring-version'), 'w') as fd:
fd.write('.'.join(map(str, KEYRING_VERSION)) + '\n') fd.write('.'.join(map(str, KEYRING_VERSION)) + '\n')
return True return True