From 5416e38ea8e11ed856386e43c759da6ab3958a7d Mon Sep 17 00:00:00 2001 From: Teemu Matilainen Date: Fri, 4 Dec 2009 17:04:40 +0200 Subject: [PATCH 1/6] Fix default configuration paths in documentation Signed-off-by: Teemu Matilainen --- src/gl-compile-conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 56b11ed..6dfc050 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -27,11 +27,11 @@ $Data::Dumper::Sortkeys = 1; # - anytime a pubkey is added/deleted # - anytime gitolite.conf is changed # input: -# - GL_CONF (default: ~/.gitolite/gitolite.conf) +# - GL_CONF (default: ~/.gitolite/conf/gitolite.conf) # - GL_KEYDIR (default: ~/.gitolite/keydir) # output: # - ~/.ssh/authorized_keys (dictated by sshd) -# - GL_CONF_COMPILED (default: ~/.gitolite/gitolite.conf-compiled.pm) +# - GL_CONF_COMPILED (default: ~/.gitolite/conf/gitolite.conf-compiled.pm) # security: # - touches a very critical system file that manages the restrictions on # incoming users. Be sure to audit AUTH_COMMAND and AUTH_OPTIONS (see From cdb7245d44a57ec73ebac50f073eef1388bec15b Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 8 Dec 2009 13:51:11 +0530 Subject: [PATCH 2/6] example conf: clarify what @all means ...thanks to Grum for catching this --- conf/example.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/example.conf b/conf/example.conf index b5ead17..3768667 100644 --- a/conf/example.conf +++ b/conf/example.conf @@ -82,7 +82,8 @@ repo gitolite-admin RW+ = @admins - # "@all" is a special, predefined, group name + # "@all" is a special, predefined, group name of all users + # (everyone who has a pubkey in keydir) repo testing RW+ = @all From 4441ed82e4967b08ce18018ee7d6467bab3b689b Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 8 Dec 2009 15:03:38 +0530 Subject: [PATCH 3/6] compile: allow full email addresses as usernames we had usurped the email style syntax to separate multiple keys belonging to the same person, like sitaram@desktop.pub and sitaram@laptop.pub. If you have so many users that you need the full email address to disambiguate some of them (or you want to do it for just plain convenience), you couldn't. This patch fixes that in a backward compatible way. See doc/3-faq-tips-etc.mkd for details. --- conf/example.conf | 10 +++++++--- doc/3-faq-tips-etc.mkd | 28 ++++++++++++++++++++++++++-- src/gitolite.pm | 6 +++--- src/gl-compile-conf | 7 +++---- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/conf/example.conf b/conf/example.conf index b5ead17..b2173e3 100644 --- a/conf/example.conf +++ b/conf/example.conf @@ -6,9 +6,13 @@ # the description string for gitweb) # - comments in the normal shell-ish style; no surprises there # - there are NO continuation lines of any kind -# - user/repo names as simple as possible -# (usernames: only alphanumerics, ".", "_", "-"; -# reponames: same, plus "/", but not at the start) +# - user/repo names as simple as possible; they must start with an +# alphanumeric, but after that they can also contain ".", "_", "-". +# - usernames can optionally be followed by an "@" and a domainname +# containing at least one "." (this allows you to use an email +# address as someone's username) +# - reponames can contain "/" characters (this allows you to +# put your repos in a tree-structure for convenience) # objectives, over and above gitosis: # - simpler syntax diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index 464a4e5..9a1d413 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -344,12 +344,36 @@ gitolite knows these two keys belong to the same person. Note that you don't say "sitaram@laptop" and so on in the **config** file -- as far as the config file is concerned there's just **one** user called -"sitaram" -- so you only say "sitaram" there. Only the **pubkey files** have -the extra "@" stuff. +"sitaram" -- so you only say "sitaram" there. I think this is easier to maintain if you have to delete or change one of those keys. +However, now that `sitaramc@gmail.com` is also a valid username, we need to +distinguish between `sitaramc@gmail.com.pub` and `sitaramc@desktop.pub`. We +do that by requiring that the multi-key suffix you use (like "desktop" and +"laptop") should not have a `"."` in it. If it does, it looks like an email +address. The following table lists sample pubkey filenames and the +corresponding derived usernames (which is what goes into the +`conf/gitolite.conf` file): + + * old style multikeys; not mistaken for emails because there is no "." in + hostname part + + sitaramc.pub sitaramc + sitaramc@laptop.pub sitaramc + sitaramc@desktop.pub sitaramc + + * new style, email keys; there is a "." in hostname part; so it's an email + address + + sitaramc@gmail.com.pub sitaramc@gmail.com + + * multikeys *with* email address + + sitaramc@gmail.com@laptop.pub sitaramc@gmail.com + sitaramc@gmail.com@desktop.pub sitaramc@gmail.com + #### support for git installed outside default PATH The normal solution is to add to the system default PATH somehow, either by diff --git a/src/gitolite.pm b/src/gitolite.pm index 71c0b0c..ee0fc77 100644 --- a/src/gitolite.pm +++ b/src/gitolite.pm @@ -24,9 +24,9 @@ $WARN = "\n\t\t***** WARNING *****\n "; $R_COMMANDS=qr/^(git[ -]upload-pack|git[ -]upload-archive)$/; $W_COMMANDS=qr/^git[ -]receive-pack$/; -# note that REPONAME_PATT allows a "/" also, which USERNAME_PATT doesn't -$REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._/-]*$); # very simple pattern -$USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._-]*$); # very simple pattern +# note that REPONAME_PATT allows "/", while USERNAME_PATT allows "@" +$REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._/-]*$); # very simple pattern +$USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@-]*$); # very simple pattern # ---------------------------------------------------------------------------- # convenience subs diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 56b11ed..1125add 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -121,7 +121,7 @@ sub expand_list { # we test with the slightly more relaxed pattern here; we'll catch the # "/" in user name thing later; it doesn't affect security anyway - die "$ABRT bad user or repo name $item\n" unless $item =~ $REPONAME_PATT; + die "$ABRT bad user or repo name $item\n" unless $item =~ $REPONAME_PATT or $item =~ $USERNAME_PATT; if ($item =~ /^@/) # nested group { die "$ABRT undefined group $item\n" unless $groups{$item}; @@ -174,7 +174,6 @@ sub parse_conf_file # store the members of each group as hash key. Keep track of when # the group was *first* created by using $fragment as the *value* do { $groups{$1}{$_} ||= $fragment } for ( expand_list( split(' ', $2) ) ); - # again, we take the more "relaxed" pattern die "$ABRT bad group $1\n" unless $1 =~ $REPONAME_PATT; } # repo(s) @@ -200,7 +199,7 @@ sub parse_conf_file # expand the user list, unless it is just "@all" @users = expand_list ( @users ) unless (@users == 1 and $users[0] eq '@all'); - do { die "$ABRT bad username $_\n" unless $_ =~ $USERNAME_PATT } for @users; + do { die "$ABRT bad username $_ PATT is $USERNAME_PATT,\n" unless $_ =~ $USERNAME_PATT } for @users; # ok, we can finally populate the %repos hash for my $repo (@repos) # each repo in the current stanza @@ -408,7 +407,7 @@ for my $pubkey (glob("*")) print STDERR "WARNING: pubkey files should end with \".pub\", ignoring $pubkey\n"; next; } - my $user = $pubkey; $user =~ s/(\@.+)?\.pub$//; + my $user = $pubkey; $user =~ s/(\@[^.]+)?\.pub$//; # lint check 2 print STDERR "WARNING: pubkey $pubkey exists but user $user not in config\n" unless $user_list{$user}; From 3403d40d0e0a478252fa4111a44fb42218f92f15 Mon Sep 17 00:00:00 2001 From: Teemu Matilainen Date: Mon, 7 Dec 2009 22:20:29 +0200 Subject: [PATCH 4/6] Add support for repo configurations Git repository configurations can be set/unset by declaring "config" lines in "repo" stanzas in gitolite.conf. For example: repo gitolite config hooks.mailinglist = gitolite-commits@example.tld config hooks.emailprefix = "[gitolite] " config foo.bar = "" config foo.baz = The firs two set (override) the values. Double quotes must be used to preserve preceding spaces. Third one sets an empty value and the last removes all keys. Signed-off-by: Teemu Matilainen --- src/gl-compile-conf | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 7526da5..138249d 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -101,6 +101,9 @@ my %rurp_seen = (); # catch usernames<->pubkeys mismatches; search for "lint" below my %user_list = (); +# repo configurations +my %repo_config = (); + # gitweb descriptions and owners; plain text, keyed by "$repo.git" my %desc = (); my %owner = (); @@ -244,6 +247,16 @@ sub parse_conf_file } } } + # configuration + elsif (/^config (.+) = ?(.*)/) + { + my ($key, $value) = ($1, $2); + die "$WARN $fragment attempting to set repo configuration\n" if $fragment ne 'master'; + for my $repo (@repos) # each repo in the current stanza + { + $repo_config{$repo}{$key} = $value; + } + } # very simple syntax for the gitweb description of repo; one of: # reponame = "some description string" # reponame "owner name" = "some description string" @@ -338,6 +351,22 @@ warn "\n\t\t***** WARNING *****\n" . "\t\"git version dependency\" in doc/3-faq-tips-etc.mkd\n" if $git_version < 10602; # that's 1.6.2 to you +# ---------------------------------------------------------------------------- +# update repo configurations +# ---------------------------------------------------------------------------- + +for my $repo (keys %repo_config) { + wrap_chdir("$repo_base_abs/$repo.git"); + while ( my ($key, $value) = each(%{ $repo_config{$repo} }) ) { + if ($value) { + $value =~ s/^"(.*)"$/$1/; + system("git", "config", $key, $value); + } else { + system("git", "config", "--unset-all", $key); + } + } +} + # ---------------------------------------------------------------------------- # handle gitweb and daemon # ---------------------------------------------------------------------------- From 64979c18ea2758f87960965bf325d310ba1611cf Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Wed, 9 Dec 2009 12:16:22 +0530 Subject: [PATCH 5/6] document repo config support --- conf/example.conf | 23 +++++++++++++++++++++++ doc/2-admin.mkd | 23 +++++++++++++++++++++++ doc/3-faq-tips-etc.mkd | 7 +++++++ 3 files changed, 53 insertions(+) diff --git a/conf/example.conf b/conf/example.conf index 76db973..84ccff2 100644 --- a/conf/example.conf +++ b/conf/example.conf @@ -181,3 +181,26 @@ repo linux perl # give gitweb access as described above if you're specifying a description gitolite "Sitaram Chamarty" = "fast, secure, access control for git in a corporate environment" + +# REPO SPECIFIC GITCONFIG +# ----------------------- + +# (Thanks to teemu dot matilainen at iki dot fi) + +# this should be specified within a "repo" stanza + +# syntax: +# config sectionname.keyname = [optional value_string] + +# example usage: if you placed a hook in src/hooks that requires configuration +# information that is specific to each repo, you could do this: + +repo gitolite + config hooks.mailinglist = gitolite-commits@example.tld + config hooks.emailprefix = "[gitolite] " + config foo.bar = "" + config foo.baz = + +# This does either a plain "git config section.key value" (for the first 3 +# examples above) or "git config --unset-all section.key" (for the last +# example). Other forms (--add, the value_regex, etc) are not supported. diff --git a/doc/2-admin.mkd b/doc/2-admin.mkd index d0460ec..a93df4b 100644 --- a/doc/2-admin.mkd +++ b/doc/2-admin.mkd @@ -9,6 +9,7 @@ In this document: * adding users and repos * specifying gitweb and daemon access * custom hooks + * custom git config ### administer @@ -90,3 +91,25 @@ just run easy install once again; it'll do it to existing repos also. implements all the branch-level permissions in gitolite. If you fiddle with the hooks directory, please make sure you do not mess with this file accidentally, or all your fancy per-branch permissions will stop working.** + +#### custom git config + +The custom hooks feature is a blunt instrument -- all repos get the hook you +specified and will run it. In order to make it a little more fine-grained, +you could set your hooks to only work if a certain "gitconfig" variable was +set. Which means we now need a way to specify "git config" settings on a per +repository basis. + +Thanks to Teemu (teemu dot matilainen at iki dot fi), gitolite now does this +very easily. For security reasons, this can only be done from the master +config file (i.e., if you're using delegation, the delegated admins cannot +specify git config settings). + +Please see `conf/example.conf` for syntax. Note that this only supports the +basic forms of the "git config" command: + + git config section.key value # value may be an empty string + git config --unset-all section.key + +It does not (currently) support other options like `--add`, the `value_regex`, +etc. diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index 9a1d413..b824dec 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -19,6 +19,7 @@ In this document: * what repos do I have access to? * "exclude" (or "deny") rules * "personal" branches + * custom hooks and custom git config * design choices * keeping the parser and the access control separate @@ -530,6 +531,12 @@ first check: Just don't *show* the user this config file; it might sound insulting :-) +#### custom hooks and custom git config + +You can specify hooks that you want to propagate to all repos, as well as +per-repo "gitconfig" settings. Please see `doc/2-admin.mkd` and +`conf/example.conf` for details. + ### design choices #### keeping the parser and the access control separate From 780b4cca200cdee3c761215e4c949f2432fc8897 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Thu, 10 Dec 2009 17:07:46 +0530 Subject: [PATCH 6/6] ssh-copy-id workaround detail plus a couple other doc fixes --- doc/0-INSTALL.mkd | 13 ++++++++----- doc/3-faq-tips-etc.mkd | 44 +++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/doc/0-INSTALL.mkd b/doc/0-INSTALL.mkd index 106e415..af4022f 100644 --- a/doc/0-INSTALL.mkd +++ b/doc/0-INSTALL.mkd @@ -37,13 +37,16 @@ Assumptions/pre-requisites: * git is installed on that server (and so is perl) * you have a userid on that server * you have ssh-pubkey (**password-less**) login to that userid - * (if you have only password access, run `ssh-keygen -t rsa` to create a - new keypair if needed, then run `ssh-copy-id user@host`) + * if you have only password access, run `ssh-keygen -t rsa` to create a + new keypair if needed, then run `ssh-copy-id user@host`. If you do + not have `ssh-copy-id`, read doc/3-faq-tips-etc.mkd and look for + `ssh-copy-id` in that file for instructions * you have a clone or an archive of gitolite somewhere on your workstation + * if you don't have one, just run `git clone git://github.com/sitaramc/gitolite` -If so, just `cd` to that clone and run `src/gl-easy-install` and follow the -prompts! (Running it without any arguments shows you usage plus other useful -info). +Once you have all this, just `cd` to that clone and run `src/gl-easy-install` +and follow the prompts! (Running it without any arguments shows you usage +plus other useful info). #### typical example run diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index b824dec..b6c65d9 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -25,16 +25,25 @@ In this document: ### common errors and mistakes - * forgetting to suffix `.git` to the end of the reponame in the `git clone`. - This suffix is *not* used in the gitolite config file for the sake of - clarity and cleaner syntax, but don't let that fool you. It's a - convention in the git world that **bare repos** end with `.git`. - * adding `repositories/` at the start of the repo name in the `git clone`. This error is typically made by the *admin* himself -- because he knows what `$REPO_BASE` is set to and thinks he has to provide that prefix on - the client side also :-) In fact gitolite prepends `$REPO_BASE` when it - is required anyway, so you shouldn't do the same thing! + the client side also :-) In fact gitolite prepends `$REPO_BASE` + internally, so you shouldn't also do the same thing! + + * being able to clone but getting errors on push. Most likely caused by a + combination of: + + * you already have shell access to the server, not just "gitolite" + access, *and* + + * you cloned using `git clone git@server:repositories/repo.git` (notice + there's an extra "repositories/" in there?) + + In other words, you used a key that completely bypassed gitolite and went + straight to the shell to do the clone. + + Please see doc/6-ssh-troubleshooting.mkd for what all this means. ### git version dependency @@ -67,6 +76,27 @@ normal way, since it's not empty anymore. ### other errors, warnings, notes... + * don't have `ssh-copy-id`? This is broadly what that command does, if you + want to replicate it manually. The input is your pubkey, typically + `~/.ssh/id_rsa.pub` from your client/workstation. + + * it copies it to the server as some file + + * it appends that file to `~/.ssh/authorized_keys` on the server + (creating it if it doesn't already exist) + + * it then makes sure that all these files/directories have go-w perms + set (assuming user is "git"): + + /home/git/.ssh/authorized_keys + /home/git/.ssh + /home/git + + [Actually, sshd requires that even directories *above* ~ (/, /home, + typically) also must be `go-w`, but that needs root. And typically + they're already set that way anyway. (Or if they're not, you've got + bigger problems than gitolite install not working!)] + * cloning an empty repo is only possible with clients greater than 1.6.2. So at least one of your clients needs to have a recent git. Once at least one commit has been made, older clients can also use it