Git Administration, Hooks, and Dangerous Things

Bri Hatch Personal Work
Onsight, Inc
bri@ifokr.org
ExtraHop Networks
bri@extrahop.com

Copyright 2014, Bri Hatch, Creative Commons BY-NC-SA License

Audience

Who should be here?

Gitolite

Gitolite is a server-side component responsible for

Gitolite Installation

me@server$ sudo su - git
git@server$ mkdir ~/bin
git@server$ git clone git://github.com/sitaramc/gitolite
git@server$ gitolite/install -ln ~/bin
git@server$ gitolite setup -pk me.pub
    
Or possibly just
git@server$ apt-get install gitolite
git@server$ gl-setup me.pub
    
(Use ssh-keygen if you don't have a key yet.)

Gitolite Installation (cont)

You may, depending on version, be launched into an editor (vi hopefully!) of ~/.gitolite.rc to tweak settings:

...
# DO NOT TOUCH THIS SECTION!
# ------------------------------------------------------------------------------

$GL_ADMINDIR=$ENV{HOME} . "/.gitolite";
$GL_CONF="$GL_ADMINDIR/conf/gitolite.conf";
$GL_KEYDIR="$GL_ADMINDIR/keydir";
$GL_CONF_COMPILED="$GL_ADMINDIR/conf/gitolite.conf-compiled.pm";
...
    

Gitolite Installation (cont)

It automatically creates/appends to your ~/.ssh/authorized_keys:

# gitolite start
command="/path/to/gitolite/gitolite-shell key id_dsa",no-
port-forwarding,no-X11-forwarding,no-agent-forwarding,no-
pty ssh-dsa AAAAB3NzaCgQu82ukoHU847277.........
# gitolite end

Gitolite Installation (cont)

On the server, data lives in

Gitolite Installation (cont)

Clone the gitolite-admin repository from your desktop/etc

$ git clone ssh://git@server/gitolite-admin.git

$ cd gitolite-admin

$ ls -1 */*
conf/gitolite.conf
keydir/me.pub

Gitolite Configuration

The default configuration file:

$ cat conf/gitolite.conf
repo    gitolite-admin
        RW+     =   me
        
repo    testing
        RW+     =   @all

git@server$ ls ~/repositories/ gitolite-admin.git/ testing.git/

Adding repositories

Simply add another repo entry, commit and push!

$ cat conf/gitolite.conf
repo    gitolite-admin
        RW+     =   me
        
repo    testing
        RW+     =   @all

repo    fooproject
        RW      =   me
$ git commit -am 'Adds new fooproject repo'; git push

git@server$ ls ~/repositories/ fooproject.git/ # it's like magic! gitolite-admin.git/ testing.git/

Adding Users

Simply add a new ssh pubkey in keydir

$ cp /path/to/xlr.pub keydir/xlr.pub

$ git add keydir/xlr.pub

$ cat conf/gitolite.conf
repo    gitolite-admin
        RW+     =   me
        
repo    fooproject
        RW      =   me
        RW      =   xlr

$ ls keydir
me.pub     xlr.pub

$ git commit -am 'Adds xlr user w/ access to fooproject'
$ git push

Gitolite Groups

Creating groups

$ cat conf/gitolite.conf
@web-team     = me xlr
@crypto-team  = alice bob carol eve

# Group members accumulate! @huge-group has three members.
@huge-group   = firstperson
@huge-group   = secondperson
@huge-group   = thirdperson

repo    fooproject
        R       =   @web-team
        RW      =   @crypto-team
        RW      =   fourthperson
    

Gitolite Permissions

Standard Permissions

Confusing Permissions

Gitolite Permissions (cont)

Advanced Example
repo    website
    RW           = @web-team
    -  master    = @web-team
    RW+          = @web-team
    R                       = @marketing
    RW refs/tags/playground = @marketing

Gitolite Advanced Permissions

Need more advanced logic? VREFs are the answer!

repo fooproject
    RW+                       = foo-team
    -    VREF/NAME/Makefile   = @marketing
    

Gitolite Advanced Permissions (cont)

Need more advanced logic? VREFs are the answer!

repo fooproject
    RW+                       = foo-team
    -    VREF/NAME/Makefile   = @marketing
    

And are beyond the scope of this talk....

Git Hooks

Hooks allow you to run code before various git actions. They can apply in your local git clone (in the .git/hooks directory) or on the server.

Uses include:

Server Side Hooks

Limited to these types:

Server Side Hooks (cont)

Location of hooks

Server Side Hooks (cont)

Enable the local hooks by uncommenting some lines in ~/.gitolite.rc:

    LOCAL_CODE         =>  "$rc{GL_ADMIN_BASE}/local",

    ...

    # allow repo-specific hooks to be added
    'repo-specific-hooks',
    

And make a directory for them in your gitolite-admin clone:

$ mkdir local/hooks/repo-specific
    

Server Side Hooks (cont)

Create hooks and enable them where desired

$ ls local/hooks/repo-specific
crlf_check     send_email   update_infrastructure

$ less conf/gitolite.conf
...
repo hostinfo
    RW   = @sysadmins
    option hook.post-update     = update_infrastructure

repo documentation
    RW   = @docs-team
    option hook.pre-receive     = crlf_check

repo @all
    option hook.post-update     = send_email
    

Server Side Hooks Example

$ cat update_infrastructure
#!/bin/bash
## If relevant files were updated, trigger push to production.

MYDIR=$(dirname $0)

while read oldrev newrev refname
do
    if $(git show --pretty="format:" --name-only $newrev |
            grep '^dns/data' >/dev/null ) ; then
        $MYDIR/update_dns.sh
    fi
    if $(git show --pretty="format:" --name-only $newrev |
            grep '^dhcp/dhcp.conf' >/dev/null ) ; then
        $MYDIR/update_dhcp.sh
    fi
done
    
    

Server Side Hook Example (cont)!

$ cat update_dns.sh
#!/bin/bash
set -e
set -u
LOCAL_REPO=/home/git/local_repos/hostinfo
SSH_ARGS='-i $HOME/.ssh/magic-key'
SSH_USER='djbdns'
DNS_HOSTS='ns1 ns2 ns3'
TARGET_DIR='/etc/service/tinydns/root/'
unset GIT_DIR

cd $LOCAL_REPO
git pull >/dev/null 2>&1

for host in $DNS_HOSTS
do
    scp -q $SSH_ARGS $LOCAL_REPO/djbdns/data \
                     $SSH_USER@$host:$TARGET_DIR
    ssh $SSH_ARGS $SSH_USER@$host make -C $TARGET_DIR
done

Sample Hooks

Git comes with several example hooks in contrib/hooks (possibly in /usr/share/doc/git-core/contrib/hooks/ for example)

Related Tools

When running server-side hooks, the following may be useful:

Git Stuff Done!

Any questions?

Thanks!

Presentation: http://www.ifokr.org/bri/presentations/seagl-2014-git/

PersonalWork

Bri Hatch
Onsight, Inc
bri@ifokr.org

Bri Hatch
ExtraHop Networks
bri@extrahop.com

Copyright 2014, Bri Hatch, Creative Commons BY-NC-SA License