In a previous post I wrote a small expect script to update a remote web server’s deployed code on a new commit to a Subversion repository using Expect and Subversion’s post-commit hooks. That first script was extraordinarily basic, so I’ve been wanting to add some sanity and error checking to it for a while. I finally got around to it today.
This improved version of the post-commit hook does the same thing as the last one (that is, it logs into your web server over SSH with the given user and password, and yes, I’m aware of the scariness of embedding a password in such a way, so you should really set up SSH to use public keys for authentication for this), except now it also produces useful output.
Here’s the same script as before, but improved:
#!/usr/bin/expect -f # # AUTHOR: Meitar Moscovitz# DATE : Thu Jun 21 16:32:42 EDT 2007 # set HOST my.web.server set USER someuser set PASS xxx # the working copy we're going to update set WC /path/to/working/copy # the path to the svn executable on the remote web server set SVNBIN /usr/local/bin/svn # our network is slow, set a long timeout set timeout 30 ##### DO NOT EDIT PAST THIS LINE! ##### # POST-COMMIT HOOK # # The post-commit hook is invoked after a commit. Subversion runs # this hook by invoking a program (script, executable, binary, etc.) # named 'post-commit' (this file) with the # following ordered arguments: # # [1] REPOS-PATH (the path to this repository) # [2] REV (the number of the revision just committed) # # Note that Subversion does not provide this program with an environment # of any kind. That means this program lacks a current working directory, # a home directory, a $PATH, and so on. set REPOS [lindex $argv 0] set REV [lindex $argv 1] # Define error codes set E_NO_SSH 1 ;# can't find a usable SSH on our system set E_NO_CONNECT 2 ;# failure to connect to remote server (timed out) set E_WRONG_PASS 3 ;# password provided does not work set E_UNKNOWN 25 ;# unexpected failure # find the SSH binary on our system if {[file executable /usr/bin/ssh]} { set SSHBIN /usr/bin/ssh } elseif {[file executable /usr/local/bin/ssh]} { set SSHBIN /usr/local/bin/ssh } else { send_error "Can't find a usable SSH on this system.\n" exit $E_NO_SSH } spawn $SSHBIN $USER@$HOST $SVNBIN update $WC expect { "continue connecting (yes/no)? " { send "yes\r"; exp_continue; } -nocase "password:" { send "$PASS\r"; } timeout { send_error "\nWe have timed out after $timeout seconds while trying to connect to $HOST!\n"; exit $E_NO_CONNECT; } } expect { -nocase "password:" { ;# if we are asked for the password again, then we have provided the wrong password send_error "\nCan not log in to $HOST because the password provided for user $USER has been rejected.\n"; exit $E_WRONG_PASS; } -re "revision (\[0-9]+)." { if {$REV == $expect_out(1,string)} { send_user "\nSuccessfully updated $WC on $HOST to revision $REV.\n" } else { send_user "\nUpdated repository to revision $expect_out(1,string), but svn reports that we are at revision number $REV.\n" send_error "CAUTION: Repository updated to revision $expect_out(1,string), but committed revision $REV.\n" } } default { send_error "An unexpected error has occured. The process at spawn ID $spawn_id has produced the following output:\n" send_error $expect_out(buffer) exit $E_UNKNOWN } }
My SVN server also asks for password. Can you provide me a patch where I can auto fill the SVN password when prompted.
With this script I am getting the following error:
————————————
spawn /usr/bin/ssh user@serverIP /usr/bin/svn update /home/user/test-svn/
user@serverIP’s password:
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,gssapi-with-mic,password).
svn: Connection closed unexpectedly
An unexpected error has occured. The process at spawn ID exp6 has produced the following output:
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,gssapi-with-mic,password).
svn: Connection closed unexpectedly
———————–
Here “Permission denied, please try again. Permission denied (publickey,gssapi-with-mic,password). svn: Connection closed unexpectedly” error is because my SVN user has a password.
Hope I am able to make my self clear.
sunil
21 Mar 08 at 3:38 AM
Sunil, the output here looks at first glance as though it’s SSH, not SVN that’s rejecting your password. Are you certain you’ve entered the correct password for the SSH user (not the SVN user) into the script at the top portion, before the “DO NOT EDIT PAST THIS LINE” line?
Also, this script expects no authentication to be necessary to do a simple `svn update`—that is to say that read-only privileges to your repository should not require a login. If they do, that’s another story, but again, it looks as though it’s SSH, not SVN that’s having trouble authenticating in your case.
Meitar
22 Mar 08 at 11:08 PM
Just wanted to say thanks for the script, worked out nicely for me! Kudos.
Kyle
23 Feb 09 at 9:36 PM
Nice script, exactly what i needed, thanks!
Felix
9 Apr 09 at 7:10 AM
Thank you!
paluh
14 Oct 09 at 3:22 PM
This is really great. Would be even better it the script had a trigger to either remote deploy or not, according to some keyword on the commit message. In my case, i commit all day to a repository, would be nice if the script listened to that keyword and only then executed the remote copy update.
Luis Martins
16 Nov 09 at 6:03 PM
I would love to see a modification of this to include passign SVN username/password so that it would work with a repository that requires auth for read access.
Great job, thanks!
John
3 Aug 10 at 11:18 AM
I’ve edited the host, user and pass and upon commit I receive the following messages:
——————-
Warning: post-commit hook failed (exit code 25) with output:
An unexpected error has occured. The process at spawn ID exp5 has produced the following output:
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,password).
svn: Connection closed unexpectedly
——————–
I know this is a SSH problem, but I was wondering if someone else bumped into this problem and found a solution?
Thanks.
benny
3 Nov 10 at 3:33 AM
Found a way to get around the svn password prob.
spawn $SSHBIN $USER@$HOST -t “$SVNBIN update $WC -password $PASS2″
bhoung
18 Sep 11 at 6:22 AM