go get 時にはgit cloneが動いているのでgitの設定でコントロールできる。
tl;dr
- 環境変数
GOPRIVATE=<private repository>
を設定する- 例
export GOPRIVATE=github.com/PRIVATE
- 例
- 秘密鍵などsshの設定をしたい場合は環境変数
GIT_SSH_COMMAND
を設定する- 例
export GIT_SSH_COMMAND=ssh -i ~/.ssh/id_rsa_privaterepo
- 例
git config --global url."ssh://git@github.com".insteadOf https://github.com/
を設定する
調べたこと
GOPRIVATE
golang 1.13で追加された設定値
デフォルトでsum.golang.orgにある公開のGo checksum databaseと照合して検証するが、公開していないリポジトリの場合は検証が行えずダウンロード時にエラーになる。
GOPRIVATE
に設定したパスは検証されなくなる。
httpsでアクセストークンを使ってcloneする
GitHubのprivate repositoryを含んだ場合のGo Modules管理 | おそらくはそれさえも平凡な日々
go get は通常ではhttpsのURLでcloneしようとする。
GitHubやBitbucketではアクセストークンを使ってhttpsでcloneできる。
insteadOf
でURLを上書きすることで、go get時に認証情報を使ってgit cloneされるようにできる
$ git config --global url."https://${USER}:${PERSONAL_TOKEN}@bitbucket.org/".insteadOf "https://bitbucket.org/"
$ cat ~/.gitconfig
[url "https://<user>:<token>@bitbucket.org/"]
insteadOf = https://bitbucket.org/
これだと上記のようにgitconfigにアクセストークンが書かれてしまうので、他の人も見える環境だとあまり良くない。
go getでsshの設定をする
bitbucketの例
https://bitbucket.org/
のかわりに ssh://git@bitbucket.org/
が使われるようにする
git config --global url."ssh://git@bitbucket.org/".insteadOf https://bitbucket.org/
~/.ssh/id_rsa
が存在して、公開鍵をホスティングサービス上に登録していれば、sshでgo getできる
$ ls -al ~/.ssh/id_rsa
.r-------- # 存在してpermissionが適切になっている
# 公開鍵をknown_hostsに登録していないと接続時にエラーになるため予め入れておく
$ ssh-keygen -F bitbucket.org || ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts
$ go get bitbucket.org/private-repo
=> 取得できた
ファイルがなかったり公開鍵を登録していなかったりすると Permission denied (publickey).
のエラーが出る。
秘密鍵のファイルパスを指定する
~/.ssh/id_rsa
以外の鍵を指定したい場合はさらに設定が必要となる。
~/.ssh/config
をいじる
Host bitbucket.org
IdentityFile ~/.ssh/id_rsa_privaterepo
これでgo getできた。 しかし全体の設定をいじることになるためあまりやりたくない。
core.sshCommand
を設定する
$ git config --global core.sshCommand "ssh -i ~/.ssh/id_rsa_privaterepo -F /dev/null"
これでgit clone時にはsshキーが使われたのだが、go get時にはなぜか使われなかった。。
ちなみに一時的に config 設定をしたい場合は git -c
で設定できて、普通にgit cloneするときはこれでもいい
$ git -c core.sshCommand="ssh -i ~/.ssh/id_rsa_privaterepo -F /dev/null" clone ssh://git@bitbucket.org/private.git
GIT_SSH_COMMAND
環境変数を設定する
同じことで悩んでいる人がいた。
git - How can you specify which ssh key go get
will use - Stack Overflow
GIT_SSH_COMMAND の設定は効くということだった。
export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_privaterepo -o StrictHostKeyChecking=no -F /dev/null"
実際これで指定した鍵を使ってgo getすることができた。
fatal: detected dubious ownership
エラー
共有ディレクトリに GOMODCACHE
を指定していたためにこのエラーも発生した。
Git fatal detected dubious ownership in repositoryエラー
こちらを設定した
git config --global safe.directory '*'
Jenkins上で実行する
worker上に秘密鍵を置いていない場合、credentialからssh private keyを取得して使うことになる。
まずは ~/.ssh/id_rsa
に鍵を置いてみた
pipeline {
agent {
label "worker"
}
stages {
stage('clone'){
steps {
withCredentials([sshUserPrivateKey(credentialsId: 'git_ssh_key', keyFileVariable: 'GIT_SSH_KEY')]) {
sh '''
mkdir -p ~/.ssh
cp "$BITBUCKET_SSH_KEY" ~/.ssh/id_rsa
chmod 400 ~/.ssh/id_rsa
ssh-keygen -F bitbucket.org || ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts
export GOPRIVATE='bitbucket.org'
git config --global url."ssh://git@bitbucket.org/".insteadOf https://bitbucket.org/
go get bitbucket.org/my/repo
'''
}
}
}
}
}
これでも良かったが、credentialの値を別の場所にコピーして使うというのが気持ち悪かったので、 GIT_SSH_COMMAND
を使った。
GIT_SSH_COMMAND版
pipeline {
stages {
stage('clone'){
steps {
withCredentials([sshUserPrivateKey(credentialsId: 'git_ssh_key', keyFileVariable: 'GIT_SSH_KEY')]) {
sh '''
ssh-keygen -F bitbucket.org || ssh-keyscan bitbucket.org >> ~/.ssh/known_hosts
export GIT_SSH_COMMAND="ssh -i $GIT_SSH_KEY -F /dev/null"
export GOPRIVATE='bitbucket.org'
git config --global url."ssh://git@bitbucket.org/".insteadOf https://bitbucket.org/
go get bitbucket.org/my/repo
'''
}
}
}
}
}