One day after I had successfully set up a subversion mirror and kept it in sync with svnsync through svn+ssh protocol as described here: http://blog.codefront.net/2007/03/31/setting-up-svnsync-ed-mirrored-svn-..., I would like to have the sync happen automatically everytime there was a commit. Oh, the blog didn't mention anything about svn+ssh protocol, but it was easily done following the subversion manual itself. So, I coded post-commit and post-revprop-change hooks as described here: http://journal.paul.querna.org/articles/2006/09/14/using-svnsync. However, as Chu Yeow mentioned in his blog that he settled with cron to do the sync because the hooks method didn't work, it also didn't work for me. Both machines were using GNU/Linux Ubuntu 8.04 Desktop.
Googling for several related keywords didn't turn up any useful result, so I tried to figure it out myself. The content of post-commit hook was as follows:
svnsync --non-interactive sync svn+ssh://10.0.0.103/var/lib/svn &
That didn't work. After three commits and manually performing the sync, I realized that the IP address was wrong since the machine didn't reside in the local network anymore. So, I changed it to:
svnsync --non-interactive sync svn+ssh://mydomain.com/var/lib/svn &
That didn't work either. After another commit and manually performing the sync, I realized that the IP address of the mirroring machine was dynamic not static. So, although I utilized public-private key authentication for the SSH session to avoid the interactive blocking password prompt, I was still prompted with a prompt like the following one:
The authenticity of host '202.192.33.21 (202.192.33.21)' can't be established. RSA key fingerprint is 36:da:77:63:d9:29:64:17:56:c5:d3:2c:98:fa:98:78. Are you sure you want to continue connecting (yes/no)?
Okay, I turned it off by doing:
$ echo "StrictHostKeyChecking=no" >> ~/.ssh/config
Still, it didn't work. Next, I realized that perhaps the command had to be written in full as follows:
/usr/bin/svnsync --non-interactive sync svn+ssh://mydomain.com/var/lib/svn &
Nope, it didn't work. Finally, I realized that because svnserve, which was the daemon that invoked the hooks, was owned by root, the hooks were executed with effective UID of root, and in turn, executed snvsync and started the SSH session as root. If the SSH session was started as root, surely the SSH would take its configuration from the home directory of root, not from the one of the user account in which I put the SSH private key and the SSH config file. So, I changed the command in the post-commit hook as follows:
sudo -u svn_admin /usr/bin/svnsync --non-interactive sync svn+ssh://mydomain.com/var/lib/svn &
This one works! To make the command in post-revprop-change hook work, simply just follow the same pattern.
To conclude, the following is the checlist to successfully run svnsync utilizing svn+ssh channel with post-commit and post-revprop-change hooks:
1. Ensure that the IP address of the mirror is correct.
2. Ensure that the IP address of the mirror is static. Otherwise, set SSH StrictHostKeyChecking to `no'.
3. Use a full path to the svnsync executable.
4. Use `sudo -u' to ensure that the correct home directory is used to find the SSH private key as well as the config file.
Keywords: ubuntu svnsync svn+ssh post hook
Ops, it needs -H as well
Hi Ho!
Some days ago the mirror server machine had an HD crash and so lost all of its data. Reinstalling everything up and setting up the mirror repository as well gave me a surprise: the post-commit synchronization described above didn't work anymore!
To find out the reason, I used the following command in the post-commit script:
It showed the following error message:
Curiously enough, previously my method really worked since I saw that the mirror stayed in sync before it crashed. Well, perhaps some package updates have caused this behavior to change.
In short, the problem lies on finding the proper home directory again as shown in the following output when the above command in the post-commit script was run with `strace':
lstat64("/root/.subversion/auth/svn.simple/9d93e889ee9e820bd678b559e707542c", 0xbf9ccf8c) = -1 ENOENT (No such file or directory)Okay, it turned out that `sudo -u testing-server-root' does not set the home directory to that of user testing-server-root. The fix according to the man page of `sudo' is to use `-H'. So, the complete new command is:
Heh, this is weird since without `-H', SSH can correctly find the public key of user testing-server-root in `/home/testing-server-root/.ssh/'. Well, I bet `svn' and `ssh' employ a different mechanism to determine the UID to find the proper home directory.
Best regards,
Eus (FSF member #4445)
In this digital era, where computing technology is pervasive,
your freedom depends on the software controlling those computing devices.
Join free software movement today!
It is free as in freedom, not as in free beer!
Join: http://www.fsf.org/jf?referrer=4445
Step-by-step
Hi Ho!
It turned out that the steps that I took to setup an SVN mirror repository has differred from my reference sources.
My setup is that the source repository resides in a private network and is accessed via svn:// while the mirror repository resides in the public Internet and is accessed via svn+ssh://. The mirror machine is setup within the local network, after which it will be deployed in the public Internet.
The steps are as follows:
That's it.
Best regards,
Eus (FSF member #4445)
In this digital era, where computing technology is pervasive, your freedom depends on the software controlling those computing devices.
Join free software movement today! It is free as in freedom, not as in free beer!
Join: http://www.fsf.org/jf?referrer=4445