SVN Authentication and Auto Update

November 24, 2007

During the first two parts of my series on setting up a Media Temple dedicated server, I setup subversion (SVN) on apache. Now I want to show you how I setup basic authentication and a SVN hook to automatically deploy files to the server (called continuous integration). This is great because you can check in your files to SVN and see them on the server immediately.

Adding Basic Apache Authentication to your Subversion (SVN) Repository

First lets give apache access to the SVN database (the $ symbol just means it is a shell command).

chmod g+s /svnroot/db

Now create a password file with htpasswd, name the file whatever you would like. I chose to make my file hidden by adding the period before the name.

htpasswd -cm /etc/.htaccess yourusername

It will prompt you for your password. Now go back to your httpd.conf and than add the last four lines below to your Location code block- we are adding to what we did in part 2 of the media temple setup series.

<Location /svn>
DAV svn
SVNParentPath /usr/local/svn
AuthType Basic
AuthName "Subversion repository"
AuthUserFile /etc/.htaccess require valid-user
</Location>

For security reasons, we also need to make sure and hide the .svn folders from having apache publicly display them:

  1. Disallow browsing of Subversion working copy administrative dirs.
<DirectoryMatch"^/.*/\.svn/">
Order deny,allow
Deny from all
</DirectoryMatch>

Restart apache and when you try to access SVN you should be prompted for authentication. Great, SVN is now secure! You can also add more security by adding SSL to your dedicated server .

Creating a Subversion (SVN) Hook to Auto Update Your Server

I want to automatically deploy my files to my httpdocs without having to manually go in and update the files. So to accomplish this you need to create a SVN hook that runs after every commit .

First, copy the post-commit template from your svnroot/hooks folder. And lets also use chmod to give the file rights to execute.

cd /svnroot/hooks/ cp post-commit.tmpl post-commit chmod +x post-commit

Now we need to create a little C program. You should have GCC installed. This will compile our little C program. Create a new svnupdate.c file and put this code in. Don’t forget to change the directory path: "public_html_directory"

#include<stddef.h>
#include<stdlib.h>
#include<unistd.h>
int main(void) {
execl("/usr/bin/svn","svn","update","/public_html_direcotry/", (const char *) NULL);
return(EXIT_FAILURE);
}

Complile the file with this command. It will take the whatever.c and compile it into a binary file.

gcc -o svnupdate svnupdate.c

Try executing the binary to see if it works with the env command.

env – ./svnupdateAlright

now copy the whatever binary into your hooks folder. And we’ll also run a couple commands to give it proper priveledges:

 cp whatever /svnroot/hooks 
cd /svnroot/hooks
chown root:root svnupdate
chmod +s svnupdate

Then lets tell the post commit hook to run our binary file name,“svnupdate”.

vi /svnroot/hooks/post-commit

Inside it the post-commit hook tell it to run the binary using the absolute path:

/svnroot/hooks/svnupdate

Test it out by checking in a file to subversion. It should automatically update at the directory we set in the C program.

33 comments

#1. Kolky on March 04, 2008

Thanks for the hook script, been searching for this for ages!

#2. Dallas Clark on May 08, 2008

I’m receiving the error “the directory is not a working copy” which leads me to these questions.
Does the “public_html_directory” need to be the full file path?
Does the location of where you want your SVN to be copied to need to be a checked out svn directory?

#3. Dallas Clark on May 08, 2008

haha! why my message submitted 3 times, I don’t know
I realise yes it has to be a checkout directory of the SVN, but it’s still not working, possibly permission errors but I’m not sure. When someone commits to the SVN and it executes the post-commit file, does it execute it as apache or the user?

#4. Marc on May 09, 2008

I’m not sure what user it executes as.

#5. Toti on May 11, 2008

Subversion executes hooks as the same user who owns the process which is accessing the
Subversion repository. In most cases, the repository is being accessed via a Subversion server, so this user is the same user as which that server runs on the system.

#6. Toti on May 11, 2008

The hooks themselves will need to be configured with OS-level permissions that allow that user to execute them. Also, this means that any file or programs (including the Subversion repository itself) accessed
directly or indirectly by the hook will be accessed as the same user. In other words, be alert to potential permission-related problems that could prevent the hook from performing the tasks it is designed to perform.

#7. Toti on May 11, 2008

Marc thanks for the article although that’s a bit all over the place and it’s not very clear. For instance when you say “Create a new whatever.c file and put this code in. Don’t forget to change the directory path.” …change directory path of what? There is no mention of where to create the file in the 1st place :P

#8. Toti on May 11, 2008

…And here I am lost:
Compile the file with this command. It will take the whatever.c and compile it into a binary file.
gcc -o svnupdate svnupdate.c
(Wait wasn’t I compiling whatever.c? Why the command reads svnupdate.c? Should I rename whatever.c to svnupdate.c??)

#9. Toti on May 11, 2008

Try executing the binary to see if it works with the env command.
$ env – ./updatesvn
(After compiling with gcc the resulting compiled binary should be called “svnupdate” why should I try to use “updatesvn” with the env command?)
Alright now copy the whatever binary into your hooks folder. And we’ll also run a couple commands to give it proper priveledges:
I am really lost… could anyone summarize a step by step process for dummies?
Thanks!

#10. Toti on May 12, 2008

By the way what’s the syntax to place in the post-commit to make it run the compiled binary?

#11. Marc Grabanski on May 19, 2008

@Toti: /public_html_direcotry/ is the directory path in the C code.
whatever.c was meant to mean name it whatever you want. svnupdate.c was what I named it.
Note this article was logged for my own memory and wasn’t meant to be the end all article. It is a compilation of notes on the subject into a format that is hopefully helpful.

#12. Darko Ljubic on May 30, 2008

Script never managed to update a working copy due to permissions issue. It kept trying to do svn update as apache user.
After a little tweaking of C program, this is the solution I came up with:
int main(void) {
execl(“/usr/bin/svn”, “svn”, “update”,
“/public_html_direcotry/”,
“—username”, “autoupdater”,
“—password”, “autoupdater_password”,
(const char *) NULL);
return(EXIT_FAILURE);
}
Notice, I only added username and password of a svn user to the original script .

#13. Philip on June 11, 2008

Will this method work across servers? I have a standalone svn server and I want to automatically update.

#14. zyk on August 05, 2008

What if the destination directory to updat is on another computer , will changing the parameter of the function “/public_html_direcotry/” to be “root@192.168.200.55:password” work ? if not , what is the right to do ?
thx

#15. Marc Grabanski on August 05, 2008

I’m not sure, zyk. All you can do is try and see if it works.

#16. Andrej Pintar on November 03, 2008

Hello.
I lost a few days on configurng SVN hooks for a test repository.
Scheme:
1. SVN repo (Server1-Centos)-Mounted Share
2. Develop server (Server2,Apache2,PHP)-Windows2000,Server, Shared Folder
So I mounted Development Site inside centos using cifs mount. Works great. And SVN update was
messing me around because of these permissions. When Loaded in terminal works fine. I got Log and Echo and everything set up fine. But when updated using SVN clients(RapidSVN,Tortoise on Windows) hooks did not execute. However they did execute only ECHO commands.

echo “SVN START:” > /tmp/svn.log #Works
#svn update /mnt/a/temp/a —non-interactive —username xxxx —password xxxx >> /tmp/svn.log#Doesnt work
/srv/uniline/repositories/its/hooks/svnupdate >> /tmp/svn.log #Works
echo “SVN END” >> /tmp/svn.log #Works
/mnt/a/temp/a is just a folder i tested to update (not whole site until i see that autoupdate is ok).
sou you need to mount share as:

  1. mount -t cifs //web1/dev08$/ /mnt/site -o username=Administrator,password=xxxxxxx,rw

    Thanks for the C code for making autoupdate work that way.
#17. Josh Friesen on March 18, 2009

Good info dude. Found this while trying to refresh my memory on SVN

#18. Alvin on March 20, 2009

I have used the auto update as instructed which works fine with a commit done on the linux system but when the commit is done from the windows system (using TortoiseSVN ) i get an error svn: Can’t convert string from native encoding to ‘UTF-8’:
is there a solution to the same

#19. Mudassir Aftab on June 01, 2009

Hi all

Thanks for great document

My postcommit hook is not working , i follow your step by step guide , i have auth base access to my svn site which is running on port 443 , Also i used diffrent documents but no success ,please suggest where i am lacking

#20. TeckniX on June 26, 2009

I edited a little bit of the post-commit hook.
Since I had multiple svn repository/branches, I figured I’d apply somewhat of a filter, so that the auto svn update would only run on a certain svn branch – Here’s my script:

#!/bin/sh
# POST-COMMIT HOOK
#

svnlook="/usr/bin/svnlook"
REPOS="$1"
REV="$2"
DIR=`$svnlook dirs-changed $REPOS -r $REV`

echo `date +"%Y%m%d-%H:%M:%S"` >> /var/log/svn_commit

if [[ "$DIR" == trunk ]]; then
/svnroot/hooks/svnupdate >> /var/log/svn_commit
fi
#21. Marc Grabanski on June 26, 2009

thanks! good tip

#22. Valeeum on August 25, 2009

Every time I run the “env – ./svnupdate” command, I get the following message:

Skipped ‘/public_html_direcotry/’ (public_html_direcotry is replaced with the actual html dir)

The script doesn’t work on a commit either.

Any ideas what may be wrong?

#23. Marc Grabanski on August 25, 2009

That means you don’t have a svn repository where the script is executing on. Try to manually update the directory and sort that out first before trying to add the svn hook.

#24. Valeeum on August 26, 2009

Thanks for the tip and the great tutorial. I figured it out! I had to checkout my repo to the public_html_dir before I could use the update command. You rock!

#25. Debugged Interactive Designs on October 22, 2009

We wrote a similar article for the DV 3.5 servers, enjoy : http://www.debuggeddesigns.com/blog/view/how-to-setup-a-subversion-svn-repo-on-a-media-temple-dv-3.5-server

#26. Valeeum on February 23, 2010

How would I be able to integrate your approach with the following command I found on the net:

cd /home/www/dev_ssl
svnlook dirs-changed [REPOS] -r [REV] | xargs /usr/bin/svn up -N

The reason I’m interested in this is because the original approach outlined in this post takes a little bit of time to update (sometimes up to a couple minutes) since I have one big repo for all of my projects. I read that the above command only updates those directories that have been changed. However, no matter what I try, it doesnt seem to work properly.

The source for the above code is from:
http://stackoverflow.com/questions/446518/using-svn-post-commit-hook-to-update-only-files-that-have-been-commited

#27. John P. Barbagallo on April 04, 2010

Would this work for the gridservice?

#28. 2 Factor Authentication on April 16, 2010

This is a great resource for improving your authentication services for linux and other platforms.

#29. Evgeny A. Gushchin on August 22, 2010

Why can’t I just tell the post-commit hook to run
svn up /public_html_direcotry/
instead of creating the binary?

#30. Marc Grabanski on August 22, 2010

Good question Evgeny, have you tried it? The reason I did it this way is because of the user permissions. The post-commit hook runs as a different user than if ran through the binary.

#31. segfault on September 18, 2010

Thanks for a useful post. I’m not sure I saw what I think I saw:

A C++ program that needs to be compiled to… update a SVN checkout :)) Sir, you are seriously twisted ;))

#32. Paola on October 09, 2010

I want automate svn update on windows, using task scheduler
Give more info on a bat script to execute svn update! Tnx!

#33. Lourens on January 14, 2011

About the authentication issues some people may be having, see:
http://www.svnforum.org/threads/34952-post-commit-hooks-not-running.?p=103872&viewfull=1#post103872

Remember to co the working copy as file:///path/to/repo/project instead of http://path/to/repo/project
and then
chown -R apache:apache /path/to/working/copy
and make sure the svnupdate binary is SUID apache (same user that owns local wc)

Leave a comment

Comment in textile images by gravatar