Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble with auth on macOS due to SIP #40

Closed
ericphanson opened this issue Jun 9, 2021 · 35 comments · Fixed by #45
Closed

Trouble with auth on macOS due to SIP #40

ericphanson opened this issue Jun 9, 2021 · 35 comments · Fixed by #45

Comments

@ericphanson
Copy link
Contributor

If I try to clone a private repo, it prompts to ask for a username. I'd like it to auth automatically, like my command line git. I think that works because I have

credential.helper=osxkeychain

in my git config --global -l.

I can do

using Git
run(`$(git()) config --global --add credential.helper osxkeychain`)

which does set the setting correctly as I check with

julia> run(`$(git()) config --global -l`)
core.excludesfile=/Users/eph/.gitignore
core.editor=nano
user.name=Eric Hanson
user.email=5846501+ericphanson@users.noreply.github.com
credential.helper=osxkeychain
Process(setenv(`/Users/eph/.julia/artifacts/55445321

but when I try to clone a private repo, I get

julia> run(`$(git()) clone private_repo`)
Cloning into 'private'...
dyld: Library not loaded: @rpath/libgettextlib-0.20.1.dylib
  Referenced from: /Users/eph/.julia/artifacts/554453215888cc66406fca3bc8a2285995626b67/libexec/git-core/git
  Reason: image not found
error: git credential-osxkeychain get died of signal 6
Username for 'https://github.com': 

Any ideas?

@DilumAluthge
Copy link
Member

What version of Julia, and what version of Git.jl?

Also, what version of macOS?

@DilumAluthge
Copy link
Member

@giordano Any idea on this part?

dyld: Library not loaded: @rpath/libgettextlib-0.20.1.dylib
  Referenced from: /Users/eph/.julia/artifacts/554453215888cc66406fca3bc8a2285995626b67/libexec/git-core/git
  Reason: image not found

@ericphanson
Copy link
Contributor Author

Julia v1.6.1, Git v1.2.1, MacOS v11.2.3 (Big Sur)

@DilumAluthge
Copy link
Member

DilumAluthge commented Jun 9, 2021

What do you get when you run git credential-osxkeychain in a terminal?

And then what do you get when you run this in Julia:

run(`$(git()) credential-osxkeychain`)

@giordano
Copy link
Member

giordano commented Jun 9, 2021

@giordano Any idea on this part?

What's the version of Gettext_jll?

@ericphanson
Copy link
Contributor Author

In Julia:

julia> run(`$(git()) credential-osxkeychain`)
git: 'credential-osxkeychain' is not a git command. See 'git --help'.
ERROR: failed process

In the terminal:

❯ git credential-osxkeychain
usage: git credential-osxkeychain <get|store|erase>

@ericphanson
Copy link
Contributor Author

(jl_MgOS5U) pkg> st -m
      Status `/private/var/folders/jb/plyyfc_d2bz195_0rc0n_zcw0000gp/T/jl_MgOS5U/Manifest.toml`
  [d7ba0133] Git v1.2.1
  [692b3bcd] JLLWrappers v1.3.0
  [21216c6a] Preferences v1.2.2
  [2e619515] Expat_jll v2.2.10+0
  [78b55507] Gettext_jll v0.20.1+7
  [f8c6e375] Git_jll v2.31.0+0
  [94ce4f54] Libiconv_jll v1.16.1+0
  [458c3c95] OpenSSL_jll v1.1.10+0
  [02c8fc9c] XML2_jll v2.9.12+0

plus stdlibs

@giordano
Copy link
Member

giordano commented Jun 9, 2021

I can't reproduce it:

julia> run(`$(git()) clone https://github.com/giordano/private.git`);
Cloning into 'private'...
Username for 'https://github.com': giordano
Password for 'https://[email protected]':
remote: Enumerating objects: 133, done.
remote: Counting objects: 100% (133/133), done.
remote: Compressing objects: 100% (87/87), done.
remote: Total 133 (delta 79), reused 96 (delta 42), pack-reused 0
Receiving objects: 100% (133/133), 68.81 KiB | 2.87 MiB/s, done.
Resolving deltas: 100% (79/79), done.

shell> rm -rf private/

julia> run(`$(git()) clone [email protected]:giordano/private.git`);
Cloning into 'private'...
Enter passphrase for key '/Users/mose/.ssh/id_ed25519':
remote: Enumerating objects: 133, done.
remote: Counting objects: 100% (133/133), done.
remote: Compressing objects: 100% (87/87), done.
remote: Total 133 (delta 79), reused 96 (delta 42), pack-reused 0
Receiving objects: 100% (133/133), 68.81 KiB | 1.01 MiB/s, done.
Resolving deltas: 100% (79/79), done.

I don't have an SSH agent set up yet, though, if that's relevant

@GunnarFarneback
Copy link
Contributor

GunnarFarneback commented Oct 25, 2021

I get the

dyld: Library not loaded: @rpath/libgettextlib-0.20.1.dylib
  Referenced from: /Users/runner/.julia/artifacts/554453215888cc66406fca3bc8a2285995626b67/libexec/git-core/git-receive-pack
  Reason: image not found

message when I try to use Git.jl in LocalRegistry, see https://github.com/GunnarFarneback/LocalRegistry.jl/runs/3993508587?check_suite_focus=true. There are no secrets or credentials involved there, the failure happens in a push to a local file:// URL. Can someone make sense of it? (The tests run with a switched DEPOT, but I see nothing in the error messages that indicates that this would be the problem.)

@giordano
Copy link
Member

What's the value of Git_jll.LIBPATH_list? What's the version of Gettext_jll?

@GunnarFarneback
Copy link
Contributor

  [78b55507] Gettext_jll v0.20.1+7

LocalRegistry.Git.Git_jll.LIBPATH_list = ["/Users/runner/hostedtoolcache/julia/1.6.3/x64/lib/julia", 
"/Users/runner/.julia/artifacts/d3cdfef027f1989b22b9b8b540872339aa1e2cbc/lib", 
"/Users/runner/.julia/artifacts/5ebe398d0866c7cb913e36f6061f7e4f4495e3c7/lib", 
"/Users/runner/.julia/artifacts/571cdee3242d2dddfc82ce9b2b9a25ba523c78e9/lib", 
"/Users/runner/.julia/artifacts/177d0c3c85c9de270494ca5bb483d7a6d15b3ee8/lib", 
"/Users/runner/.julia/artifacts/ec7ccd15172f5e13c4fb3a9499b2e4eccb5c1830/lib"]

@giordano
Copy link
Member

Uhm, ec7ccd15172f5e13c4fb3a9499b2e4eccb5c1830 is the macOS artifact for Gettext_jll v0.20.1+7 🤔

Can you reproduce the error locally, or it's only in CI?

@GunnarFarneback
Copy link
Contributor

The CI passes for Linux and Windows but fails for macOS. Unfortunately I don't have any access to macOS for testing locally.

@giordano
Copy link
Member

Do you have a simple reproducer I could try (besides running all the tests)?

@GunnarFarneback
Copy link
Contributor

You can start to see if the tests fail locally for LocalRegistry#git_jll. If not it's a CI only thing. If they do I can try to reduce it via CI.

@giordano
Copy link
Member

I fear git is doing something fishy here:

mose@Moses-MacBook-Pro ~ % /Users/mose/.julia/artifacts/554453215888cc66406fca3bc8a2285995626b67/libexec/git-core/git-receive-pack
dyld: Library not loaded: @rpath/libgettextlib-0.20.1.dylib
  Referenced from: /Users/mose/.julia/artifacts/554453215888cc66406fca3bc8a2285995626b67/libexec/git-core/git-receive-pack
  Reason: image not found
zsh: abort
mose@Moses-MacBook-Pro ~ % DYLD_FALLBACK_LIBRARY_PATH=$(julia-16 -E 'using Git_jll; Git_jll.LIBPATH[]') /Users/mose/.julia/artifacts/554453215888cc66406fca3bc8a2285995626b67/libexec/git-core/git-receive-pack
fatal: You must specify a directory.

usage: git receive-pack <git-dir>

    -q, --quiet           quiet

It looks like git is internally calling libexec/git-core/git-receive-pack but somehow shadowing the value of DYLD_FALLBACK_LIBRARY_PATH

@giordano
Copy link
Member

giordano commented Oct 25, 2021

A small reproducer (the high-level git command run) would still be helpful though 🙂

@GunnarFarneback
Copy link
Contributor

Not exactly small but this is enough to trigger the error in CI and should let you eliminate LocalRegistry from the equation.

dir1 = mktempdir()
git1 = LocalRegistry.Git.git(["-C", dir1, "-c", "user.name=a", "-c", "user.email=b@c"])
url1 = "file://$dir1"
dir2 = mktempdir()
git2 = LocalRegistry.Git.git(["-C", dir2, "-c", "user.name=a", "-c", "user.email=b@c"])
run(`$git1 init --bare`)
run(`$git2 init`)
write(joinpath(dir2, "README"), "test")
run(`$git2 add --all`)
run(`$git2 commit -qm test`)
run(`$git2 remote add origin $url1`)
run(`$git2 push --set-upstream origin master`)

@giordano
Copy link
Member

giordano commented Oct 25, 2021

Ok, that's perfect, thanks!

I translated that to a simple shell script

#!/bin/sh

set -euf -o pipefail

export DYLD_FALLBACK_LIBRARY_PATH="$(julia-16 -E 'using Git_jll; Git_jll.LIBPATH[]')"
GIT="$(julia-16 -e 'using Git_jll; print(Git_jll.git_path)')"

dir1=$(mktemp -d)
url1="file://${dir1}"
dir2=$(mktemp -d)
"${GIT}" -C "${dir1}" -c "user.name=a" -c "user.email=b@c" init --bare
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" init
echo "test" > "${dir2}/README"
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" add --all
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" commit -qm test
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" remote add origin "${url1}"
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" push --set-upstream origin master

but unfortunately now this one doesn't reproduce the failure:

mose@Moses-MacBook-Pro tmp % ./git.sh
warning: templates not found in /workspace/destdir/share/git-core/templates
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: 	git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: 	git branch -m <name>
Initialized empty Git repository in /private/var/folders/v2/hmy3kzgj4tb3xsy8qkltxd0r0000gn/T/tmp.YHxZbGQQ/
warning: templates not found in /workspace/destdir/share/git-core/templates
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: 	git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: 	git branch -m <name>
Initialized empty Git repository in /private/var/folders/v2/hmy3kzgj4tb3xsy8qkltxd0r0000gn/T/tmp.EnE1XJfk/.git/
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 190 bytes | 190.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To file:///var/folders/v2/hmy3kzgj4tb3xsy8qkltxd0r0000gn/T/tmp.YHxZbGQQ
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

I can't debug further now, but leaving some breadcrumbs here for future reference

@giordano
Copy link
Member

Ok, I had to set some extra environment variables to reproduce the error

#!/bin/sh

set -euf -o pipefail

export DYLD_FALLBACK_LIBRARY_PATH="$(julia-16 -e 'using Git_jll; print(Git_jll.LIBPATH[])')"
GIT_DIR="$(julia-16 -e 'using Git_jll; print(Git_jll.artifact_dir)')"
GIT="${GIT_DIR}/bin/git"
export GIT_EXEC_PATH="${GIT_DIR}/libexec/git-core"
export GIT_TEMPLATE_DIR="${GIT_DIR}/share/git-core/templates"
export GIT_SSL_CAINFO="$(julia-16 -e 'print(dirname(Sys.BINDIR))')/share/julia/cert.pem"

dir1=$(mktemp -d)
url1="file://${dir1}"
dir2=$(mktemp -d)
"${GIT}" -C "${dir1}" -c "user.name=a" -c "user.email=b@c" init --bare
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" init
echo "test" > "${dir2}/README"
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" add --all
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" commit -qm test
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" remote add origin "${url1}"
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" push --set-upstream origin master

output

mose@Moses-MacBook-Pro tmp % ./git.sh
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: 	git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: 	git branch -m <name>
Initialized empty Git repository in /private/var/folders/v2/hmy3kzgj4tb3xsy8qkltxd0r0000gn/T/tmp.abYaa1to/
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: 	git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: 	git branch -m <name>
Initialized empty Git repository in /private/var/folders/v2/hmy3kzgj4tb3xsy8qkltxd0r0000gn/T/tmp.PKK9TZUK/.git/
dyld: Library not loaded: @rpath/libgettextlib-0.20.1.dylib
  Referenced from: /Users/mose/.julia/artifacts/554453215888cc66406fca3bc8a2285995626b67/libexec/git-core/git-receive-pack
  Reason: image not found
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

@mortenpi
Copy link

mortenpi commented Jun 2, 2022

With Mose's help, I've been digging into this a little. I ran into what's probably a related issue, where calling git submodule leads to the following on GitHub Actions runners:

dyld: lazy symbol binding failed: Symbol not found: _libiconv_open
  Referenced from: /Users/runner/.julia/artifacts/fc4adbf1d7551761c1693502d0b221eb0f780b59/libexec/git-core/git
  Expected in: /usr/lib/libiconv.2.dylib

dyld: Symbol not found: _libiconv_open
  Referenced from: /Users/runner/.julia/artifacts/fc4adbf1d7551761c1693502d0b221eb0f780b59/libexec/git-core/git
  Expected in: /usr/lib/libiconv.2.dylib

The culprit appears to be Mac's SIP, together with the fact that Git loves to start all kinds of child processes, including sh and perl. In the submodule case, the subcommand is actually a shell script. However, by design, SIP purges the DYLD_FALLBACK_LIBRARY_PATH variable from the enviroment when Git calls /bin/sh. But then git-submodule.sh tries to call git again, and it, of course, can't find the shared libraries.

I was able to get submodule working by by setting SIPHACK_DYLD_FALLBACK_LIBRARY_PATH in Julia, and then patching the submodule script with export DYLD_FALLBACK_LIBRARY_PATH=$SIPHACK_DYLD_FALLBACK_LIBRARY_PATH. That variable gets passed through to sh.

As for the issue here, it seems reasonable that, somehow, when e.g. git clone calls git-receive-pack, there is also an intermediate step where SIP purges DYLD_*s. However, it doesn't look like there are any shell scripts involved, so I am not entirely sure where that happens, but it does look like git likes to also construct sh calls internally (and not just execute external shell scripts).

At the moment I can think of two solutions:

  1. Patch the shell scripts (also the Perl ones I guess..) when building Git_jll for Mac, to use the variable workaround. Although this won't help with the other cases reported here.
  2. Bundle the necessary .dylibs in the lib/ directory of the Git_jll. This seems to fix both issues.

I also have some scripts here that I used to debug and test stuff on CI, including simple implementations of the two oh-so-pretty workarounds.

@staticfloat
Copy link
Contributor

staticfloat commented Feb 15, 2023

I have attempted to take Mosè's script and translate it to Julia:

using Git
gitd(dir, cmd) = run(`$(git()) -C $(dir) -c "user.name=a" -c "user.email=b@c" $(cmd)`)
mktempdir() do dir1; mktempdir() do dir2;
    gitd(dir1, `init --bare`)
    gitd(dir2, `init`)
    open(joinpath(dir2, "README"); write=true) do io
        println(io, "test")
    end
    gitd(dir2, `add --all`)
    gitd(dir2, `commit -qm test`)
    gitd(dir2, `remote add origin file://$(dir1)`)
    gitd(dir2, `push --set-upstream origin main`)
end; end

This works just fine for me, does it work for everyone else?

@DilumAluthge
Copy link
Member

Is SIP enabled on your Mac?

@DilumAluthge
Copy link
Member

Also, did you set the additional environment variables listed in #40 (comment)?

@DilumAluthge
Copy link
Member

I needed to edit your script - I changed the penultimate line to this:

    gitd(dir2, `push --set-upstream origin master`)

When I did so, it failed for me with:

dyld: Library not loaded: @rpath/libgettextlib-0.21.dylib
  Referenced from: /Users/dilum/.julia/artifacts/fc4adbf1d7551761c1693502d0b221eb0f780b59/libexec/git-core/git-receive-pack
  Reason: image not found

I have SIP enabled on this Mac. I did not set the additional environment variables listed in #40 (comment).

Full output: (click to expand)
julia> mktempdir() do dir1; mktempdir() do dir2;
           gitd(dir1, `init --bare`)
           gitd(dir2, `init`)
           open(joinpath(dir2, "README"); write=true) do io
               println(io, "test")
           end
           gitd(dir2, `add --all`)
           gitd(dir2, `commit -qm test`)
           gitd(dir2, `remote add origin file://$(dir1)`)
           gitd(dir2, `push --set-upstream origin master`)
       end; end
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: 	git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: 	git branch -m <name>
Initialized empty Git repository in /private/var/folders/yf/1bpklfv955vdhc4fmvll26c40000gp/T/jl_obS1Mb/
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: 	git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: 	git branch -m <name>
Initialized empty Git repository in /private/var/folders/yf/1bpklfv955vdhc4fmvll26c40000gp/T/jl_Jm6hud/.git/
dyld: Library not loaded: @rpath/libgettextlib-0.21.dylib
  Referenced from: /Users/dilum/.julia/artifacts/fc4adbf1d7551761c1693502d0b221eb0f780b59/libexec/git-core/git-receive-pack
  Reason: image not found
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
ERROR: failed process: Process(setenv(`/Users/dilum/.julia/artifacts/fc4adbf1d7551761c1693502d0b221eb0f780b59/bin/git -C /var/folders/yf/1bpklfv955vdhc4fmvll26c40000gp/T/jl_Jm6hud -c user.name=a -c user.email=b@c push --set-upstream origin master`,["XPC_FLAGS=0x0", "PATH=/Users/dilum/.julia/artifacts/3bb83a2812f716f0d1610026d1e470dbf92a952e/bin:/Users/dilum/.julia/artifacts/a7bbbe8a0c64cb275b1f3a526f339accb1888b94/bin:/Users/dilum/.julia/artifacts/0c9c721045741232851be4413320f4fbc87949ba/bin:/Users/dilum/.julia/artifacts/fc4adbf1d7551761c1693502d0b221eb0f780b59/bin:/Users/dilum/.asdf/installs/julia/1.8.4/bin:/Users/dilum/.asdf/shims:/Users/dilum/.asdf/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin", "COMMAND_MODE=unix2003", "PWD=/Users/dilum/Downloads", "XPC_SERVICE_NAME=0", "TERM_PROGRAM=iTerm.app", "GIT_EXEC_PATH=/Users/dilum/.julia/artifacts/fc4adbf1d7551761c1693502d0b221eb0f780b59/libexec/git-core", "SHELL=/bin/bash", "DYLD_FALLBACK_LIBRARY_PATH=/Users/dilum/.asdf/installs/julia/1.8.4/lib/julia:/Users/dilum/.julia/artifacts/3bb83a2812f716f0d1610026d1e470dbf92a952e/lib:/Users/dilum/.julia/artifacts/a7bbbe8a0c64cb275b1f3a526f339accb1888b94/lib:/Users/dilum/.julia/artifacts/47a0441fc4c0611720643ad5cb10ad0fbf263c54/lib:/Users/dilum/.julia/artifacts/0c9c721045741232851be4413320f4fbc87949ba/lib:/Users/dilum/.julia/artifacts/397fee52d94fc3404c3e466a6a8277ad9fdde715/lib:/Users/dilum/.asdf/installs/julia/1.8.4/bin/../lib/julia:/Users/dilum/.asdf/installs/julia/1.8.4/bin/../lib:/Users/dilum/lib:/usr/local/lib:/lib:/usr/lib", "__CF_USER_TEXT_ENCODING=0x1F6:0x0:0x0"  …  "GIT_TEMPLATE_DIR=/Users/dilum/.julia/artifacts/fc4adbf1d7551761c1693502d0b221eb0f780b59/share/git-core/templates", "BASH_SILENCE_DEPRECATION_WARNING=1", "USER=dilum", "ITERM_SESSION_ID=w0t0p0:088C3CC7-9B3D-43B0-9CE1-8F72EEBC5EDB", "ASDF_DIR=/Users/dilum/.asdf", "HOME=/Users/dilum", "TERM=xterm-256color", "TERM_PROGRAM_VERSION=3.4.19", "GIT_SSL_CAINFO=/Users/dilum/.asdf/installs/julia/1.8.4/share/julia/cert.pem", "COLORTERM=truecolor"]), ProcessExited(128)) [128]

Stacktrace:
  [1] pipeline_error
    @ ./process.jl:565 [inlined]
  [2] run(::Cmd; wait::Bool)
    @ Base ./process.jl:480
  [3] run
    @ ./process.jl:477 [inlined]
  [4] gitd
    @ ./REPL[4]:1 [inlined]
  [5] (::var"#26#29"{String})(dir2::String)
    @ Main ./REPL[5]:10
  [6] mktempdir(fn::var"#26#29"{String}, parent::String; prefix::String)
    @ Base.Filesystem ./file.jl:764
  [7] mktempdir (repeats 2 times)
    @ ./file.jl:760 [inlined]
  [8] #25
    @ ./REPL[5]:1 [inlined]
  [9] mktempdir(fn::var"#25#28", parent::String; prefix::String)
    @ Base.Filesystem ./file.jl:764
 [10] mktempdir(fn::Function, parent::String) (repeats 2 times)
    @ Base.Filesystem ./file.jl:760
 [11] top-level scope
    @ REPL[5]:1

@DilumAluthge DilumAluthge changed the title Trouble with auth Trouble with auth on macOS (likely due to SIP) Feb 15, 2023
@GunnarFarneback
Copy link
Contributor

I have attempted to take Mosè's script and translate it to Julia:

Are we going full circle? Julia was the starting point: #40 (comment)

@GunnarFarneback
Copy link
Contributor

I don't have a Mac to try on but the GitHub runners keep failing with GunnarFarneback/LocalRegistry.jl#38, from which this testcase was derived.

@staticfloat
Copy link
Contributor

staticfloat commented Feb 16, 2023

@giordano can you try this in your Git_jll artifact and tell me if it works for you?

# Move C binary to `_git`
mv git _git

# Create new `git` wrapper script:
cat >git << 'EOF'
#!/bin/bash

SCRIPT_DIR=$( cd -- "$( dirname -- $(readlink -f "${BASH_SOURCE[0]}") )" &> /dev/null && pwd )
export DYLD_FALLBACK_LIBRARY_PATH="${JLL_DYLD_FALLBACK_LIBRARY_PATH}"
exec -a "${BASH_SOURCE[0]}" "${SCRIPT_DIR}/_git" "$@"
EOF

chmod +x git

For me, this passes on a SIP-enabled mac. The important two pieces here are:

  • Re-convert from JLL_DYLD_* environment variable to DYLD_* at the git entrypoint, as pretty much all tools invoke that top-level entrypoint.
  • Use exec -a <name> to pass the argv[0] name through properly, as that's how git understands which mode it should be running in.

Are we going full circle? Julia was the starting point:

Hah, I saw LocalRegistry. and immediately blanked out the rest, thinking it was using some internal functionality, not just reaching inside to get the Git.jl functions. :P

@giordano
Copy link
Member

giordano commented Feb 16, 2023

Yes, with the proposed changes this updated shell script works for me:

#!/bin/sh

set -euf -o pipefail

JULIA="julia --project=/tmp"
export JLL_DYLD_FALLBACK_LIBRARY_PATH="$(${JULIA} -e 'using Git_jll; print(Git_jll.LIBPATH[])')"
GIT="$(${JULIA} -e 'using Git_jll; print(Git_jll.git_path)')"

dir1=$(mktemp -d)
url1="file://${dir1}"
dir2=$(mktemp -d)
"${GIT}" -C "${dir1}" -c "user.name=a" -c "user.email=b@c" init --bare
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" init
echo "test" > "${dir2}/README"
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" add --all
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" commit -qm test
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" remote add origin "${url1}"
"${GIT}" -C "${dir2}" -c "user.name=a" -c "user.email=b@c" push --set-upstream origin main
% ./test.sh
warning: templates not found in /workspace/destdir/share/git-core/templates
Initialized empty Git repository in /private/var/folders/v2/hmy3kzgj4tb3xsy8qkltxd0r0000gn/T/tmp.wLhmC0XD/
warning: templates not found in /workspace/destdir/share/git-core/templates
Initialized empty Git repository in /private/var/folders/v2/hmy3kzgj4tb3xsy8qkltxd0r0000gn/T/tmp.xu3TRY8B/.git/
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 189 bytes | 189.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To file:///var/folders/v2/hmy3kzgj4tb3xsy8qkltxd0r0000gn/T/tmp.wLhmC0XD
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

And also your Julia code works, unchanged.

@giordano
Copy link
Member

It works for me also if I don't rename the git executable and call the shell script git.sh, it doesn't look like we need to pass again through the shell driver.

It isn't entirely clear to me why we can't just set the environment variable and avoid using the shell driver.

@staticfloat
Copy link
Contributor

It works for me also if I don't rename the git executable and call the shell script git.sh, it doesn't look like we need to pass again through the shell driver.

I don't think that will work in all cases. The breaking case is when we have something like git calls /bin/sh -c "${libexec}/git-receive-pack"; this will call /bin/sh, which drops DYLD_* environment variables, then call git-receive-pack (which is a symlink back to git), which will freak out because it can't find its libraries. To fix this, I made all of the symlinks point to a shell script which will always restore the environment variables before invoking the true executable, so that no matter what internal path execution takes, it will always pass through that shell script before invoking the core executable.

@giordano
Copy link
Member

giordano commented Feb 16, 2023

Ah, I don't need your shell driver if I set both JLL_DYLD_FALLBACK_LIBRARY_PATH and DYLD_FALLBACK_LIBRARY_PATH:

export DYLD_FALLBACK_LIBRARY_PATH="$(${JULIA} -e 'using Git_jll; print(Git_jll.LIBPATH[])')"
export JLL_DYLD_FALLBACK_LIBRARY_PATH="${DYLD_FALLBACK_LIBRARY_PATH}"

@staticfloat
Copy link
Contributor

staticfloat commented Feb 16, 2023

Are you sure you're testing the right case? In your code snippet above you're not even setting JLL_DYLD_FALLBACK_LIBRARY_PATH to a valid path, you're setting it to the string "DYLD_FALLBACK_LIBRARY_PATH".

@giordano
Copy link
Member

Yes, sorry, that was a copy-paste error, but it was really working for me. Anyway, in JuliaPackaging/Yggdrasil#4987 I'm now creating the shell driver you suggested, I downloaded the artifact built in CI, installed in my artifact dir and now Git.jl works out-of-the-box. If you can review it maybe we can go.

@giordano
Copy link
Member

giordano commented Feb 16, 2023

This isn't enough for credential-osxkeychain though: JuliaPackaging/Yggdrasil#4987 (comment) 😕 Edit: false alarm.

@DilumAluthge DilumAluthge changed the title Trouble with auth on macOS (likely due to SIP) Trouble with auth on macOS due to SIP) Feb 17, 2023
@DilumAluthge DilumAluthge changed the title Trouble with auth on macOS due to SIP) Trouble with auth on macOS due to SIP Feb 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants