Getting started with gitosis
So you’ve evaluated the SaaS landscape the Web has to offer and decided to go it alone and host public repositories behind your corporate firewall. You’ve also decided you want to build the service using free components from the Open Source community if possible. Enter gitosis.
Gitosis is a program designed to facilitate hosting Git repositories in a secure manner using SSH and only requiring 1 user for the server setup. It does this via SSH keys for authentication. The administrative interface for gitosis is nothing more than a single INI-style configuration file, gitosis.conf, and a set of SSH public keys that correspond to users referenced in the config file. This is a great system because it’s cross platform and straightforward; if you have a version of Python that supports ConfigParser et al. On the list of downsides this is a fairly low-level way of interacting with the application, requiring a modest skill level to work with. For savvy administrators who will be doing everything from installing gitosis to maintaining the configuration the administrative paradigm is light and easy. But even for the savvy administrator gitosis exposes a weakness.
After making a change to gitosis.conf and committing locally, updates are made effective via a git post-update hook which reads the new configuration and updates the SSH configuration accordingly. The problem occurs when an admin introduces a parse error into gitosis.conf. Once the file is pushed to the remote gitosis-admin repository the post-update hook runs and an error occurs on the server. If you try to clean up gitosis.conf and do another push, you’ll soon discover the repository is hosed… The syntax error in gitosis.conf from the last commit is preventing subsequent pushes to the public repository.
Our only recourse at this point is to SSH into the server, edit the configuration file there, and then we can push from cloned repositories again. Ouch, that’s painful even for an administrator, but imagine trying to delegate repository administration to a junior staff member or less technical individual! A solution then is to parse the gitosis.conf file with a commit hook and refuse commits if the syntax is invalid.
#!/usr/bin/python import ConfigParser, os cwd = os.popen("pwd").read().strip() theconfig = os.popen( "git diff --cached --name-only | egrep 'gitosis.conf$'") if theconfig.read().strip() == "gitosis.conf": config = ConfigParser.ConfigParser() try: config.readfp(open(cwd + '/gitosis.conf')) exit(0) except ConfigParser.Error as detail: print "* Cannot parse gitosis.conf; aborting commit." print "Underlying exception from parser:" print detail exit(1) else: exit(0)
If you enjoyed this post please consider sharing it!