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 '220.127.116.11 (18.104.22.168)' 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