freebsd / poudriere

Port/Package build and test system
https://github.com/freebsd/poudriere/wiki
BSD 2-Clause "Simplified" License
381 stars 161 forks source link

Env passing breaks git "global" (home directory) config #841

Open overhacked opened 3 years ago

overhacked commented 3 years ago

Prerequisites

Describe the bug

When Poudriere invokes a subcommand script, HOME is not one of the passed environment variables. git's ability to read "global" config (~/.gitconfig or $XDG_HOME/git/config) breaks, because it relies on the HOME environment variable rather than calling getpwuid() like openssh does.

How to reproduce

  1. Set a git option globally, like credential store: git config --global credential.helper=store
  2. Manually clone a private repository that requires authentication, to populate the credential store: git clone --depth-1 $REPO_URL \ (you can pre-populate the url-encoded credentials in ~/.git-credentials, but running clone is the simplest way)
  3. Run git fetch -vv from the cloned directory to prove that git doesn't ask for credentials again.
  4. Have Poudriere create a ports tree from that same repository: poudriere ports -c -p credential_test -m git -U $REPO_URL
  5. When Poudriere invokes git in ports.sh, it will ask for a username / password again even though they're already in ~/.git-credentials.

Expected behavior

If git config --global credential.helper=store is set and there are valid credentials in ~/.git-credentials, actions to the same server should not prompt for credentials.

Environment

bdrewery commented 3 years ago

https://gist.github.com/bdrewery/f36d2e6207ccc7aa7c0f6e3d0b891873 should fix it but I don't want to rush into passing it through. Need to think about what else it might impact.

bdrewery commented 3 years ago

If there is another git env var you can set to achieve this (that's not HOME) you could export it from your poudriere.conf too.

overhacked commented 3 years ago

Well, as of git 2.31 (unreleased), git will allow passing configuration options via environment variables (see also, on Stack Overflow). But that's pretty bleeding edge. 😐

Looking at ports.sh, I think another workaround would be setting GIT_CMD in poudriere.conf, too:

GIT_CMD='git -c credential.helper="store --file /root/.git-credentials"'

I haven't yet had a chance to test that, and the quoting is a bit weird because you would definitely have to pass the --file option to git-credential-store because it uses HOME to find .git-credentials.

overhacked commented 3 years ago

Tested. That syntax doesn't work. Still trying to figure out how to pass through a parameter that must have spaces.

overhacked commented 3 years ago

Oof. It's ugly, but this works:

GIT_CMD='eval git -c credential.helper="store --file /root/.git-credentials"'
bdrewery commented 3 years ago

Here's another fun one. Since GIT_CMD defaults to git this should work too.

git() {
    command git -c credential.helper="store --file /root/.git-credentials"
}
overhacked commented 3 years ago

Turns out git already has an undocumented environment variable config:

export GIT_CONFIG_PARAMETERS=“‘credential.helper=store --file /root/.git-credentials’”