gitano is not entirely unlike the
non-web, server side of github. It allows you to create and manage
users and their SSH keys, groups and repositories from the command
line. Repositories have ACLs associated with them. Those can be
complex (“allow user X to push to master
in the doc/
subtree) or
trivial (“admin can do anything”). Gitano is written by Daniel
Silverstone, and I’d like to thank him both for writing it and for
holding my hand as I went stumbling through my initial gitano setup.
Getting started with Gitano can be a bit tricky, as it’s not yet packaged and fairly undocumented. Until it is packaged, it’s install from source time. You need luxio, lace, supple, clod, gall and gitano itself.
luxio
needs a make install LOCAL=1
, the others will be installed
to /usr/local
with just make install
.
Once that is installed, create a user to hold the instance. I’ve
named mine git
, but you’re free to name it whatever you would like.
As that user, run gitano-setup and answer the prompts. I’ll use
git.example.com
as the host name and john
as the user I’m setting this
up for.
To create users, run ssh git@git.example.com user add john john@example.com John Doe
, then add their SSH key with ssh git@git.example.com as john sshkey add workstation < /tmp/john_id_rsa.pub
.
To create a repository, run ssh git@git.example.com repo create myrepo
. Out of the box, this only allows the owner (typically
“admin”, unless overridden) to do anything with it. To change ACLs,
you’ll want to grab the refs/gitano/admin
branch. This lives
outside of the space git usually use for branches, so you can’t just
check it out. The easiest way to check it out is to use
git-admin-clone. Run it as git-admin-clone git@git.example.com:myrepo ~/myrepo-admin
and then edit in
~/myrepo-admin
. Use git to add, commit and push as normal from
there.
To change ACLs for a given repo, you’ll want to edit the
rules/main.lace
file. A real-world example can be found in the
NetSurf repository and the lace syntax
might be useful. A lace file consists of four types of lines:
- Comments, start with – or #
- defines, look like
define name conditions
- allows, look like
allow "reason" definition [definition…]
- denials, look like
deny "reason" definition [definition…]
Rules are processed one by one, from the top and terminate whenever a matching allow or deny is found.
Conditions can either be matches to an update, such as ref refs/heads/master
to match updates to the master branch. To create
groupings, you can use the anyof
or allof
verbs in a definition.
Allows and denials are checked against all the definitions listed and
if all of them match, the appropriate action is taken.
Pay some attention to what conditions you group together, since a
basic operation (is_basic_op
, aka op_read
and op_write
) happens
before git is even involved and you don’t have a tree at that point,
so rules like:
define is_master ref refs/heads/master
allow "Devs can push" op_is_basic is_master
simply won’t work. You’ll want to use a group and check on that for basic operations and then have a separate rule to restrict refs.