It’s been almost a year since I discovered the joys of SVN post-commit hooks (I started by following this excellent and concise guide), but I never really gave it the time it wanted: now that I have, my scripts finally work flawlessly and I’m very happy with the result!
One of the things I’ve done is to monitor only some specific folders in my SVN repository, folders that contain files that I want to copy to another folder that is monitored using inotify (I have a server Java application that inspects these files and decides whether they’re “accepted” to be served to clients.. I plan to switch to Java 7 to test the new java.nio.file package, but for now I use a little
inotify bash script).
I needed a working copy of the SVN repository (well, just a branch actually), and I needed it to be updated whenever a file in one of the monitored folders is edited, added or deleted. So, I created a user called
svnuser that just pulls updates whenever the post-commit hook tells it to. At first I thought of named pipes as a means to have the two processes communicate: a daemon script always running in background launched by
svnuser waiting for notifications on a named pipe that are written by the post-commit hook; it seemed to work fine, but then I thought “wouldn’t it be easier if this script was launched by the post-commit hook itself?”.
It is 🙂
Post-commit hooks are executed by the user that is committing changes, so I had to use
sudo. To configure
visudo (or, equivalently,
vim /etc/sudoers as user root.. just remember to save the file using
:wq! to override the read-only setting).
User privilege specification section you should see this line
root ALL=(ALL) ALL
that means that user root can run any command (last
ALL) on any host (first
ALL) as any user (the
ALL between parentheses).
You can add your definitions at the very bottom of the file (they’re executed in order, so you can override a definition with a more specific one just by putting the overriding definition after the overridden).
You can use groups, too! Just put a
% symbol in front of the group name.
You can also apply a rule to a single command, or to a (comma-separated) list of commands by replacing the last
You can do a lot of stuff, actually, if you’re interested just dive into this page. I had to spend some time to figure out what I needed to do, so I hope that a little summary will help somebody.
I don’t want to force users to type their passwords every time that they commit some file to one of the “sensible” paths, so I included the
Here’s the final line:
%svngroup ALL=(svnuser) NOPASSWD: /home/svnuser/svnsync *
that means that any user in the group named
svngroup can run the
/home/svnuser/svnsync script as user
svnuser passing whatever parameter (last
*) and without having to input their
sudo password (
That’s it, now my post-commit hook just calls the
svnsync like this:
sudo -u svnuser /home/svnuser/svnsync $UPDATED_PATH