wheeler
wheeler

Reputation: 3251

Calling Git in Jenkins build script in Docker

I have a build script for a Jekyll website (GH pages) that required calling git commands that require Github authentication from inside of the script. Here is the script:

#!/usr/bin/env bash

rm -rf _site/

git clone [email protected]: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 ..

I am running Jenkins within a Docker container that I pulled from the docker hub. I modified the container by adding the same private key information used by Jenkins to perform the initial clone of the repository. However, when I call a git command from the script, it says it's unauthenticated:

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 [email protected]:RIT-EVT/RIT-EVT.github.io.git # timeout=10
Fetching upstream changes from [email protected]:RIT-EVT/RIT-EVT.github.io.git
 > git --version # timeout=10
using GIT_SSH to set credentials GitHub - ssh
 > git fetch --tags --progress [email protected]: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 [email protected]: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

So the key information is clearly working for the git plugin for jenkins, but for whatever reason, the key is not being picked up by the git binary in the container. What's even weirder is I can SSH into the machine that the container is running on, docker exec -it jenkins bash into the container, and run the same git command, and it works perfectly.

This got me thinking that it might be an issue with users and permissions. So I tried to find out what user jenkins is running the script as. Here is the very small script I ran:

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

This is the output I get:

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

+ echo hello
hello
Finished: SUCCESS

So it seems that it's not able to get access to the key information loaded into ssh-agent because the script is not being run under the same user that loaded the key(?)

Any help would be greatly appreciated :)

Update:

I ran whoami to see if that would work in the script, and it gave me jenkins as the result:

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

So I am stumped why git cannot pickup the private key from ssh-agent.

Upvotes: 2

Views: 5630

Answers (2)

Joshua
Joshua

Reputation: 11

While this may have worked for you, it is entirely possible to call git commands from within Docker containers on Jenkins. Simply use the SSH agent plugin when configuring your build job. This will not only provide the SSH key that you need from the Jenkins credential store, but it will also configure and setup the SSH agent for you.

I always suggest using only SSH keys as they are more secure and harder to compromise.

In addition, the SSH agent plugin can be invoked within a Jenkins pipeline script as well. Simply wrap any commands that need access to the key with an sshagent block.

For example:

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

Upvotes: 1

wheeler
wheeler

Reputation: 3251

I figured out what was wrong. If I logged into the container using docker exec -it jenkins bash, ran eval `ssh-agent -s` to start the ssh-agent, and ran ssh-add <keyFile>, I could run the git clone right there in the shell.

However, if exited the shell and logged back in by running the same docker command, the ssh-agent would not be started and would not have the private key loaded, which led me to believe that the ssh-agent was not actually running when the Jenkins build ran.

So, I switched to using https with git and supplying a username and password into the URL of the repo by using the credentials binding plugin.

So in essence, you cannot call git commands from Jenkins build scripts and expect to be able to use your SSH keys.

Upvotes: 1

Related Questions