Installation of a Gitolite Server
This post holds my installation notes of a Git server based on Gitolite.
The objective is to allow people to collaborate on a project via git i.e. to be able to host Git repositories managed via SSH, yet having a single system account (git in general) and not one per contributor.
Several utilities can be considered at this level:
- gitosis, the historical one.
- gitolite, a modern alternative with more fine-grained access control and many (many!) more powerful features.
- gitlab, a complete web interface offering a similar interface than Github for Git repository management, code reviews, issue tracking, activity feeds and wikis. For gitlab configuration, see
gitlab.md
_WARNING_: in the first two cases, once setup, these tools are configured via a git repository (named gitosis-admin or gitolite-admin). To avoid problems if an error is performed on the syntax of the configuration files and is commited that would deny access to the repository, we will always configure the tools to be managed either remotely or locally.
Resources:
Installation
Manual install
Install the required packages
$> yum install git gitolite3
Create a git user, to ensure shorten URLs upon clone operations (i.e. git clone git@... instead of git clone gitolite3@... ):
$> adduser --system --shell /bin/sh --comment "git repository hosting with git clone ... URLs shorter" --gid gitolite3 --home-dir /var/lib/git --create-home git
Create a local SSH keypair for the root user that will be used to pilot the initial configuration of Gitolite:
$> ssh-keygen -t rsa -b 4096 -o -a 100 -C "Git-Admin"
If you use SELinux, you’ll need to set the appropriate context (see this blog post)
$> chcon -R unconfined_u:object_r:user_home_t:s0 /var/lib/git/.ssh
# OR
$> semanage fcontext -a -t ssh_home_t /var/lib/git/.ssh/
$> restorecon -v /var/lib/git/.ssh/
Gitolite is now installed, but is not ready for use. The admin SSH key need to be copied to somewhere gitolite can access it, and then run the setup script.
$> cp /root/.ssh/id_dsa.pub ~git/root@$(hostname -f).pub
Bootstrap Gitolite with the SSH key for the git user as follows:
$> sudo su - git
(git)$> gitolite setup -pk root@$(hostname -f).pub
NOTE: the admin username is 'root@<hostname>'
Initialized empty Git repository in /var/lib/git/repositories/gitolite-admin.git/
Initialized empty Git repository in /var/lib/git/repositories/testing.git/
WARNING: /var/lib/git/.ssh missing; creating a new one
(this is normal on a brand new install)
WARNING: /var/lib/git/.ssh/authorized_keys missing; creating a new one
(this is normal on a brand new install)
Puppet-based install
You can use the echoes/gitolite module to setup a gitolite server, for instance with the following recipe:
1 2 3 4 5 6 7 | |
Local configuration repository
You can check again that the root user (or whoever has seen his public SSH key configured for the setup of gitolite) will have access to the gitolite-admin repository that hold the gitolite configuration:
1 2 3 4 5 | |
In case the above command failed with the following error message:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
The reason might be linked to SELinux and you may see an error in the audit log (/var/log/audit/audit.log) on the server as follows:
Apr 14 10:03:46 <hostname> setroubleshoot: SELinux is preventing /usr/sbin/sshd from read access on the file authorized_keys. For complete SELinux messages. run sealert -l eacc55af-fdf1-4f19-9428-6f598236a260
Apr 14 10:03:46 <hostname> python: SELinux is preventing /usr/sbin/sshd from read access on the file authorized_keys.
See above for the expected fix – typically restorecon -R -v /path/to/.ssh.
And the root user can now clone the gitolite-admin repository (this step is already handled by the Puppet profile ::profile::gitolite):
1 2 3 | |
Gitolite Admin repository layout
The layout of the gitolite-admin repository can be organized as follows:
1 2 3 4 5 6 7 | |
SSH Key filename conventions
There is a 1:n mapping between users and ssh public-keys under gitolite.
A given user may have one or more registered keys, each in a separate key file under gitolite-admin/keydir/. The keyfile name is significant and determines the user’s identity assumed by the system upon demonstration of possession of the matching private-key. The basic pattern for a keyfile name is one of the following:
user.pubuser@qualifier.pub(where qualifier does not include a dot)user@host.dom.pub(where user@host.dom is an e-mail address with at least one dot in the hostname)
In the first two cases, the associated identity for access control in the conf/gitolite.conf file is user. In the latter case, it is user@host.dom.
The first two cases allow a user to register multiple keys (e.g. user.pub and user@laptop.pub) while still affording the same access privileges to both keys. The latter form allows non-local users to be identified in a way that preserves their contact information.
In principle the user name be arbitrary and can start with any alphanumeric character and contain dots, dashes and underscores (e.g. John-Smith).
In practice, the following convention can be used:
- admin keys are stored under
keydir/admins/ - regular users keys are stored under
keydir/users/- Each users key(s) are stored in a dedicated directory named
firstname.name@domain.com/, wherefirstname.name@domain.comis a valid email adress for this user - thus a key for a user is
username@domain.com/username@domain.com.pub
- Each users key(s) are stored in a dedicated directory named
Completing the configuration of gitolite-admin for remote management
as root on git-admin.hpc
1 2 3 4 5 | |
You need also to update the default configuration conf/gitolite.conf to allow this key:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
Now you should be able to clone remotely the repository and feel more comfortable on your local workstation to update the repository.
1 2 3 4 5 6 7 | |
Common [sysadmins] operations
See also:
Add a new user or a new key
Update your local copy of the repository
$> git up
Follow the above convention to add the public key. Examples, to add a new UNI user:
$> cd keydir
$> mkdir -p users/firstname.name@uni.lu
$> cp /path/to/user_id_dsa.pub users/firstname.name@uni.lu/fname.pub
Add the key to the git repository and commit your changes (with your commit message prefixed with [gitolite-admin] NEW_KEY:)
$> git add users/firstname.name@uni.lu/fname.pub
$> git commit -s -m "[gitolite-admin] NEW_KEY: add key for user F. Name"
Edit the file conf/gitolite.conf, go into the section Users group definitions and create a group for this user:
1 2 3 4 5 6 7 8 9 | |
Commit your changes (as always, prefixed with [gitolite-admin]) and push them
$> git commit -s -m "configuration for user F. Name"
$> git push origin
Creating a new repository
You have to edit the file conf/gitolite.conf and add a new repo entry.
Typical addition of the repository mynewrepo
repo mynewrepo
desc = "My new repo"
RW+ = admin @ORGadmins
You should have at least in the RW+ field entries for admin AND @ORGadmins.
Then feel free to add other groups/users etc.
Adding a description permits to populate the file ~git/repositories/<reponame>/description assuming you enable the cgit extension.
1 2 3 4 5 6 7 8 9 10 11 | |
-
Once you finished the configuration, commit your changes with your commit message prefixed with
[gitolite-admin] NEW_REPO:)$> git commit -s -m "[gitolite-admin] NEW_REPO: add repo 'mynewrepo' -
push your changes onto
git-admin:$> git push origin -
Now you can clone locally the newly created repository
$> git clone ssh://git@<hostname>/reponame.git [...] bla bla work commit $> git push -u origin master
Using the mailing-list hook
See blog post
You first need to setup the hook script post-receive-email on the server as ~git/.gitolite/hooks/common/post-receive, just copy the one located in /usr/share/doc/git-1.8.3.1/contrib/hooks/post-receive-email
1 2 3 4 5 | |
Now you should setup ~git/.gitolite.rc to change GIT_CONFIG_KEYS as ‘.*’. The cgit part is made to populate automatically the description file of each repository:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Not doing this will lead to the error upon pushing
1 2 | |
Now you can setup the repositories for which you want to send email notifications. Symply add the entries:
config hooks.mailinglist = "youmailinglist"
config hooks.emailprefix = "[GIT] reponame: "
to the appropriate repo.
You can also set this option for all repositories:
1 2 3 | |
… Or define a group of repositories for which you want to see this activated.
Note that you probably want in this case to setup the desc = "<description>" attribute such that, assuming the cgit entension is enabled, you don’t receive mails with subject like that:
<emailprefix>: UNNAMED PROJECT branch master updated. acb42a341617af8e293bc058c70cebcbc46f419f
It is also important to version the .gitolite.rc file under the gitolite-admin repository – normally it is not the case (see reference documentation), yet for some reason the file is reset to default (loosing the above mentioned modifications) if you don’t do it.
As indicated in the reference doc), just add it to your gitolite-admin repo, push the change, then replace ~/.gitolite.rc with a symlink to ~/.gitolite/.gitolite.rc as git.
1 2 3 | |
List available repositories
From your local machine, simply run:
1 2 3 4 5 | |