Reviewing gitolite modules from the puppet forge

When a million flowers bloom in the world of open source, with no clear winner in the popularity contest for wide-spread use, sometimes the options can overwhelm. What follows is a summary of what I learned spending a day reviewing my options for a tool I could perhaps have written myself in that time, if I had felt free to ignore the prior art. It relates to yet another great tool written in perl, gi‪tolite by sitaramc.


If you manage your infrastructure with puppet, your source code with git and have need of an in-house git repository providing user and group access control lists, this article may be relevant to your needs.

A mother board died earlier this week, orphaning our gitolite installation and several other key components of our company's infrastructure. The assets hosted on that now dead server were the last components of our infrastructure not yet under puppet management. Now seemed like the time to do something about that. And that led to this review of the gitolite modules available of the puppet forge.

Gitolite and the project on github --

But for those not familiar with this tool; . . .

As Sitaram Chamarty (the author) describes it: 'Gitolite allows you to setup git hosting on a central server, with fine-grained access control and many more powerful features'. gitolite is an application written in perl which allows for its management using a single configuration file with a simple and intuitive syntax, backed by a directory of public keys.

Its configuration looks like this:

tree gitolite-admin/

├── conf
│   └── gitolite.conf
└── keydir
├── gitolite-admin
│   └──
└── etc., etc.

3 directories, 29 files

sandbox/gitolite-admin/conf/gitolite.conf --

@ymd_development = hesco larry moe curly
@some_client = joe sarah sally

repo gitolite-admin
RW+ = hesco

repo client-project
RW+ = hesco
RW = @ymd_development
R = @some_client
- = @former_employees

Adding a new repo stanza to gitolite.conf will initialize an empty git repository on the central server. Adding a public key to the keydir/ path will enable a key-pair authenticated connection to the gitolite server. Groups are defined with space delimited lists assigned to perl arrays. Repository access is controlled with assignments to permission levels. And repository administration really is that simple.

Note that I have public keys here for the Jenkins CI server, a cluster wide deploy user and a user dedicated to managing backups for our network. Any user, human or application, with a need for access to your git managed source code can be given access by generating a key-pair. (Don't afraid to log in once manually to accept the fingerprint into .ssh/known_hosts).

Configuration management --

Over the last six or ten years a new class of system administration tools have come to the fore to dominate how folks administer servers these days. I even use a configuration management tool to manage my own desktop machine. The options include puppet, chef, ansible, salt and others. Generally these tools use a declarative Domain Specific Language, permitting one to decalre the end state one wishes a server to reach and through multiple idempotent runs of what in puppet is called a catalog, the server will eventually converge on that state. Subsequent runs should mainatin that state by overwriting configuration drift for any server components under configuration management. The configuration management tool I started with and which I continue to use to this day is puppet, developed by Puppetlabs with contributions from a broad community of systems administrators.

The puppet modules --

Puppetlabs hosts a forge of community contributed modules used to administer various tools, applications and configurations a sysadmin may be called upon to install on a machine. Puppetlabs maintains a couple of dozen key modules in house which are published to the forge, and as of last month's PuppetConf announced a new program for 'Puppet Approved' community developed modules which have been reviewed for conformity to quality standards, including design and style standards, unit testing and behavior testing.

What follows is my evaluation of the modules on the forge intended to build and administer a gitolite installation. This is intended to summarize my review of the options, my assessment of code quality, their feature set, their interface, the extent to which they can be customized, the maturity of the projects, their popularity among module consumers and code contributors.

gitolite is in its third major version, currently at 3.6.1. My target environment is a debian jessie/testing installation. Its packaging system includes gitolite3 (version 3.6-1) and gitolite (version 2.3-1). offers the same options and versions.

The options, ranked in order of their popularity are:

[nvpuppet/gitolite] --

With 2,585 downloads, nearly all of them of the current version 0.7.0, published June 11, 2013, this module offers terse, well organized code and a simple, elegant interface which will ensure the presence of the gitolite (version 2, no support for v3) package for OS Families redhat (using the EPEL repositories) and debian. This module permits the path, user and the public key for the administrator to be set on the interface. Its code design anticipates extension to offer further options, but its ::params class is currently empty. This is the work of a single developer, who has made 18 commits and two releases, and who has published no changes in 16 months. As of this writing, this remains the most popular gitolite module on the forge.

[huit/gitolite] --

At 1,949 dowloads of five published tags, nearly half of those since the latest v0.2.0 release in November 2013, the huit module is the second most popular on the forge. Its interface provides for a highly configurable interface to a source install from the git repository. It defaults to version 3.1, but that can be over-ridden when the gitolite class is invoked in your puppet profile. The huit module pays more attention to sanity checks than the more popular nvpuppet module. It provides no options for using packages from the distribution repositories. Its code could be more maintainable with some simple organization, but it has attracted seven contributors and 41 commits on three branches. Without trying to manage a gitweb installation, this module does integrate gitolite with gitweb.

[hunner/gitolite] --

The hunner module is nearly as popular, with 1,810 downloads, nearly all of its 5th release, v.0.3.0, published over two years ago. This work is the product of five contributors making 34 commits on ten branches, forked from prior art by jfryman, whose original code did not turn up in my search. Its params class intends to support a range of redhat and debian class operating systems. Its code base is well organized for easy maintenance or extension. Its interface offers a reasonable but not overwhelming range of switches, nearly all of them optional. By default, this module installs only the git clients. But it will also install gitolite version 2 (not 3, without hacking) from packages, manage apache and a gitweb installation, without the option of over-riding the extra functionality.

[gwmngilfen/gitolite] --

This module has been downloaded 1,042 times, half of those in the last sixteen months since the publication of the latest version (1.02) of the three released. Two contributors have offered ten commits. According to its, the module supports installation of gitolite version 2, and that gitolite version 3 is yet to come. The interface exposed by this module permits the customization of the gitolite user, group, package name, base path and a couple of other keys. According to a sanity check in its ::params class, this module supports Debian and Ubuntu, but will fail with a message that it has not been tested with other operating systems. It depends on the puppetlabs/git module. It takes the package specified on the interface and uninstalls it, in order to perform a source install from the three year old tarball included in the package. One feature offered by this module which I have not seen before is a gitolite::repo defined type for initializing a new repository. But while it is used internally to create the gitlite-admin repo, I suspect that it is of dubious value as gitolite's built-in hooks makes repo initialization as easy as pushing a revised configuartion file to the origin repo.

[yguenane/gitolite] --

The yguenane module is the product of 18 commits by two contributors, who have produced two releases. The latest version (v0.1.1) is 14 months old and is responsible for nearly two-thirds of the 756 downloads this module has received. Its ::params class exists, but is empty. The module will support installation of git from either packages or source, defaulting to version 1.7.1 when installing from source. The module provides a gitolite::instance defined type which defaults to version 3.5.2 but allows the consumer to set it. It proceeds to curl downloads and install from source a tarball from the site.

[ctrlcroot/gitolite] --

The ctrlcroot module has published two versions to the forge, most recently five months ago. That version (v. 0.2.0) is responsible for nearly half the 508 downloads from the forge. Two contributors have made 17 commits. This module offers defined types for ::repo, ::sshkey, ::group and ::hook, and seems to anticipate that the repos and access control for the installation will all be managed by puppet rather than using the gitolite-admin repo directly. The documentation warns that this module is expected to work only with redhat class machines. It installs gitolite version 3 from packages. Its ::init class provides basic data validation and resource chaining to manage the installation's initial configuration.

[eshamow/gitolite] --

Five releases of the eshamow module have been published to the forge, the latest (v 0.2.0) eight months ago. That version accounts for three-fifths of the 477 downloads to date. But the project link yields a 404 error on github. The project is no longer listed on the author's github page. The has conflicting guidance as to what OS families are supported. But there is evidence in the ::params class that both debian and redhat osfamily are supported. This module supports installation by package, source tarball or git clone. While it claims to support version 3 of gitolite, for debian, its hard-coded package name suggests otherwise. I would file a bug on that based on my code review (as I have filed bugs on two other packages reviewed here), but the author provides no means for doing so.

[jlcox/gitolite] --

Only six weeks old, this module has released two versions to the forge, almost all of its 115 downloads of the latest version, but its github links return 404 errors. Its metadata file promises compatibility with redhat and centos installations. It includes a couple of useful git repo hooks and puppet code to manage them. It installs gitolite version 3, as an upgrade after installing version 2, though I am not sure why that would be necessary. But this code is otherwise pretty straightforward, working through the installation and setup steps expected of the sitramc code base.

Recommendations --

For my own use, I get to immediately eliminate from the running, anything not compatible with debian. I will also eliminate the hunner module as I do not intend at this time to host a gitweb installation, and the hunner module either violates the principle of 'doing one thing and doing it well', or at least has a different conception than my own of what that one thing is. I am also interested in hosting version 3 of gitolite, which makes me less disposed to work with modules for which I would have to hack in that support and send off a patch for, hoping it might get accepted. Even so, I would appreciate an open path to contributions if those were warranted, so projects which fail to publish their code where I can clone and fork it, or who fail to offer an issue queue for reporting issues are easy to look past.

That leaves: huit and yguenane. Though I found in most of these packages, code which would be worth borrowing from were I to build the __perfect__ puppet module for managing a gitolite installation.

Were I to set out to write that perfect module, I would likely rather fork and extend nvpuppet or hunner instead. But I'd borrow whole hog the defined types to be found in the ctrlcroot code, making sure there was a switch for $manage_gitolite_configuration, and of course one for $install_gitweb, spinning those resources off, if not into their own module, at least into a distinct class. I also find attractive eshamow's options for installation from the consumer's choice of package, source or git source.

Having completed this review of the current options available on the forge, unless actual testing proves that course necessary, offering yet another option in the mix is likely not as high a priority as restoring access to the gitolite installation orphaned by this week's mother board death. Already other work is on hold for lack of access to our source code and a paying customer has called daily (with a very understanding tone) to inquire as to our time table for restoration.

These notes have helped narrow my options to two I can now proceed to test. I hope others who read this might find my code review useful to them as well. Perhaps a future post or comments on this one will report on my test results. At any rate, today I hope to restore our source repos so that our work can continue. And having finally puppetized this installation, I trust that any future disruptions can be more quickly recovered from.

1 Comment

Leave a comment

About hesco

user-pic I blog about Perl.