switchtower 0.10.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/switchtower/actor.rb +51 -20
- data/lib/switchtower/cli.rb +1 -1
- data/lib/switchtower/command.rb +1 -2
- data/lib/switchtower/configuration.rb +49 -7
- data/lib/switchtower/extensions.rb +38 -0
- data/lib/switchtower/gateway.rb +15 -3
- data/lib/switchtower/generators/rails/deployment/templates/switchtower.rake +6 -2
- data/lib/switchtower/logger.rb +8 -5
- data/lib/switchtower/recipes/standard.rb +49 -10
- data/lib/switchtower/scm/base.rb +2 -2
- data/lib/switchtower/scm/baz.rb +118 -0
- data/lib/switchtower/scm/bzr.rb +70 -0
- data/lib/switchtower/scm/cvs.rb +57 -6
- data/lib/switchtower/scm/perforce.rb +139 -0
- data/lib/switchtower/scm/subversion.rb +8 -3
- data/lib/switchtower/transfer.rb +1 -1
- data/lib/switchtower/utils.rb +26 -0
- data/lib/switchtower/version.rb +3 -3
- data/test/actor_test.rb +34 -1
- data/test/configuration_test.rb +16 -1
- data/test/fixtures/custom.rb +3 -0
- data/test/scm/cvs_test.rb +24 -2
- data/test/scm/subversion_test.rb +17 -2
- data/test/utils.rb +8 -0
- metadata +9 -3
data/lib/switchtower/transfer.rb
CHANGED
@@ -58,7 +58,7 @@ module SwitchTower
|
|
58
58
|
sftp = @actor.sessions[server].sftp
|
59
59
|
sftp.connect unless sftp.state == :open
|
60
60
|
|
61
|
-
sftp.open(@filename, IO::WRONLY | IO::CREAT, @params[:mode] || 0660) do |status, handle|
|
61
|
+
sftp.open(@filename, IO::WRONLY | IO::CREAT | IO::TRUNC, @params[:mode] || 0660) do |status, handle|
|
62
62
|
break unless check_status("open #{@filename}", server, status)
|
63
63
|
|
64
64
|
logger.info "uploading data to #{server}:#{@filename}"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SwitchTower
|
2
|
+
# A helper method for converting a comma-delimited string into an array of
|
3
|
+
# roles.
|
4
|
+
def self.str2roles(string)
|
5
|
+
list = string.split(/,/).map { |s| s.strip.to_sym }
|
6
|
+
list.empty? ? nil : list
|
7
|
+
end
|
8
|
+
|
9
|
+
# Used by third-party task bundles to identify the switchtower configuration
|
10
|
+
# that is loading them. It's return value is not reliable in other contexts.
|
11
|
+
# If +require_config+ is not false, an exception will be raised if the current
|
12
|
+
# configuration is not set.
|
13
|
+
def self.configuration(require_config=false)
|
14
|
+
config = Thread.current[:switchtower_configuration]
|
15
|
+
if require_config && config.nil?
|
16
|
+
raise "Please require this file from within a SwitchTower recipe"
|
17
|
+
end
|
18
|
+
config
|
19
|
+
end
|
20
|
+
|
21
|
+
# Used internally by SwitchTower to specify the current configuration before
|
22
|
+
# loading a third-party task bundle.
|
23
|
+
def self.configuration=(config)
|
24
|
+
Thread.current[:switchtower_configuration] = config
|
25
|
+
end
|
26
|
+
end
|
data/lib/switchtower/version.rb
CHANGED
@@ -18,13 +18,13 @@ module SwitchTower
|
|
18
18
|
good
|
19
19
|
end
|
20
20
|
|
21
|
-
MAJOR =
|
22
|
-
MINOR =
|
21
|
+
MAJOR = 1
|
22
|
+
MINOR = 0
|
23
23
|
TINY = 0
|
24
24
|
|
25
25
|
STRING = [MAJOR, MINOR, TINY].join(".")
|
26
26
|
|
27
|
-
SSH_REQUIRED = [1,0,
|
27
|
+
SSH_REQUIRED = [1,0,8]
|
28
28
|
SFTP_REQUIRED = [1,1,0]
|
29
29
|
end
|
30
30
|
end
|
data/test/actor_test.rb
CHANGED
@@ -4,6 +4,7 @@ require 'stringio'
|
|
4
4
|
require 'test/unit'
|
5
5
|
require 'switchtower/actor'
|
6
6
|
require 'switchtower/logger'
|
7
|
+
require 'switchtower/configuration'
|
7
8
|
|
8
9
|
class ActorTest < Test::Unit::TestCase
|
9
10
|
|
@@ -83,6 +84,12 @@ class ActorTest < Test::Unit::TestCase
|
|
83
84
|
end
|
84
85
|
end
|
85
86
|
|
87
|
+
module CustomExtension
|
88
|
+
def do_something_extra(a, b, c)
|
89
|
+
run "echo '#{a} :: #{b} :: #{c}'"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
86
93
|
def setup
|
87
94
|
TestingCommand.reset!
|
88
95
|
@actor = TestActor.new(MockConfiguration.new)
|
@@ -162,7 +169,7 @@ class ActorTest < Test::Unit::TestCase
|
|
162
169
|
run "do this"
|
163
170
|
end
|
164
171
|
|
165
|
-
assert_equal %w(01.example.com 02.example.com 03.example.com 04.example.com 05.example.com 06.example.com 07.example.com all.example.com), @actor.tasks[:foo].servers
|
172
|
+
assert_equal %w(01.example.com 02.example.com 03.example.com 04.example.com 05.example.com 06.example.com 07.example.com all.example.com), @actor.tasks[:foo].servers.sort
|
166
173
|
end
|
167
174
|
|
168
175
|
def test_run_in_task_without_explicit_roles_selects_all_roles
|
@@ -258,4 +265,30 @@ class ActorTest < Test::Unit::TestCase
|
|
258
265
|
@actor.foo
|
259
266
|
assert_equal %w(foo after_foo), history
|
260
267
|
end
|
268
|
+
|
269
|
+
def test_uppercase_variables
|
270
|
+
config = SwitchTower::Configuration.new(TestActor)
|
271
|
+
config.set :HELLO, "world"
|
272
|
+
assert_equal "world", config.actor.instance_eval("HELLO")
|
273
|
+
config.set :HELLO, "test"
|
274
|
+
assert_equal "test", config.actor.instance_eval("HELLO")
|
275
|
+
end
|
276
|
+
|
277
|
+
def test_connect_when_no_matching_servers
|
278
|
+
@actor.define_task :foo, :roles => :db, :only => { :fnoofy => true } do
|
279
|
+
run "do this"
|
280
|
+
end
|
281
|
+
|
282
|
+
assert_raises(RuntimeError) { @actor.foo }
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_custom_extension
|
286
|
+
assert SwitchTower.plugin(:custom, CustomExtension)
|
287
|
+
@actor.define_task :foo, :roles => :db do
|
288
|
+
custom.do_something_extra(1, 2, 3)
|
289
|
+
end
|
290
|
+
assert_nothing_raised { @actor.foo }
|
291
|
+
assert TestingCommand.invoked?
|
292
|
+
assert SwitchTower.remove_plugin(:custom)
|
293
|
+
end
|
261
294
|
end
|
data/test/configuration_test.rb
CHANGED
@@ -125,6 +125,16 @@ class ConfigurationTest < Test::Unit::TestCase
|
|
125
125
|
assert_equal 1, @config.roles[:web].length
|
126
126
|
end
|
127
127
|
|
128
|
+
def test_load_proc_explicit
|
129
|
+
@config.load :proc => Proc.new { set :gateway, "nifty.zoo.test" }
|
130
|
+
assert_equal "nifty.zoo.test", @config.gateway
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_load_proc_implicit
|
134
|
+
@config.load { set :gateway, "nifty.zoo.test" }
|
135
|
+
assert_equal "nifty.zoo.test", @config.gateway
|
136
|
+
end
|
137
|
+
|
128
138
|
def test_task_without_options
|
129
139
|
block = Proc.new { }
|
130
140
|
@config.task :hello, &block
|
@@ -209,10 +219,15 @@ class ConfigurationTest < Test::Unit::TestCase
|
|
209
219
|
end
|
210
220
|
|
211
221
|
def test_get_proc_variable_sets_original_value_hash
|
212
|
-
@config.set
|
222
|
+
@config.set(:proc) { "foo" }
|
213
223
|
assert_nil @config[:original_value][:proc]
|
214
224
|
assert_equal "foo", @config[:proc]
|
215
225
|
assert_not_nil @config[:original_value][:proc]
|
216
226
|
assert @config[:original_value][:proc].respond_to?(:call)
|
217
227
|
end
|
228
|
+
|
229
|
+
def test_require
|
230
|
+
@config.require "#{File.dirname(__FILE__)}/fixtures/custom"
|
231
|
+
assert_equal "foo", @config.gateway
|
232
|
+
end
|
218
233
|
end
|
data/test/scm/cvs_test.rb
CHANGED
@@ -9,10 +9,15 @@ class ScmCvsTest < Test::Unit::TestCase
|
|
9
9
|
attr_accessor :story
|
10
10
|
attr_reader :last_path
|
11
11
|
|
12
|
-
def cvs_log(path)
|
12
|
+
def cvs_log(path,branch)
|
13
13
|
@last_path = path
|
14
14
|
story.shift
|
15
15
|
end
|
16
|
+
|
17
|
+
def cvs_branch(path)
|
18
|
+
"deploy-me"
|
19
|
+
end
|
20
|
+
|
16
21
|
end
|
17
22
|
|
18
23
|
class MockChannel
|
@@ -56,7 +61,6 @@ class ScmCvsTest < Test::Unit::TestCase
|
|
56
61
|
def setup
|
57
62
|
@config = MockConfiguration.new
|
58
63
|
@config[:repository] = ":ext:joetester@rubyforge.org:/hello/world"
|
59
|
-
@config[:local] = "/hello/world"
|
60
64
|
@config[:cvs] = "/path/to/cvs"
|
61
65
|
@config[:password] = "chocolatebrownies"
|
62
66
|
@config[:now] = Time.utc(2005,8,24,12,0,0)
|
@@ -144,11 +148,19 @@ MSG
|
|
144
148
|
end
|
145
149
|
|
146
150
|
def test_latest_revision
|
151
|
+
@config[:local] = "/hello/world"
|
147
152
|
@scm.story = [ @log_msg ]
|
148
153
|
assert_equal "2004-10-12 02:21:02", @scm.latest_revision
|
149
154
|
assert_equal "/hello/world", @scm.last_path
|
150
155
|
end
|
151
156
|
|
157
|
+
def test_latest_with_default_local
|
158
|
+
@config[:local] = nil
|
159
|
+
@scm.story = [ @log_msg ]
|
160
|
+
assert_equal "2004-10-12 02:21:02", @scm.latest_revision
|
161
|
+
assert_equal ".", @scm.last_path
|
162
|
+
end
|
163
|
+
|
152
164
|
def test_checkout
|
153
165
|
@actor.story = []
|
154
166
|
assert_nothing_raised { @scm.checkout(@actor) }
|
@@ -161,4 +173,14 @@ MSG
|
|
161
173
|
assert_nothing_raised { @scm.checkout(@actor) }
|
162
174
|
assert_equal ["chocolatebrownies\n"], @actor.channels.last.sent_data
|
163
175
|
end
|
176
|
+
|
177
|
+
def test_current_branch
|
178
|
+
assert_equal "deploy-me", @scm.current_branch
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_default_current_branch
|
182
|
+
@config[:branch] = "default-branch"
|
183
|
+
@scm = CvsTest.new(@config)
|
184
|
+
assert_equal "default-branch", @scm.current_branch
|
185
|
+
end
|
164
186
|
end
|
data/test/scm/subversion_test.rb
CHANGED
@@ -84,7 +84,7 @@ MSG
|
|
84
84
|
@actor.story = []
|
85
85
|
assert_nothing_raised { @scm.checkout(@actor) }
|
86
86
|
assert_nil @actor.channels.last.sent_data
|
87
|
-
assert_match %r{/path/to/svn}, @actor.command
|
87
|
+
assert_match %r{/path/to/svn co\s+-q}, @actor.command
|
88
88
|
end
|
89
89
|
|
90
90
|
def test_checkout_via_export
|
@@ -92,7 +92,7 @@ MSG
|
|
92
92
|
@config[:checkout] = "export"
|
93
93
|
assert_nothing_raised { @scm.checkout(@actor) }
|
94
94
|
assert_nil @actor.channels.last.sent_data
|
95
|
-
assert_match %r{/path/to/svn export}, @actor.command
|
95
|
+
assert_match %r{/path/to/svn export\s+-q}, @actor.command
|
96
96
|
end
|
97
97
|
|
98
98
|
def test_update
|
@@ -119,4 +119,19 @@ MSG
|
|
119
119
|
assert_nothing_raised { @scm.checkout(@actor) }
|
120
120
|
assert_equal ["chocolatebrownies\n"], @actor.channels.last.sent_data
|
121
121
|
end
|
122
|
+
|
123
|
+
def test_svn_password
|
124
|
+
@config[:svn_password] = "butterscotchcandies"
|
125
|
+
@actor.story = [[:out, "Password: "]]
|
126
|
+
assert_nothing_raised { @scm.checkout(@actor) }
|
127
|
+
assert_equal ["butterscotchcandies\n"], @actor.channels.last.sent_data
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_svn_username
|
131
|
+
@actor.story = []
|
132
|
+
@config[:svn_username] = "turtledove"
|
133
|
+
assert_nothing_raised { @scm.checkout(@actor) }
|
134
|
+
assert_nil @actor.channels.last.sent_data
|
135
|
+
assert_match %r{/path/to/svn co --username turtledove}, @actor.command
|
136
|
+
end
|
122
137
|
end
|
data/test/utils.rb
CHANGED
@@ -32,6 +32,14 @@ class MockConfiguration < Hash
|
|
32
32
|
@logger ||= MockLogger.new
|
33
33
|
end
|
34
34
|
|
35
|
+
def set(variable, value=nil, &block)
|
36
|
+
self[variable] = value
|
37
|
+
end
|
38
|
+
|
39
|
+
def respond_to?(sym)
|
40
|
+
self.has_key?(sym)
|
41
|
+
end
|
42
|
+
|
35
43
|
def method_missing(sym, *args)
|
36
44
|
if args.length == 0
|
37
45
|
self[sym]
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: switchtower
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2006-02-18 00:00:00 -07:00
|
8
8
|
summary: "SwitchTower is a framework and utility for executing commands in parallel on
|
9
9
|
multiple remote machines, via SSH. The primary goal is to simplify and
|
10
10
|
automate the deployment of web applications."
|
@@ -38,6 +38,7 @@ files:
|
|
38
38
|
- lib/switchtower/cli.rb
|
39
39
|
- lib/switchtower/command.rb
|
40
40
|
- lib/switchtower/configuration.rb
|
41
|
+
- lib/switchtower/extensions.rb
|
41
42
|
- lib/switchtower/gateway.rb
|
42
43
|
- lib/switchtower/generators
|
43
44
|
- lib/switchtower/logger.rb
|
@@ -45,6 +46,7 @@ files:
|
|
45
46
|
- lib/switchtower/scm
|
46
47
|
- lib/switchtower/ssh.rb
|
47
48
|
- lib/switchtower/transfer.rb
|
49
|
+
- lib/switchtower/utils.rb
|
48
50
|
- lib/switchtower/version.rb
|
49
51
|
- lib/switchtower/generators/rails
|
50
52
|
- lib/switchtower/generators/rails/deployment
|
@@ -57,8 +59,11 @@ files:
|
|
57
59
|
- lib/switchtower/recipes/templates
|
58
60
|
- lib/switchtower/recipes/templates/maintenance.rhtml
|
59
61
|
- lib/switchtower/scm/base.rb
|
62
|
+
- lib/switchtower/scm/baz.rb
|
63
|
+
- lib/switchtower/scm/bzr.rb
|
60
64
|
- lib/switchtower/scm/cvs.rb
|
61
65
|
- lib/switchtower/scm/darcs.rb
|
66
|
+
- lib/switchtower/scm/perforce.rb
|
62
67
|
- lib/switchtower/scm/subversion.rb
|
63
68
|
- examples/sample.rb
|
64
69
|
- test/actor_test.rb
|
@@ -69,6 +74,7 @@ files:
|
|
69
74
|
- test/ssh_test.rb
|
70
75
|
- test/utils.rb
|
71
76
|
- test/fixtures/config.rb
|
77
|
+
- test/fixtures/custom.rb
|
72
78
|
- test/scm/cvs_test.rb
|
73
79
|
- test/scm/subversion_test.rb
|
74
80
|
test_files: []
|
@@ -87,7 +93,7 @@ dependencies:
|
|
87
93
|
-
|
88
94
|
- ">="
|
89
95
|
- !ruby/object:Gem::Version
|
90
|
-
version: 1.0.
|
96
|
+
version: 1.0.8
|
91
97
|
version:
|
92
98
|
- !ruby/object:Gem::Dependency
|
93
99
|
name: net-sftp
|