Jenkins : Gitolite

Gitolite Architecture

Gitolite is a wrapper around a base git installation which facilitates the secure management of project repositories and of the user privileges governing access to those repositories.  Its simple configuration is well documented in a short README in the distribution.  Essentially, those sys-admins charged with administration of the central git installation clone the gitolite configuration directory, make their changes to the configuration files and push those back to origin.  A post-commit hook in the gitolite installation deploys the new configuration, creating and modifying project repositories as required and installing, revoking or updating the keys for authorized users as appropriate.

The gitolite configuration consists of conf/gitolite.conf used to define project repositories and the group and user privileges which apply to it; and a directory of ssh public keys in the form: keydir/

11:33:04 (master) ~/gitolite-admin$ ls -Rl
total 0
drwxr-xr-x 2 hesco hesco  80 Dec  8 17:48 conf
drwxr-xr-x 2 hesco hesco 208 Dec  8 17:46 keydir

total 4
-rw-r--r-- 1 hesco hesco 299 Dec  8 17:48 gitolite.conf

total 20
-rw-r--r-- 1 hesco hesco 396 Sep 30 12:12
-rw-r--r-- 1 hesco hesco 419 Dec  8 13:27
-rw-r--r-- 1 hesco hesco 397 Sep 30 12:08
-rw-r--r-- 1 hesco hesco 397 Sep 30 12:08

The security model depends on the creation of a single user with privileges over the git installation and the project repositories it hosts.  By default, this user is called git.  Only the git user may interact with the projects.  

The user privilege model is built on ssh key pairs.  Each developer or tester with need for access to a project repository hosted by gitolite generates a key pair, traditionally done using ssh-keygen, and provides their public key (.ssh/ by default) to the administrator of the repository.  The gitolite administrator then adds the public key to their cloned gitolite configuration, runs `git add keydir/` then `git commit` then `git push origin` to enable the new user.  

The syntax used in conf/gitolite.conf is documented in the linked README above.

Integrating Jenkins with Gitolite

Applying what we no know of the Gitolite architecture then requires the following steps:

generate an ssh key-pair

Generate an ssh key-pair with an empty passphrase on the jenkins server for the jenkins server

 hesco@jenkins:~$ cd /var/lib/jenkins
hesco@jenkins:/var/lib/jenkins$ sudo -u jenkins ssh-keygen
[sudo] password for hesco:
Generating public/private rsa key pair.
Enter file in which to save the key (/var/lib/jenkins/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in .ssh/id_rsa.
Your public key has been saved in .ssh/
The key fingerprint is:
The key's randomart image is:
+--[ RSA 2048]----+
|  .              |
| . o . . .       |
|  + * = +        |
|E  + B = .       |
| .    = S        |
|.     ..         |
| .     o.        |
|  o o o  .       |
|   =.. ..        |

It is important to use an empty passphrase, or the CI server will pause until it times out waiting for the entry of the passphrase.  

Next harvest that public key for the next step:

 hesco@pbx:/var/lib/jenkins$ sudo -u jenkins cat .ssh/
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA8OEjcUj . . . nPkOUXCjScyw==

create a gitolite user for jenkins

create a gitolite user for jenkins like so:

 11:52:51 (master) ~/gitolite-admin$ vim keydir/

Paste the jenkins public key into this file, ensuring that it is on a single line, collapsing line feeds if it wrapped when you pasted it into the file.  

extend privileges to the jenkins user to each relevant project repository 

Extend privileges to the jenkins user to each relevant project repository like so:

 12:04:37 (master) ~/gitolite-admin$ vim conf/gitolite.conf
@development_team = bob carol ted alice

repo gitolite-admin
    RW+     =   hesco

repo myproject
    RW+     =   hesco
    RW      =   @development_team
    R       =   jenkins

Read only privileges are sufficient to permit jenkins to clone the directory.

push changes to gitolite configuration

push changes to gitolite configuration like so:

12:13:14 {master} ~/gitolite-admin$ git add keydir/ conf/gitolite.conf

12:13:28 (master) ~/gitolite-admin$ git commit keydir/ conf/gitolite.conf
[master ba84830] Added public key for and added jenkins to myproject
 1 files changed, 5 insertions(+), 3 deletions(-)

12:13:43 (master) ~/gitolite-admin$ git push origin
Counting objects: 12, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 1.10 KiB, done.
Total 8 (delta 2), reused 0 (delta 0)

add /etc/hosts entry for git repository

If the same IP hosts both gitolite and jenkins, you next want to add an entry to /etc/hosts for the git repository on the jenkins server.

 hesco@pbx:/var/lib/jenkins$ sudo vim /etc/hosts git

add gitolite ssh fingerprint to jenkins' .ssh/known_hosts

Add the gitolite repository's ssh fingerprint to the jenkins user's .ssh/known_hosts file in their home directory on the jenkins' server like so:

hesco@jenkins:/var/lib/jenkins/workspace/myproject$ sudo -u jenkins git clone
Cloning into 'myproject'...
The authenticity of host ' (' can't be established.
RSA key fingerprint is 25:ac:4b:23:22:6c:5d:11:82:c9:4f:65:73:6a:90:0c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '' (RSA) to the list of known hosts.
remote: Counting objects: 1005, done.
remote: Compressing objects: 100% (434/434), done.
remote: Total 1005 (delta 412), reused 1005 (delta 412)
Receiving objects: 100% (1005/1005), 880.75 KiB, done.
Resolving deltas: 100% (412/412), done.

hesco@pbx:/var/lib/jenkins/workspace/myproject$ cd ..

hesco@pbx:/var/lib/jenkins/workspace$ sudo -u jenkins rmdir myproject

Make sure you clean up after the fingerprint is captured, so you are ready for the next build.  

configure the git credentials in jenkins for the Project


Configure the git credentials in Jenkins for the Project.  If the gitolite and jenkins installations are hosted at the same IP and you set up the entry in /etc/hosts, then you can use the same credentials and url as you would to clone the project in your local sandbox.  Otherwise you will need to repeat the .ssh/known_hosts step above for localhost or