thanks to milki for all the efforts!
Details:
- partial-copy fell afoul of BSD not having $RANDOM
- test suite: fix bad GNU sort with good perl sort
- test suite: fix md5sum dependency (which BSD doesn't have or can't
easily have or requires extra options or whatever...), by doing it
in perl. (Requires Digest::MD5, which is probably available
anyway, but since this is only for the test suite, meh!)
I had not remembered that the 'tc' subcommand in tsh adds *text* that
contains the current time, so commit SHAs were changing.
Thanks to milki for catching this, and in fact being the only person who
ever appears to have attempted to run the test suite at all!
The POST_CREATE trigger is called when
* a user creates a new "wild" repo,
* a user uses the "perms" command, and
* a user uses the "fork" command.
The trigger calls 3 programs (see rc file):
post-compile/update-git-configs
post-compile/update-gitweb-access-list
post-compile/update-git-daemon-access-list
(They are also called by the POST_COMPILE trigger, by the way.)
However, the 3 programs shown are a bit wasteful -- they run through
*all* the repos when really only *one* repo has been affected.
This patch
* passes the repo name to the 3 programs (duh!)
* adds the optimisation to the first of the 3 programs listed above
(the one dealing with 'git config').
For the other two programs (gitweb and git-daemon), you have 3 choices:
* if you don't have too many repos, ignore the problem.
* take out the 2nd and 3rd lines from the POST_CREATE list in the rc
file, so they don't run.
Then run 'gitolite trigger POST_COMPILE' from cron at regular
intervals. (Note that is POST_COMPILE not POST_CREATE!) However,
this means that gitweb and daemon permissions won't be current
immediately after someone adds a new repo or sets perms etc.; they
get updated only on the next cron run.
* patch the programs to add this optimisation (and send me the
patches). The optimisation would check if arg-1 ($1 in shell,
$ARGV[0] in perl) is 'POST_CREATE', and if it is, take the *next*
argument as a repo name that may have changed.
gitolite setup fails to check admin pubkey, because $text always
contains 2 or more lines after tsh_try() (the key and -n).
[committer adds:
I wasn't sure if 'printf' would work on cygwin, so I chose what
looked like a safer option, but apparently it wasn't safe enough and
fell afoul of Solaris.
Anyway I managed to check (using a small test program) with someone
who runs gitolite on cygwin, and it works.
If you're wondering why I didn't just use echo followed by chomp(),
that would of course have been the easy way out but I wanted to see
how you'd do it without a post-processing option. It became a
frustrating challenge of sorts because it seems such a trivial thing!
]
The fix is easy enough, but I hate having to code work-arounds for
proprietary OSs when the same code works fine on Linux and BSD.
/me wisely avoids words like posix in his rant ;-)
Thanks to Franck Zoccolo for help in finding what the problem was and
when and why it occurred.
----
Someday there will be some issue that requires a fix with significant
code change (or worse, a change that is incompatible with Linux), and I
will probably refuse. Of course, I will be properly regretful about my
inability to fix it.[1]
I must have blindly converted from some shell-thinking/shell-code for
these to have slipped through!
(found when doing an audit of all system, exec, ``, qx, and tsh_)
(manually tested, no test script)
the whimsically named "D" command deletes repos, and is the opposite of
the "C" permission that enables the user to create one in the first
place. See the usage message for user info, and look in the comments of
the code itself for admin info.
- minor typo fixes, clarifications, etc.
- keep sts.html url consistent, because many people link to
http://sitaramc.github.com/gitolite/sts.html
- create a common migration doc, so the old 'migr.html' does not 404
when g3 docs become "main"
- progit doc done
- add gitosis convert script (FWIW)
- a minor comment fix to Sugar.pm
...now that triggers are not restricted to external programs and can be
perl code called by gitolite-shell (thus in the same PID), there's no
need to compute and pass along the times() array.
This also changes the arguments to POST_GIT; they're now the same as
PRE_GIT's.
I don't know why I had put VERSION in GL_ADMIN_BASE, which is pretty
stupid. It should be in GL_BINDIR.
It also has nothing to do with setup -- the file needs to be generated
at 'install' time.
because the loop in the code below was sending out $repo =
'./gitolite-admin.git' to hook_1(), inside which there is an explicit
check for 'gitolite-admin', which of course doesn't match
'./gitolite-admin'!
someone reported an error on "my $_" (presumably old perl) but I now
realise the whole map is useless; both the lists concerned have already
been chomped.
...there was one real bug, plus I had forgotten to put a comented out
line in the rc file, but most of the rest of the effort was moving the
test script over.
oh and I'd also forgotten to move this from 'commands' to 'triggers' :-)
...otherwise 'gitolite help' was getting too confusing, mixing up stuff
that users should not be running directly (even on the server)
----
implementation notes:
those who are worried about the '../triggers/' in various parts of the
code here, remember you can only do that from a command line on the
server. Remote users can only use commands that have been explicitly
listed in the COMMANDS hash in the rc file. This means they can't even
access other commands in the same directory as, say, the 'info' command,
so a '../' is definitely not going to work.
For example, in
repo foo/..*
C = u1 u2 u3
RW+ = CREATOR
RW = WRITERS
R = READERS
config hooks.emailprefix = '[%GL_REPO] '
config foo.bar = bar one
repo foo/u1/..*
config bar.baz = frob nitz
make that last config also work!
non-core programs can get their settings from the rc file also.
cpu-time is a perl example and desc is a shell example.
(info is not a good example because it does not use "Gitolite::Easy")
- a remote "id" (usually the IP) is generated and logged on the first
log message in a "transaction"
- speaking of which, a new "transaction ID" is logged that stays the
same for each input command/invocation, tying together all the
spawned commands
- so now time stamps can be generated each time they are needed,
rather than re-use the one at the beginning
- log messages have a keyword at the start now
remote, (create), check1 -- from gitolite-shell
update, check2 -- from update
post-up -- from post-update
command -- from gitolite
die, system -- from anywhere
(and the other Dan Carpenter finding too, while we're about it!)
Note that neither of these is an actual issue, (and even less likely now
that gitolite is pure perl and no shell metas used) but it's just
playing safe.
- new Gitolite::Easy module hides all the other stuff
- (put GL_ADMIN_BASE and GL_REPO_BASE into %ENV)
- new 'gitolite creator' shell command
- 'writes' command modified to use Gitolite::Easy. It is also the
only dual mode command -- it can be invoked remotely as well as
locally. I deem that the required trick to make other remote-only
commands work locally is too much trouble for what is probably a
rarely used command.
- don't look for user-roles if the repo is missing (doesn't make sense
and because we roll in the <perm> = CREATOR function into that, it
causes bugs like [1] below)
- allow ^CREATOR/ in repo names (i.e., don't insist it has to be
/CREATOR/)
----
[1] here's the bug
repo foo/..*
C = u1
RW+ = CREATOR # <--- this line
R = READERS
RW = WRITERS
causes
GL_USER=u2 gitolite info
to print
hello u2, this is gitolite3 (unknown) on git 1.7.7.6
R W foo/..*
R W testing
when in reality it should not be looking at CREATOR at all.
(although the opposite case is still a "die")
We found out how this can happen: if you change
repo r1 r2
to
@g = r1 r2
repo @g
as found by t/deleg-2.t, which suddenly started breaking after an
apparently unrelated commit :-)
new triggers:
- PRE_GIT and POST_GIT in gitolite-shell
- PRE_CREATE and POST_CREATE when a new wild repo is created
- (POST_COMPILE had already existed)
- ACCESS_CHECK triggers both in gitolite-shell and the update hook
- trace() learned to print the file name if called from top level and
a function name is not available
note: trigger was called 'run-all' and only had POST_COMPILE. The code
existed in gitolite-shell, but is now moved to Rc.pm.
when a real repo (i.e., not a groupname or such) doesn't exist, checking
any permission other than ^C will give invalid results unless ^C is ok
for the user in question.
Take a look at this:
repo foo/CREATOR/a[0-9][0-9]
C = u2 u3
RW+ = CREATOR
R = READERS u1
u1 looking for R access on foo/u1/a11 will otherwise result in
success.
implementation notes
- new sugar role_names() to prefix an "@" to CREATOR, and any role
names listed in the rc file.
- invalidate the cache in rules() if the repo was missing. Without
this, an auto-create operation succeeds the ^C check and calls
new_wild_repo(), but then -- due to the cached rules not containing
a rule for CREATOR, the actual read/write fails.
- treat roles (READERS, WRITERS, etc.) as group names that apply only
to that particular repo. Don't add them to %groups, because that
would screw up caching, but add them in when memberships() is called
for the user.
This is why the membership call for the user also has a reponame
tacked on -- i.e., a user's membership list varied depending on
which repo you're talking about.
- while we're about it, pretend we added "CREATOR = <content of
gl-creator>" as another "role". Makes things so much easier dealing
with "RW+ = CREATOR"
- searching for rules pertaining to foo/CREATOR/bar when looking at
repo foo/sitaram/bar is done backwards from what g2 used to do. G2
used to play tricks with the do-eval'd file using global variables
so that what you get after the do may not even contain 'CREATOR'.
We go the other way. We replace sitaram with CREATOR and start
looking for memberships of *both* foo/sitaram/bar and
foo/CREATOR/bar.
- this doesn't work (because we don't know *what* to replace) for
missing repos if GL_USER is not set. This means that 'gitolite
access ...' queries (which do not set GL_USER) cannot be used
reliably for non-existant repos.
Since a ^C check is the only meaningful one for a non-existent repo,
this means you cannot do that from 'gitolite access'.
'GL_USER=luser gitolite info' will still work though ;-)
all in all, much cleaner and simpler than g2.