Ryan Kanno: The diary of an Enginerd in Hawaii

Everything you've ever thought, but never had the balls to say.

My LinkedIn Profile
Follow @ryankanno on Twitter
My Feed

Dreamhost + Subversion + Post-Commit Tutorial

Update

According to Jeff, Dreamhost has disabled setuid for home directories – which they probably should’ve done years ago. :) As a side note, some other alternatives include the following:

In any case, I’ve since moved half my sites to WebFaction so if you know of a solution, post it in the comments and I’ll write a new blog post about it. :)


Since Dreamhost has integrated Subversion into their services, I finally decided to take the leap and move my local repository to my hosted account. After all, I was tired of always having to remember to transfer my updated files via scp. With my repository moved over to Dreamhost, I figured I would take advantage of Subversion’s post-commit hooks to automagically update my live beta site.

After reading a myriad of solutions (like here and here ), I found the Dreamhost wiki entry the most helpful. So without further adieu, here’s a small, quick and dirty tutorial on how to automagically get post-commit working with Subversion on your Dreamhost account.

The setup

The very first thing you need to do is create a directory on your Dreamhost account to checkout the source files to (I’m assuming you’ve already created your Subversion repository, have checked files into it, and are ssh’ed into your Dreamhost account.). In my situation, I created a subdomain in Dreamhost called beta.localkinegrinds.com. Dreamhost automatically creates a directory named beta.localkinegrinds.com within the root of the admin account. I cd’ed into that directory and issued the following command:

svn co PATH_TO_FILES_IN_REPOSITORY . --username USERNAME --password PASSWORD

Once checked out, I switched into my Subversion repository directory; it was named svn in the root of my admin account. From there, I went into my named repository, and then into the ‘hooks’ directory.

Here’s where all the fun begins!

First, I created a script called ‘post-commit.script’ that looked like the following:

#!/bin/sh
/usr/bin/svn up PATH_TO_DIR --username SVN_USERNAME --password PASSWORD

I exited my text editor, then issued the following command:

chmod +x post-commit.script

From reading all the forums, the main issue with the post-commit hooks is that svnserve will run the hooks as the Apache user; in Dreamhost’s case, the dhapache user. Thus, we have the following options as described here. We can:

  1. Run password-less sudo (which we don’t have access to on Dreamhost)
  2. Change the group permissions (which we don’t have access to on Dreamhost)
  3. Checkout the files as the dhapache user from a post-commit hook, then change it to update as described here (which I thought was a pain in the rear, not to mention having the directory be world writeable)
  4. Compile a small C program with its setuid bit set

Being the programmer that I am, I chose the last option. Basically, as Wikipedia describes, “when a binary executable file has been given the setuid attribute, normal users on the system can execute this file and gain the privileges of the user who owns the file (commonly root) within the created process.” This means that even though the Apache user will run the post-commit hook, it’ll assume the privileges of the user who owns the file (my account) and be able to execute the post-commit.script file we just created!

Neat!

So… taking a look at the Dreamhost wiki, I created the following c program named post-commit.c

#define PATH_TO_POST_COMMIT_SCRIPT "/PATH/TO/POST_COMMIT.SCRIPT"
#include <sys/types.h>
#include <unistd.h>
main( ac, av ) char **av;
{
  execv( PATH_TO_POST_COMMIT_SCRIPT, av );
}

I then issued the following command to compile the program into a binary called post-commit:

gcc -o post-commit post-commit.c

And then to set the setuid bit on the post-commit file:

chmod 4755 post-commit


Voila!

Assuming you set all the correct paths, on a commit to your Subversion repository – your live site will be updated!

As a side note, most of the sites previously mentioned didn’t have any troubleshooting tips. Here’s a few that I ran into along the way:

  1. Always test the scripts out first, ie, execute them from the command line and make sure they are doing what you want them to.
  2. Apparently, according to the Subversion book, “Subversion repository executes hook scripts with an empty environment.” This is something good to know.
  3. If everything was done right, and it’s still not working, try to update your checked out Subversion directory. Sometimes you need to clean up before any other updates can occur. That problem took me a whole half-an-hour to figure out. :)

In any case, if done correctly, you’ll be on your way to a better development environment!

Popularity: 42% [?]

  1. But you still love me. :)

  2. Hey – thanks for the post! Was struggling with getting it to work with dreamhost, but hit this before finding it on the dreamhost wiki. I can update repositories now, but for some reason it doesn’t send an email except when executed from the command line!

    One thing you might want to do / note: configure apache so people can’t browse your .svn directories: see http://subversion.tigris.org/faq.html#website-auto-update. Also, because on dreamhost we don’t have access to httpd.conf, just need to pop this in an .htaccess file:
    Options +FollowSymLinks
    RewriteEngine on
    RewriteRule \.svn/ – [F]

    cheers

  3. Justin,

    I’m glad something I wrote actually helped someone in the same predicament. Thanks for the .svn tip, I really need to do that. :)

  4. [...] followed my own tutorial and created a post-commit hook to update the appropriate Dreamhost directories when I committed to [...]

  5. This post was quite helpful. I’ve spent the better part of the day fighting with this. This helped me to get the update of the site working, but I have finally given up on getting site update + update e-mail working together. The problem appears to be that an expected argument is getting overwritten when the new script is called, for example the repository path. The revision number is still there. I hard-coding the repository path into the script and this made it get a bit further, but then it was throwing up on the revision number for some reason, even though I have verified it is the right value. I think maybe the commit-email.pl script is expecting to have access to the command params or something, beyond the arguments provided. That’s about as far as I’m gonna go on this. I think the optimal solution might actually involve coding the entire damned script in C as a part of the original set uid executable. :-/

  6. Despite following your directions, I cannot get this to work! It’s been driving me crazy all day long.

    I use Dreamweaver as my host and have also attempted to follow the wiki directions – everything has failed. Though I am able to make commits and updates, the directory that the post-commit.script is pointed to does not get updated. (I have even changed the file permissions to 777)

    What the heck’s going on?!

  7. dude, you rock. thank you!

  8. You absolutely decimated any other help on this topic. Your idea of making the c post-commit the actual hook object instead of some bash executable solved a problem that had caused me hours of trouble. Great blog, great work. Come have a free CD on me :) http://www.twelvestepstospace.com

    Peace!

  9. Nice article. I also host my blog on Dreamhost but after svn update I need to execute ‘touch dispatch.fcgi’ to tell Apache that files are changed.

  10. @Dima -

    Could it be that this is due to some type of in-memory caching mechanism?

  11. [...] my 2 year old “Subversion + Dreamhost + Post-Commit” blog still gets quite a number of hits. Second, after the latest Dreamhost outage move, I’m [...]

  12. As of Feb 18, 2008, this trick no longer works. Dreamhost’s response to a support ticket I opened about this:

    “Unfortunately we no longer support this workaround to run post-commit as
    your user. There were some security issues found (besides the obvious
    dangers of running setuid programs as your user) and the admins had to
    disable setuid for home directories. Sorry that this ended up breaking
    your post-commit. At this time the only solution I can offer is to
    change the post-commit to a cron job…”

  13. [...] Dreamhost Subversion Post Commit Tutorial [...]

Please leave a reply »

Powered by Wordpress. Stalk me.