Setting up a Centralized Git Service

Your company wants a centralized code repository, and you like git.  Git is not normally centralized, although neat services like GitHub are out there.  While GitHub is awesome, and I use it (and so should any developer that would like to do work that is public or otherwise), the affordable multiseat license that is online is, well, online, and the multiseat license that you can get for offline work is really expensive.  Some smaller organizations might scoff at this, some for understandable reasons, others less so, but I’m not here to get into those symantics.  What I want to do is describe how you can get something up and running that has a centralized git service that might work a lot like GitHub, although it might be missing some of its nicer features (but it might have some other features you might like).  For this first post, we are going to set up gitolite and get it running the kind of hard/kind of easy way.  In later posts, I’ll add in front ends that will make accessing and using gitolite easier.

Edit: This is the first in a four part series about gitolite and Redmine, ending with full automation. The other articles are:

Ok, let’s continue…

Gitolite, available at https://github.com/sitaramc/gitolite in its rawest form, is one way to get it, also this can be done using apt-get in Ubuntu.  Doing things the hard way is often the best, and will give you the most understanding, and then meandering down the road to the easy way later on will make you very effective if you have to do it the hard way later.  Just like those damn Calculus classes that you took in college, or not if that isn’t what tickled your fancy.  What we are going to do then, is build this from scratch, do a full installation of it, and go through step by step.  Perhaps, if it tickles my fancy, I’ll produce the ‘easy’ way later, and you can decide what you want to do.

I would suggest that you do all practice work in a VM.  The easy way is to get an Ubuntu 12.04 ISO and VirtualBox and get that up and running.  KVM is good, but I think it’s a little harder.  I can cover that later.  Either way, get onto a box where you have sudo access and get ready to do some real work.

Now let’s pretend that you have little to no idea what you are doing (hell, I have no idea what I’m doing most of the time anyhow).  The reality is, the vast majority of our work is guesswork and the vast majority of the time, we don’t have time to figure out the ins and outs of every little thing that we put into place in any one organization.  I’ll try to make sure that I put up appropriate headers for all of the actions that I am taking so that parts can be skipped over.  If you want to do this the easy way, you can wait for me to throw up an easy tutorial, or you can look for another online (especially one with redmine integration, which you can find around).

The hard way of getting gitolite up and running is to complete the following steps:

  1. Create the necessary gitolite user and appropriate home directories for storing the repositories.
  2. Download gitolite.
  3. Install gitolite.
  4. Create an ssh key for the administration of gitolite.
  5. Initialize gitolite with new repositories and the created ssh key.
  6. Create a new user ssh key.
  7. Install the user ssh key with gitolite, and create your first repository.
  8. Modify the repository with the user key.

After all of these steps, you will have a difficult to work with centralized git repository.  I shouldn’t say that it is necessary difficult, as much as I mean that the creation of new users who can use the centralized repos isn’t easily automated, like it would be if you set up a redmine plugin or had a GitHub account (once again the easiest solution).  I should stop here and say – if you are just somebody who is writing something up that they want to make public someday, just go ahead and start on GitHub now instead.  Nobody is going to look at it when it isn’t good, and it is likely nobody will see it when it is either.  You shouldn’t care, really.  Heck, if someone does notice and likes the idea, perhaps they’ll start helping you out on it and you’ll have a excellent repo and an item for your development portfolio.  Don’t be shy, don’t be embarrassed, just do it.  There are only a couple of good reasons that you should complete this tutorial and use private repos:

  1. You never plan on making your code public.
  2. You are working for an organization that needs their code to be private.
  3. Dropbox is not a viable alternative for storing your repo (more than one person working on it).
  4. A simple localized repo is just not good enough for you.

OK, I’ve spoken my peace and you still want gitolite.  That’s fine, I just wanted to make absolutely positive first.

Get onto your server and get your sudo commands ready for execution, because we’re about to cook a turkey.

Create the gitolite user

The gitolite user that we will create will end up having the same home directory location as if we had set it up using dpkg-reconfigure in Ubuntu: /var/lib/gitolite/ (sorry if you don’t know what I mean by dpkg-reconfigure.  In a future tutorial using apt-get I’ll make more sense of it).  Here is the command that we will use to create the user:

$ sudo useradd gitolite --home-dir=/var/lib/gitolite/ --create-home --shell=/bin/bash

This command basically says that it will create a user gitolite, without a password (because we didn’t create one), with the home directory /var/lib/gitolite/, created now, and using the shell bash.  If you are unfamiliar with all of this, you should spend some time with the man page for useradd.  If you don’t know how to access a man page, I’m starting to think you should probably pick up the Ubuntu Server Book now and spend some time with it, or if you are cheap or uneasy with that, use the following command:

$ man useradd

For more information about adding users to a server.

Download Gitolite

Gitolite is sourced on, well, what else? GitHub. There is almost irony there, but I’m not really sure. The entire concept of irony and when something is and isn’t irony really confuses me, but I digress.

If you are working on an Ubuntu box, and you don’t have git installed, then now you need to install it so that you can get the source code. If you are on an Ubuntu server, then this would look something like:

$ sudo apt-get install git-core

And now git commands should start working. Installing git for other systems is outside the scope of this tutorial. I mean, really, I have to draw the line someplace. Now, we need to find the download link for gitolite. Starting at the url listed earlier: https://github.com/sitaramc/gitolite, we will notice the read only access links https://github.com/sitaramc/gitolite.git and git://github.com/sitaramc/gitolite.git.  Either of these should be fine.  We will clone one using:

$ git clone git://github.com/sitaramc/gitolite.git

This will create a new directory ‘gitolite’ with all of the gitolite goodness in it.

Install Gitolite

There is a quick install/setup guide here: http://sitaramc.github.com/gitolite/qi.html that you can look at. Unfortunately, it doesn’t have a ton of detail. I went ahead and took a chance and ran:

$ gitolite/install --help

And got a big list of output that you might even want to look at yourself. I won’t post it here because I’m lazy, but because I don’t want you to be lazy. Either way, after trying to work out the command, I eventually stumbled through the docs to this: https://github.com/sitaramc/gitolite/blob/master/doc/install.mkd and ended up running the following:

$ sudo gitolite/install -ln /usr/local/bin

Now I guess that gitolite is ‘installed’, as now there is a new file /usr/local/bin/gitolite in that directory.

The next part of the setup is having the user gitolite setup the initial repositories for administration of gitolite. The gitolite user, created without a password, can be accessed via sudo:

$ sudo su - gitolite

As this user, we need to run the setup commands for gitolite. But before we do so, we need to have access to a private/public key pair. If you know what this is, then skip the following section. If not, please read on.

Create an SSH key for administration of gitolite

Most requests for information from repositories using git involve the use of ssh. It is arguably the most secure way to get at that repository as well. Herein lies a problem, though, as well: the user that administers git under gitolite (and others for that matter) is always the same person for all of the repositories. This means that if I have repository ‘psalcido’ under user ‘gitolite’ and I want to give someone else access to that same repository, I need to give them access to the gitolite password to log in to get at the repo. No good. Especially because gitolite doesn’t even have a password, so how can it be accessed from elsewhere?

Well, we have one answer: create a user with sudo access on the same box and use sudo su - gitolite but that isn’t going to help us with anything automated, just like pulls from gitolite will have to be. Thus we need to use ssh key pairs. What ssh key pairs do is allow you, from a given computer with the private half of a given key pair, to login as a user on another computer where they have decided to authorize the use of that key by installing the public key. Basically, the authorized_keys file on the server is the lock, and your private key is the key. The user on the server can accept many keys on their lock, but the only way that you can get your key to work in that lock is by getting your key authorized first. Thus, anyone that is going to want to do administrative work on gitolite will have to get access to the private key in this case.

If you are new to ssh keys, just remember to protect your private key, and/or password protect it.

For this tutorial, we are going to make an unencrypted private key, which means you won’t have to enter a password to use it. You can encrypt the key here, but then that same key can’t be used by most administrative consoles.

Now, as user gitolite, run the following:

$ ssh-keygen

And accept all of the defaults, and nothing for the passwords, and you will have an unencrypted key pair in /var/lib/gitolite/.ssh in the files id_rsa.pub (the public key) and id_rsa (the private key).

Way too much explanation for something that simple.

Initialize gitolite with new repositories

Now we need to initialize gitolite. I tried to do this immediately here, with the command:

$ gitolite setup -pk /var/lib/gitolite/.ssh/is_rsa.pub

And I ended up with the following:

Initialized empty Git repository in /var/lib/gitolite/repositories/gitolite-admin.git/
Initialized empty Git repository in /var/lib/gitolite/repositories/testing.git/
WARNING: /var/lib/gitolite//.ssh/authorized_keys missing; creating a new one

Which is resolved simply enough with:

$ touch ~/.ssh/authorized_keys
$ chmod 0600 ~/.ssh/authorized_keys

Which creates the ‘lock’ mentioned in the previous section about creating ssh keys. Now we run the same setup command again and get:

$ gitolite setup -pk /var/lib/gitolite/.ssh/id_rsa.pub

And now we see no output, because the base setup repositories have already been created in the actions above, so we are very much in the clear and ready to move on.  I’m not going to spend a huge amount of time here, but you might want to view the file ~/.ssh/authorized_keys, as I learned a ton about the file by looking at it after having this setup run (actually, back when gitosis was the standard, I caught it, but still, basically the same game).

Create a new user ssh key

Your main user for this VM is going to need the ability to do work on a new repository. We’re going to set them up with a new ssh key pair and get that key installed for use in gitolite. My user is psalcido, but yours is probably someone different. I’m going to write up this section and when you see psalcido$ or gitolite$, you should be able to tell who is running what.

First, I’m going to create a key pair for my user:

psalcido$ ssh-keygen

You may choose whatever options you like in this case. Now, I need to make the public key available to gitolite. Please note that nobody (except root) can look in my .ssh directory. If you open up permissions on your .ssh directory, then ssh will refuse to use it. Due to this, gitolite can’t see the public key. Thus, I’m going to move it someplace where it can be seen by everyone, and gitolite, then make sure users have permissions to open the file using chmod (see $ man chmod for more information). Nobody can harm you by having access to your public key, but please keep your private key safe.

psalcido$ cp ~/.ssh/id_rsa.pub /tmp/psalcido_id_rsa.pub
psalcido$ chmod 0666 /tmp/psalcido_id_rsa.pub

Install the user ssh key with gitolite, and create your first repository

Now that we have gitolite all set up, the actual way that you add users to gitolite is by cloning the gitolite administrative repository and doing the necessary modifications to it. It will then setup everything that it needs to automagically. Of course, that is unfair to leave at that, but there is a significant amount of documentation already out there to help you in what it does and how that works in the gitolite GitHub repository (are you sure you don’t want to just go ahead and use GitHub yet? Just checking).

Currently, the only user that has gitolite administrative access is the user gitolite. Log in as gitolite, and run the following:

gitolite$ git clone gitolite@localhost:gitolite-admin.git

And with that you should have the admin repository in the gitolite home directory. Under this directory, you will see the following files:

  • keydir/
    • id_rsa.pub
  • conf/
    • gitolite.conf

The data in gitolite.conf looks like:

repo gitolite-admin
    RW+     =   id_rsa

repo testing
    RW+     =   @all

What this basically says is that anyone who has the private key for id_rsa.pub can modify gitolite-admin (in this case, that is only the user gitolite on the local box), and anyone who has a key match for any repository can modify the repository ‘testing’. Here, we will set up a new repo ‘psalcido’, install the new key, and give the key psalcido_id_rsa permission to view the data in the new repository. We will add on the following lines at the end of the file gitolite.conf:

repo psalcido
    RW+     =   psalcido_id_rsa

Then we will add the key from /tmp/ to the repository under the key directory:

gitolite$ cp /tmp/psalcido_id_rsa.pub ~/gitolite-admin/keydir/psalcido_id_rsa.pub

A git status for the gitolite-admin clone should now return:

# On branch master
# Changes not staged for commit:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   conf/gitolite.conf
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#       keydir/psalcido_id_rsa.pub
no changes added to commit (use "git add" and/or "git commit -a")

Now I need to commit and push these changes into the administrative repository.

gitolite$ cd ~/gitolite-admin/
gitolite$ git add *
gitolite$ git commit -m "Adding user psalcido to the repo, adding repo psalcido."

At this point you might get errors about git config. Run the commands that git requests for configuration and retry the commit. The following messages should occur:

[master 8f9e41c] Adding user psalcido to the repo, adding repo psalcido.
 2 files changed, 4 insertions(+)
 create mode 100644 keydir/psalcido_id_rsa.pub
gitolite@ansible-dev:/var/lib/gitolite/gitolite-admin$ git push
Counting objects: 10, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 854 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
remote: Initialized empty Git repository in /var/lib/gitolite/repositories/psalcido.git/
To gitolite@localhost:gitolite-admin.git
   f01acb3..8f9e41c  master -> master

If you are normally accustomed to seeing git response messages, the message remote: Initialized empty Git repository in /var/lib/gitolite/repositories/psalcido.git/ and after should really jump out at you, as these ‘hooks’ are actually creating the repository and giving the user ‘psalcido’ access to those directory (or, really, they are giving access to the private key that is owned by the user psalcido).

Modify the repository with the user key

Now we need to login with the user psalcido, and try to clone and commit to the new repository.

psalcido:~$ git clone gitolite@localhost:psalcido.git

We should end up with a warning about cloning an empty repository. If we do, it means that everything has worked so far. Now I’m going to create a readme file and try to commit to it.

psalcido$ cd psalcido
psalcido$ echo "This is a test commit" >> README
psalcido$ git add *
psalcido$ git commit -m "Initial commit"
psalcido$ git push origin master

Done! You now know how to create new users, set up the ssh keys for those users, and get gitolite working in general. It is actually pretty easy from here on out.

Advertisements

9 comments

  1. Hi there,

    Just wondering, do I have to create it under the user gitolite? Can I create a user git instead or will that conflict somewhere with the git executable? It would just be nice to not have to use gitolite@address all of the time.. Also, do you foresee any problems creating the home directory as /home/git?

    Thanks

  2. You can use whatever user you like, but I strongly recommend that where ever you put your repositories, they remain under the /var directories. /home is often space limited (or should be in most server builds), whereas /var is often given a large amount of space.

  3. Pretty Good and Cool. Thanks for help me!
    I suggest to correct some little typing errors.
    Before you said “We will add on the following lines at the end of the file gitolite.conf:” i believe you want to said psalcido_id_rsa instead of psalcido_id_isa

    And, at last of the document, the second line you have

    psalcido$ echo “This is a test commit” >> README
    I think you has to say
    psalcido$ echo “This is a test commit” >> README

    I am newbie on this: Gitolite and English.. excuse my language
    Thanks Paul!!!!!

  4. I have made the first change, and I thank you for finding it. Embarrassing error – however, as far as your second listed change, I don’t get it, they look the same to me. is there something that I’m missing there, as the two lines look the same to me.

  5. Hello !

    Your website is amazing but in the end there is something I don’t get :

    After typing this line :

    psalcido:~$ git clone gitolite@localhost:psalcido.git

    My computer ask me a password :

    ***********************************************************************
    user1@debX64:~$ git clone gitolite@localhost:user1.git
    Cloning into user1. . .
    gitolite@localhost’s password: // So I try empty, and others passwords…
    Permission denied, please try again.
    gitolite@localhost’s password:
    Permission denied, please try again.
    gitolite@localhost’s password:
    Permission denied (publickey, password) .
    fatal: The remote end hung up unexpectedly
    ***********************************************************************

    1. This means that user1’s public key has not yet been installed in the gitolite authorized keys file. I don’t know if user1 is the ‘administrative’ user, or a later user, but what you will need to do is either use the administrative key to add another user by checking out the repository, adding the public key to the repository, and then having gitolite add it to the authorized keys file, or you will need to initialize gitolite so that it has an admin key. My guess is the former.

  6. Very good guide. Thanks!
    I have all running, but now, I want to add a new user (new developer) working on his machine, at home. The communication and ports are opened, but my question is.. what I need to do? Can you explain to me slowly 😀
    I thing I need to create a ssh-keys in dev machine and copy to git-server host.. and then? where to put it, I need to give access on the repo via gitolite-admin? Can you try to explain as you do it, clearly and with steps! was really easy to follow the guide! Thanks!

  7. gabrielcz · · Reply

    Very good guide. Thanks!
    I have all running, but now, I want to add a new user (new developer) working on his machine, at home. The communication and ports are opened, but my question is.. what I need to do? Can you explain to me slowly 😀
    I thing I need to create a ssh-keys in dev machine and copy to git-server host.. and then? where to put it, I need to give access on the repo via gitolite-admin? Can you try to explain as you do it, clearly and with steps! was really easy to follow the guide! Thanks!

  8. If you follow the steps from “Install the user ssh key with gitolite, and create your first repository” down, except instead of psalcido you use this new users name, it should work. You just need to install their key, and give them access by modifying the administrative password. Once you have the entire system up and running, there are a lot of things at https://github.com/sitaramc/gitolite that are really helpful about setting up new users.

    One aspect of what you need to know is ssh, and the other is gitolite itself. Also, if you use another tool like Redmine on top of this, it really makes it much easier to manage the entire gitolite system.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: