From 70d26d810b4089f2f66577fc68adc4b1c6e53f0e Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Fri, 25 Sep 2009 12:17:33 +0530 Subject: [PATCH] compile, all docs/confs: specify gitweb/daemon access + bonus bonus: documented the "bits and pieces" thing properly; should have done this long ago, but it came to the forefront now thanks to this item --- README.mkd | 6 +++- conf/example.conf | 21 +++++++++-- conf/example.gitolite.rc | 5 +++ doc/0-UPGRADE.mkd | 6 ++++ doc/1-migrate.mkd | 2 ++ doc/2-admin.mkd | 23 ++++++++++++ doc/3-faq-tips-etc.mkd | 77 ++++++++++++++++++++++++++++++++++++++++ src/gl-compile-conf | 74 +++++++++++++++++++++++++++++++++++++- 8 files changed, 209 insertions(+), 5 deletions(-) diff --git a/README.mkd b/README.mkd index fa8e2f4..5a59bd1 100644 --- a/README.mkd +++ b/README.mkd @@ -38,7 +38,11 @@ that: * no one in $DAYJOB type environments will use or approve access methods that work without any authentication, so I didn't need gitweb/daemon - support in the tool or in the config file + support in the tool or in the config file. + + Update 2009-09-24: I don't use this feature but someone wanted it, so I + added it... see the "faq, tips, etc" document for more + * the idea that you admin it by pushing to a special repo is nice, but not really necessary because of how rarely these changes are made, especially considering how much code is involved in that piece diff --git a/conf/example.conf b/conf/example.conf index 7170140..6ea6234 100644 --- a/conf/example.conf +++ b/conf/example.conf @@ -8,9 +8,13 @@ # objectives, over and above gitosis: # - simpler syntax -# - no gitweb/daemon control -# - allows ff/non-ff control -# - allows branch level control +# - easier gitweb/daemon control +# - specify who can push a branch/tag +# - specify who can rewind a branch/rewrite a tag + +# convenience: allow specifying the access control in bits and pieces, even if +# they overlap. Keeps the config file smaller and saner. See the example in +# the "faq, tips, etc" document # ---------------------------------------------------------------------------- # LISTS @@ -97,3 +101,14 @@ repo @privrepos thirdsecretrepo RW refs/tags/ss/ = @secret_staff RW tmp/.* = @secret_staff R = @secret_staff + +# ---------------------------------------------------------------------------- +# GITWEB AND DAEMON CONTROL + +# there is no special syntax for this. If a repo gives read permissions to +# the special user "gitweb" or "daemon", the corresponding changes are made +# when you compile; see "faq, tips, etc" document for details. + +# this means you cannot have a real user called "gitweb" or "daemon" but I +# don't think that is a problem :-) + diff --git a/conf/example.gitolite.rc b/conf/example.gitolite.rc index ee5a3e3..3725110 100644 --- a/conf/example.gitolite.rc +++ b/conf/example.gitolite.rc @@ -24,6 +24,11 @@ $REPO_UMASK = 0077; # gets you 'rwx------' # $REPO_UMASK = 0027; # gets you 'rwxr-x---' # $REPO_UMASK = 0022; # gets you 'rwxr-xr-x' +# part of the setup of gitweb is a variable called $projects_list (please see +# gitweb documentation for more on this). Set this to the same value: + +$PROJECTS_LIST = "/home/git/projects.list"; + # -------------------------------------- # I see no reason anyone may want to change the gitolite admin directory, but diff --git a/doc/0-UPGRADE.mkd b/doc/0-UPGRADE.mkd index a374c05..8c80bb7 100644 --- a/doc/0-UPGRADE.mkd +++ b/doc/0-UPGRADE.mkd @@ -42,6 +42,12 @@ And you're done. If any extra steps beyond the generic ones above are needed, they will be listed here, newest first. +#### upgrading from 8217ef9 + +Between 8217ef9 and this version, gitolite learnt to handle gitweb/daemon +access. As a result, the rc file acquired a new variable, `$PROJECTS_LIST`, +which you have to set to whatever your gitweb installation requires. + #### upgrading from 86faae4 Between 86faae4 and this version, gitolite had a *major* change in the diff --git a/doc/1-migrate.mkd b/doc/1-migrate.mkd index 6ef0c90..fe0b4cf 100644 --- a/doc/1-migrate.mkd +++ b/doc/1-migrate.mkd @@ -1,5 +1,7 @@ # migrating from gitosis to gitolite +[TODO: make the migration tool fix up gitweb and daemon control also...] + Migrating from gitosis to gitolite is pretty easy, because the basic design is the same. The differences are: diff --git a/doc/2-admin.mkd b/doc/2-admin.mkd index 0585e06..8cd2216 100644 --- a/doc/2-admin.mkd +++ b/doc/2-admin.mkd @@ -32,6 +32,29 @@ Please read on to see how to do this correctly. should be exactly the same as their keyfile names, but without the `.pub` extension +#### specifying gitweb and daemon access + +This is a feature that I personally do not use (corporate environments don't +like unauthenticated access of any kind to any repo!), but someone wanted it, +so here goes. + +There's **no special syntax** for this -- just give read permission to a user +called `gitweb` or `daemon`! (This also means you can't have a normal user +with either of those two names, but I doubt that's a problem!). See the "faq, +tips, etc" document for easy ways to specify access for multiple repositories. + +Note that this does **not** install or configure gitweb/daemon -- that is a +one-time setup you must do separately. All this does is: + + * for gitweb, add the repo to the list of projects to be served by gitweb + (see the config file variable `$PROJECTS_LIST`, which should have the same + value you specified for `$projects_list` when setting up gitweb) + * for daemon, create the file `git-daemon-export-ok` in the repository + +`src/gl-compile-conf` will keep these files consistent with the config +settings -- this includes removing such settings if you remove "read" +permissions for the special usernames. + #### compiling * backup your `~/.ssh/authorized_keys` file if you feel nervous :-) diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index d919087..b28c548 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -6,8 +6,10 @@ In this document: * git version dependency * other errors, warnings, notes... * differences from gitosis + * simpler syntax * two levels of access rights checking * error checking the config file + * easier to specify gitweb/daemon access * built-in logging * one user, many keys * who am I? @@ -92,6 +94,49 @@ Apart from the big ones listed in the top level README, and subjective ones like "better config file format", there are some small, but significant and concrete, differences from gitosis. +#### simpler syntax + +The basic syntax is simpler and cleaner but it goes beyond that: **you can +specify access in bits and pieces**, even if they overlap. + +Some access needs are best grouped by repo, some by username, and some by +both. So just do all of them, and gitolite will combine all the access lists! +Here's an example: + + # define groups of people + @bosses = phb1 phb2 phb3 + @devs = dev1 dev2 dev3 + @interns = int1 int2 int3 + + # define groups of projects + @open = git gitolite linux rakudo + @closed = c1 c2 c3 + @topsecret = ts1 ts2 ts3 + + # all bosses have read access to all projects + repo @open @closed @topsecret + R = @bosses + + # everyone has read access to "open" projects + repo @open + R = @bosses @devs @interns + + [...or any other combination you want...] + + # later in the file: + + # specify access for individual repos (like RW, RW+, etc) + repo c1 + [...] + + [...etc...] + +If you notice that `@bosses` are given read access to `@open` via both rules, +do not worry that this causes some duplication or inefficiency. It doesn't +:-) + +See the "specify gitweb/daemon access" section below for one more example. + #### two levels of access rights checking Gitolite has two levels of access checks. The **first check** is what I will @@ -134,6 +179,38 @@ In gitolite, you have to "compile" the config file first (this step takes the place of the commit+push in gitosis), and keyword typos *are* caught so you know right away. +#### easier to specify gitweb/daemon access + +Specifying gitweb and/or daemon access for a repo is simple: give "read" +permissions to two special usernames: `gitweb` and `daemon`. + +You can also keep these pieces separate from the detailed, branch level access +for each repo, if you like, since you can write the access control specs in +bits and pieces. Here's an example, using short repo names for convenience: + + # maybe near the top of the file, for ease of access: + + @only_web = r1 r2 r3 + @only_daemon = r4 r5 r6 + @web_and_daemon = r7 r8 r9 + + repo @only_web + R = gitweb + repo @only_daemon + R = daemon + repo @web_and_daemon + R = gitweb + R = daemon + + # ...maybe much later in the file: + + repo r1 + # normal developer access lists for r1 and its branches/tags in the + # usual way + + repo r2 + # ...and so on... + #### built-in logging ...just in case of emergency :-) diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 33cc057..2422bc2 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -15,6 +15,11 @@ $Data::Dumper::Indent = 1; # (gl-)update hook need this, and it seems easier to do this than # replicate the parsing code in both those places. As a bonus, it's # probably more efficient. +# (3) - finally does what I have resisted doing all along -- handle gitweb and +# git-daemon access. It won't *setup* gitweb/daemon for you -- you have +# to that yourself. What this does is make sure that "repo.git" +# contains the file "git-daemon-export-ok" (for daemon case) and the +# line "repo.git" exists in the "projects.list" file (for gitweb case). # how run: manual, by GL admin # when: @@ -42,7 +47,7 @@ $Data::Dumper::Indent = 1; # common definitions # ---------------------------------------------------------------------------- -our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK); +our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST); # now that this thing *may* be run via "push to admin", any errors have to # grab the admin's ATTENTION so he won't miss them among the other messages a @@ -227,6 +232,73 @@ warn "\n\t\t***** WARNING *****\n" . "\t\"git version dependency\" in doc/3-faq-tips-etc.mkd\n" if $git_too_old; +# ---------------------------------------------------------------------------- +# handle gitweb and daemon +# ---------------------------------------------------------------------------- + +# How you specify gitweb and daemon access is quite different from gitosis. I +# just assume you'll never have any *real* users called "gitweb" or "daemon" +# :-) These are now "pseduo users" -- giving them "R" access to a repo is all +# you have to do + +wrap_chdir("$repo_base_abs"); + +# get the current project list; note that the file may not yet exist if no +# gitweb access has been specified so far +my %projlist = (); +if (-f $PROJECTS_LIST) { + my $projlist_fh = wrap_open( "<", $PROJECTS_LIST); + while(<$projlist_fh>) { + chomp; + $projlist{$_} = 1; + } + close $projlist_fh; +} +my $projlist_changed = 0; + +# daemons first... +for my $repo (sort keys %repos) { + my $export_ok = "$repo.git/git-daemon-export-ok"; + if ($repos{$repo}{'R'}{'daemon'}) { + unless (-f $export_ok) { + system("touch $export_ok"); + print STDERR "daemon add $repo.git\n"; + } + } else { + if (-f $export_ok) { + unlink($export_ok); + print STDERR "daemon del $repo.git\n"; + } + } +} + +# ...then gitwebs +for my $repo (sort keys %repos) { + if ($repos{$repo}{'R'}{'gitweb'}) { + unless ($projlist{"$repo.git"}) { + # not in the old list; add it to the new one + $projlist{"$repo.git"} = 1; + $projlist_changed = 1; + print STDERR "gitweb add $repo.git\n"; + } + } else { + if ($projlist{"$repo.git"}) { + # delete it from new list + delete $projlist{"$repo.git"}; + $projlist_changed = 1; + print STDERR "gitweb del $repo.git\n"; + } + } +} + +# has there been a change? +if ($projlist_changed) { + print STDERR "updating gitweb project list $PROJECTS_LIST\n"; + my $projlist_fh = wrap_open( ">", $PROJECTS_LIST); + print $projlist_fh join("\n", sort keys %projlist), "\n" if %projlist; + close $projlist_fh; +} + # ---------------------------------------------------------------------------- # "compile" ssh authorized_keys # ----------------------------------------------------------------------------