Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Pull: rollback on rsync failure and support gateway variable #12

Open
wants to merge 3 commits into from

2 participants

@mcary

I've made two changes to capistrano_rsync_with_remote_cache:

  1. When rsync fails, instead of silently continuing, rollback the deploy
  2. Obey Capistrano's :gateway variable to forward SSH through a bastion host when calling rsync

I've added tests for each. Please let me know if there is anything else you require for acceptance of these changes.

Branches:
rollback-on-rsync-failure
add-gateway-support

Thanks!

mcary added some commits
@mcary mcary Rollback the deploy instead of continuing when rsync fails
When rsync fails, I'm getting a deploy that looks like it went fine
except for an inconspicuous message saying that rsync failed and a
production deployment that's still on the old code version.  Sometimes I
don't notice right away that the new code is not actually live, and this
is a big problem.

I'd like to see a clear error message when rsync fails.

Raise an exception of rsync fails to any of the servers receiving a code
update.
47945cb
@mcary mcary Add support for Capistrano's :gateway variable to rsync invocation
When running rsync, the RsyncWithRemoteCache strategy doesn't heed
Capistrano's :gateway parameter, which says to SSH to the server
named by that parameter before connecting to the target server.

Add support for a gateway by using the ProxyCommand SSH directive.
Assume netcat is installed as nc on the target system.
27640fe
@mcary mcary Merge branches 'add-gateway-support' and 'rollback-on-rsync-failure' 4d01750
@mtrias

Hi!

Is this feature planned to be merged sometime ? Are there any other alternatives to this ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 12, 2011
  1. @mcary

    Rollback the deploy instead of continuing when rsync fails

    mcary authored
    When rsync fails, I'm getting a deploy that looks like it went fine
    except for an inconspicuous message saying that rsync failed and a
    production deployment that's still on the old code version.  Sometimes I
    don't notice right away that the new code is not actually live, and this
    is a big problem.
    
    I'd like to see a clear error message when rsync fails.
    
    Raise an exception of rsync fails to any of the servers receiving a code
    update.
  2. @mcary

    Add support for Capistrano's :gateway variable to rsync invocation

    mcary authored
    When running rsync, the RsyncWithRemoteCache strategy doesn't heed
    Capistrano's :gateway parameter, which says to SSH to the server
    named by that parameter before connecting to the target server.
    
    Add support for a gateway by using the ProxyCommand SSH directive.
    Assume netcat is installed as nc on the target system.
  3. @mcary
This page is out of date. Refresh to see the latest.
View
4 lib/capistrano/recipes/deploy/strategy/rsync_with_remote_cache.rb
@@ -36,7 +36,7 @@ def update_local_cache
def update_remote_cache
finder_options = {:except => { :no_release => true }}
- find_servers(finder_options).each {|s| system(rsync_command_for(s)) }
+ find_servers(finder_options).each {|s| system(rsync_command_for(s)) or raise "Command failed" }
end
def copy_remote_cache
@@ -44,7 +44,7 @@ def copy_remote_cache
end
def rsync_command_for(server)
- "rsync #{rsync_options} --rsh='ssh -p #{ssh_port(server)}' #{local_cache_path}/ #{rsync_host(server)}:#{repository_cache_path}/"
+ "rsync #{rsync_options} --rsh='ssh -p #{ssh_port(server)}#{" -o \"ProxyCommand ssh #{configuration[:gateway]} nc -w300 %h %p\"" if configuration[:gateway]}' #{local_cache_path}/ #{rsync_host(server)}:#{repository_cache_path}/"
end
def mark_local_cache
View
35 test/capistrano_rsync_with_remote_cache_test.rb
@@ -250,6 +250,24 @@ class CapistranoRsyncWithRemoteCacheTest < Test::Unit::TestCase
@strategy.rsync_command_for(server).should == expected
end
+ should "be able to run the rsync command through a gateway" do
+ server = stub()
+
+ @strategy.stubs(:rsync_host).with(server).returns('rsync_host')
+ @strategy.configuration.stubs(:[]).with(:gateway).returns('ssh_gateway')
+
+ @strategy.stubs(
+ :rsync_options => 'rsync_options',
+ :ssh_port => 'ssh_port',
+ :local_cache_path => 'local_cache_path',
+ :repository_cache_path => 'repository_cache_path'
+ )
+
+ expected = "rsync rsync_options --rsh='ssh -p ssh_port -o \"ProxyCommand ssh ssh_gateway nc -w300 %h %p\"' local_cache_path/ rsync_host:repository_cache_path/"
+
+ @strategy.rsync_command_for(server).should == expected
+ end
+
should "be able to update the remote cache" do
server_1, server_2 = [stub(), stub()]
@strategy.stubs(:find_servers).with(:except => {:no_release => true}).returns([server_1, server_2])
@@ -257,12 +275,25 @@ class CapistranoRsyncWithRemoteCacheTest < Test::Unit::TestCase
@strategy.stubs(:rsync_command_for).with(server_1).returns('server_1_rsync_command')
@strategy.stubs(:rsync_command_for).with(server_2).returns('server_2_rsync_command')
- @strategy.expects(:system).with('server_1_rsync_command')
- @strategy.expects(:system).with('server_2_rsync_command')
+ @strategy.expects(:system).with('server_1_rsync_command').returns(true)
+ @strategy.expects(:system).with('server_2_rsync_command').returns(true)
@strategy.update_remote_cache
end
+ should "notice failure to update teh remote cache" do
+ server_1, server_2 = [stub(), stub()]
+ @strategy.stubs(:find_servers).with(:except => {:no_release => true}).returns([server_1, server_2])
+
+ @strategy.stubs(:rsync_command_for).with(server_1).returns('server_1_rsync_command')
+ @strategy.stubs(:rsync_command_for).with(server_2).returns('server_2_rsync_command')
+
+ @strategy.expects(:system).with('server_1_rsync_command').returns(false)
+ @strategy.expects(:system).with('server_2_rsync_command').never
+
+ lambda { @strategy.update_remote_cache }.should raise_error
+ end
+
should "be able copy the remote cache into place" do
@strategy.stubs(
:repository_cache_path => 'repository_cache_path',
Something went wrong with that request. Please try again.