(thanks to Kevin Fleming for the need/use case)
TODO: tests
TODO: proper documentation; meanwhile, just read this:
- you can give gitweb and daemon read rights to wild card repos also,
and it'll all just work -- when a new repo is 'C'reated, it'll pick
up those rights etc
- you can assign descriptions (and owners) to individual repos as
before, except now you can assign them to repos that actually were
created from wild card patterns. So for example, you can define
rules for
repo foo/..*
and then assign descriptions like
foo/repo1 = "repo one"
foo/repo2 = "repo two"
foo/dil "scott" = "scott's dilbert repo"
However, this only works for repos that already exist, and only when
you push the admin repo.
Thumb rule: have the user create his wild repo, *then* add and push
the admin config file with the description. Not the other way
around.
implementation notes:
- wildcard support for git config revamped, refactored...
it's not just git config that needs wildcard support. daemon and
gitweb access also will be needing it soon, so we start by factoring
out the part that finds the "pattern" given a "real" repo name.
- GL_NO_DAEMON_NO_GITWEB now gates more than just those two things;
see doc/big-config.mkd for details
- we trawl through $GL_REPO_BASE_ABS *once* only, collecting repo
names and tying them to either the same name or to a wild pattern
that the repo name was created from
- nice little subs to setup gitweb, daemon, and git config
- god bless $GL_REPOPATT and the day I decided to set that env var
whenever a user hits a wild repo in any way :-)
- the code in gl-compile-conf is very simple now. Much nicer than
before
make it a sort of "super global" (an ENV var) all through, because
*everyone* seems to need it *and* this variable is pretty much constant
for the entire install
conf/example.gitolite.rc
- "slave mode" flag to disable pushes and "list of slaves"
hooks/common/post-receive.mirrorpush
- code to push to the mirror, creating the repo if needed
src/mirror-shell
- shell for master pushing to a slave, because we don't actually want
to go through gitolite itself, yet we have to take care of
$REPO_BASE being wherever. And of course we have to set
GL_BYPASS_UPDATE_HOOK to 1 for the push to happen!
src/gl-mirror-sync
- manually runnable program to sync from current server to another
allows a default 'setperms' string to be set for new wildcard
repositories.
Also, fix a bug in the fork script where a failure in the git command
would still cause the rest of the script to attempt to run.
The log message format has changed. All log messages now have a common
prefix (timestamp, user, IP). This is followed by $SSH_ORIGINAL_COMMAND
(or, in one special case, the name of the user's login shell). Any
further text appears after this (currently this only happens in the case
of a successful push -- one for each ref pushed successfully)
[Please NOTE: this is all about *user* groups, not *repo* groups]
SUMMARY: gl-auth-commmand can now take an optional list of usergroup
names after the first argument (which is the username).
See doc/big-config.mkd in the next commit or so
If you have many thousands of repos and users, neatly organised into
groups, etc., the normal gitolite fails. (It actually runs out of
memory very fast while doing the "compile" when you push the config, due
to the number of combinations of repo/user being stored in the hash!)
This commit series will stop doing that if you set $GL_BIG_CONFIG = 1 in
the rc file.
Some notes:
- deny rules will still work but somewhat differently -- now they must
be placed all together in one place to work like before. Ask me for
details if you need to know before I get done with the docs
- I've tested most of the important features, but not every single
nuance
- the update hook may be a tad less efficient now; we can try and
tweak it later if needed but it shouldn't really hurt anything
significantly even now
- docs have not been written yet
Ouch! How mortifying :) I'd always thought this was one of the Brit/US
differences, but to find out that it really *isn't* a word... hmph!
Anyway, in the interest of not breaking existing wild repos, the
ownership file is still called "gl-creater". Everything else has been
changed.
(...thanks to Sverre)
The "fork" adc cannot simply do a "git clone..."; hooks and gl-creater
won't get set up. We need a way to initiate the *creation* of a repo
from a shell command, and then fetch the refs over.
For a long time, we used to trick gitolite into creating a repo for us
by simply using "git ls-remote host:reponame" ;-) Now we have an actual
command, so we can say "ssh git@server git-init \'reponame\'"
Yes; those single quotes are required. Deal with it.
This commit series allows an admin to designate a set of commands that
users can run. For example, he can allow users to delete a repo that
they have created:
ssh git@server rmrepo foo/me/bar
or fork (to use github's terminology) a repo they have "R" access to,
into a new one they have "C" access to:
ssh git@server fork foo/someone-else/bar foo/me/bar
Please see documentation for details
----
(this commit)
- (rc) new variable $GL_ADC_PATH; without this none of this is enabled
- (pm) new helper routine "cli_repo_rights" to get rights/ownership
from outside
- (auth) call $GL_ADC_PATH/$cmd if it exists
This commit series refactors all the rights querying logic.
- old repo_rights sub renamed to wild_repo_rights
- new repo_rights sub to be a single entry point for most rights
queries
- callable from gl-auth-command and expand_wild
- callable from *outside* too, as long as $ENV{GL_USER} is set
- the format of the returned permissions contains C, R, and W as
applicable, with sigils reflecting the 3 possible ways in which you
can get R or W perms (2 ways for C):
@R means @all users have the same access
#R means you're a "super user" (think root's shell prompt) so
you can see all repos
R is the normal, explicit, access
All this is about a user trying to look if a repo exists or not, when he
does not have any access to that repo. Ideally, "repo does not exist"
should be indistinguishable from "you dont have perms to that repo".
(1) if $GL_WILDREPOS is not set, you either get a permissions error, or
a "$repo not found in compiled config" death. Fixed.
(2) if $GL_WILDREPOS is set, you either get either a permissions error,
or a "$repo has no matches" death. Fixed.
(3) The following combination leaks info about repo existence:
- actual repo doesn't exist
- spying user don't have C perms
- repo patt doesn't contain CREATER
- RW+ = CREATER is specified (as is normal)
In such case, the "convenience copy" of the ACL that parse_acl
makes, coupled with substituting CREATER for the invoking user means
$repos{$actual_repo} has RW+ for the spying user. This means the
access denied doesn't happen, and control passes to git, which
promptly expresses it unhappiness and angst over being given a repo
that 'does not appear to be a git repository'
This doesn't happen if all those conditions are not met:
- if repo exists, CREATER is set to the real creater, so RW+ =
CREATER does not gain spying user anything
- if spying user has C perms it just gets created, because he has
rights. This is also info leak but we can't prevent it; tighten
the config (maybe by including CREATER in repo pattern) if this
is not wanted
- if repo patt contains CREATER it will never match someone else's
repo anyway!
a configuration like this:
repo CREATER/.*
C = CREATER
RW+ = WRITERS
was buggy; CREATER was implicitly part of WRITERS so he got RW
permissions implicitly, so the push went through
- no need to put it at the end of the config file now, yeaaay!
- @all for @all is meaningless and not supported. People asking will
be told to get a life or use git-daemon.
- NAME/ limits for @all repos is ignored for efficiency reasons.
Currently the pattern of expand command is line anchored. This is
different than in e.g. grep, and causes extra work to add '.*' prefix
and/or suffix in many use cases.
The new semantics now mean you might get more matches than you would
have gotten earlier. However, the expand command is still totally
undocumented, so I think it is acceptable to change the functionality.
;)
This patch removes the anchoring. So for earlier behavior the specified
pattern needs be in form of '^<pattern>$'. The default pattern is also
changed from '.*' to '^', so there might be even a small speed
improvement. =)
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
The wildrepos branch has been merged into master, and deleted. It will no
longer exist as a separate branch. Instead, a new variable
called $GL_WILDREPOS has been added which acts as a switch; when
off (which is the default), many wildrepos features are disabled.
(the "C" permissions, and the getperms (etc.) commands mainly).
Important: if you are using wildrepos, please set "$GL_WILDREPOS = 1;" in
the RC file when you upgrade to this version (or just before you do the
upgrade).
Allow users to set and display description (for gitweb) for their
own wildcard repositories using ssh commands:
setdesc <repo>
getdesc <repo>
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
brought on by realising that you lost $shell_allowed when refactoring
(previous commit) but perl hadn't caught it because -- damn -- you
didn't have "use strict" in gitolite.pm
lots of conflicts, esp in gl-auth-command, due to refactoring the
"special commands" stuff on master
Conflicts:
doc/3-faq-tips-etc.mkd
src/gitolite.pm
src/gl-auth-command
src/gl-compile-conf
great idea by Robin Smidsrød: since users are already capable of
authenticating themselves to gitolite via ssh keys, use that to let them
set or change their own HTTP passwords (ie, run the "htpasswd" command
with the correct parameters on behalf of the "git" user on the server)
code, rc para, and documentation. In fact everything except... ahem...
testing ;-)
and while we're about it, we also reorganised the way these helper
commands (including the venerable "info" are called)
This is actually a pretty big deal, and I am seriously starting wonder
if calling this "gito*lite*" is justified anymore.
Anyway, in for a penny, in for a pound...
This patch implements a generic way to allow access control for external
commands, as long as they are invoked via ssh and present a server-side
command that contains enough information to make an access control
decision.
The first (and only, so far) such command implemented is rsync.
Please read the changes in this commit (at least the ones in conf/ and
doc/) carefully.
- see *all* wildcard repos you have access to (this uses line-anchored
regexes as described in doc/4). Examples:
ssh git@server expand '.*'
ssh git@server expand 'assignment.*'
- show perms like the info command does
Please see comments against 02cee1d for more details and caveats.
gitolite specific ssh commands ("getperms", "setperms", "info" etc.)
should exit with non-error code in case of success.
Also "get/setperms" should print to STDOUT instead of STDERR.
This change is specially needed for the gitolite-tools
(http://github.com/tmatilai/gitolite-tools) to work.
Signed-off-by: Teemu Matilainen <teemu.matilainen@reaktor.fi>
for those not yet able to upgrade (or until I merge this into the branch
you care about), if you have a repo called, say "bk2git", just refer to
it as "bk2git.git" in the clone command!
[Thanks to Mark Frazer for finding this...]
we've removed the facility of auto-viving "W" access repos when they are
not wildcards. A wildcard pattern like foo/CREATER was
indistinguishable from a non-wildcard repo, and resolving it was
becoming kludgier and kludgier. (See the revert in the commit before
this one for details).
As a side effect of not being able to distinguish wildcard repos from
real repos easily, the expand command now works for a normal repo too
(because we have to make it work for "foo/CREATER")
".../gl-auth-command username" is the normal command that authkeys
forces, and this prevents that key from being used to get a shell.
We now allow the user to get a shell if the forced command has a "-s"
before the "username", like ".../gl-auth-command -s sitaram".
(Now that a plain "ssh gitolite" gets you a shell, there's a new "info"
command that such privileged keys can use to get basic access info).
Thanks to Jesse Keating for the idea! I can't believe this never
occurred to me before, but I guess I was so enamoured of my "innovation"
in converting what used to be an error into some useful info I didn't
think a bit more :/
Looks like I'd forgotten this when I did the autoviv code. Repos
created via gl-compile (when you add a new repo to the config file and
push) worked fine, but repos created via gl-auth (when you autoviv a
repo, wild or not) did not.
This *should* be merged into wildrepos soon after testing; wildrepos
will have a lot more autoviv-ing than master.