在Docker中调用Jenkins构建脚本中的Git

时间:2017-03-07 15:17:55

标签: git bash docker jenkins ssh

我有一个Jekyll网站(GH页面)的构建脚本,需要从脚本内部调用需要Github身份验证的git命令。这是脚本:

#!/usr/bin/env bash

rm -rf _site/

git clone git@github.com:RIT-EVT/RIT-EVT.github.io.git --branch master --depth 1 _site

LIVE_VERSION_BUILD=`cat _site/version`

LIVE_VERSION=${LIVE_VERSION_BUILD%.*}
LIVE_BUILD=${LIVE_VERSION_BUILD##*.}
PACKAGE_VERSION=`sed -nE 's/^\s*"version": "(.*?)",$/\1/p' package.json`

if [[ "$LIVE_VERSION" == "$PACKAGE_VERSION" ]]; then
    LIVE_BUILD=`expr $LIVE_BUILD + 1`
else
    LIVE_VERSION=${PACKAGE_VERSION}
    LIVE_BUILD=0
fi

rm -rf _site/*

jekyll build
echo "$LIVE_VERSION.$LIVE_BUILD" > _site/version

cd _site/
git add -A
git commit -m "v$LIVE_VERSION.$LIVE_BUILD $(date)"
git push
cd ..

我在Docker容器中运行Jenkins,这是我从docker hub中提取的。我通过添加Jenkins使用的相同私钥信息来修改容器,以执行存储库的初始克隆。但是,当我从脚本中调用git命令时,它说它未经过身份验证:

Started by user evt
Building in workspace /var/jenkins_home/workspace/Website Deploy
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url git@github.com:RIT-EVT/RIT-EVT.github.io.git # timeout=10
Fetching upstream changes from git@github.com:RIT-EVT/RIT-EVT.github.io.git
 > git --version # timeout=10
using GIT_SSH to set credentials GitHub - ssh
 > git fetch --tags --progress git@github.com:RIT-EVT/RIT-EVT.github.io.git +refs/heads/*:refs/remotes/origin/*
 > git rev-parse refs/remotes/origin/develop^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/develop^{commit} # timeout=10
Checking out Revision 85084620e62b5b03f02c610e33880eeb94b12531 (refs/remotes/origin/develop)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 85084620e62b5b03f02c610e33880eeb94b12531
 > git rev-list 85084620e62b5b03f02c610e33880eeb94b12531 # timeout=10
[Website Deploy] $ /bin/bash -xe /tmp/hudson9119924045433544873.sh
+ rm -rf _site/
+ git clone git@github.com:RIT-EVT/RIT-EVT.github.io.git --branch master --depth 1 _site
Cloning into '_site'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Build step 'Execute shell' marked build as failure
Finished: FAILURE

所以关键信息显然适用于jenkins的git插件,但无论出于何种原因,密钥都没有被容器中的git二进制文件拾取。甚至更奇怪的是我可以通过SSH连接到运行容器的机器docker exec -it jenkins bash到容器中,然后运行相同的git命令,它运行正常。

这让我觉得它可能是用户和权限的问题。所以我试图找出用户jenkins运行脚本的原因。这是我跑的非常小的脚本:

echo ${USER}
echo hello # Just a sanity test to make sure that echo works :p

这是我得到的输出:

misc. Jenkins stuff...
[Website Deploy] $ /bin/sh -xe /tmp/hudson1343134234815638946.sh
+ echo

+ echo hello
hello
Finished: SUCCESS

所以它似乎无法访问加载到ssh-agent中的密钥信息,因为脚本没有在加载密钥的同一用户下运行(?)

非常感谢任何帮助:)

更新

我运行whoami以查看是否可以在脚本中使用,并且结果显示jenkins

[Website Deploy] $ /bin/bash -xe /tmp/hudson2652666458388248519.sh
+ whoami
jenkins
Finished: SUCCESS

所以我很难过为什么git无法从ssh-agent中获取私钥。

2 个答案:

答案 0 :(得分:1)

虽然这可能对您有用,但完全可以从Jenkins上的Docker容器中调用git命令。在配置构建作业时,只需使用SSH代理插件即可。这不仅会提供Jenkins凭据存储中所需的SSH密钥,还会为您配置和设置SSH代理。

我总是建议只使用SSH密钥,因为它们更安全,更难以妥协。

此外,SSH代理插件也可以在Jenkins管道脚本中调用。只需使用 sshagent 块包装需要访问密钥的任何命令。

例如:

sshagent(credentials: ['jenkins-credential-id']) {
  sh 'git clone git@github.com:RIT-EVT/RIT-EVT.github.io.git'
  sh 'jekyll build'
}

答案 1 :(得分:0)

我弄清楚出了什么问题。如果我使用docker exec -it jenkins bash登录容器,运行eval `ssh-agent -s`启动ssh-agent,然后运行ssh-add <keyFile>,我可以在shell中运行git clone

但是,如果退出shell并通过运行相同的docker命令重新登录,则ssh-agent将无法启动并且不会加载私钥,这使我相信ssh-agent实际上并不是在Jenkins构建运行时运行。

因此,我转而使用git使用https,并使用凭据绑定插件将用户名和密码提供给repo的URL。

所以从本质上讲,你不能从Jenkins构建脚本调用git命令,并希望能够使用你的SSH密钥。