engineyard-serverside 2.0.4 → 2.0.5.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/engineyard-serverside.rb +2 -1
- data/lib/engineyard-serverside/about.rb +37 -0
- data/lib/engineyard-serverside/cli.rb +2 -49
- data/lib/engineyard-serverside/configuration.rb +1 -0
- data/lib/engineyard-serverside/deploy.rb +5 -8
- data/lib/engineyard-serverside/propagator.rb +75 -0
- data/lib/engineyard-serverside/server.rb +3 -2
- data/lib/engineyard-serverside/servers.rb +28 -14
- data/lib/engineyard-serverside/shell.rb +6 -6
- data/lib/engineyard-serverside/shell/command_result.rb +1 -1
- data/lib/engineyard-serverside/strategies/git.rb +9 -4
- data/lib/engineyard-serverside/version.rb +1 -1
- data/spec/propagator_spec.rb +95 -0
- data/spec/spec_helper.rb +1 -1
- metadata +47 -68
- data/lib/engineyard-serverside/future.rb +0 -35
- data/lib/engineyard-serverside/futures/celluloid.rb +0 -15
- data/lib/engineyard-serverside/futures/dataflow.rb +0 -26
- data/lib/vendor/celluloid/lib/celluloid.rb +0 -261
- data/lib/vendor/celluloid/lib/celluloid/actor.rb +0 -242
- data/lib/vendor/celluloid/lib/celluloid/actor_pool.rb +0 -54
- data/lib/vendor/celluloid/lib/celluloid/actor_proxy.rb +0 -75
- data/lib/vendor/celluloid/lib/celluloid/application.rb +0 -78
- data/lib/vendor/celluloid/lib/celluloid/calls.rb +0 -93
- data/lib/vendor/celluloid/lib/celluloid/core_ext.rb +0 -14
- data/lib/vendor/celluloid/lib/celluloid/events.rb +0 -14
- data/lib/vendor/celluloid/lib/celluloid/fiber.rb +0 -33
- data/lib/vendor/celluloid/lib/celluloid/fsm.rb +0 -141
- data/lib/vendor/celluloid/lib/celluloid/future.rb +0 -60
- data/lib/vendor/celluloid/lib/celluloid/links.rb +0 -61
- data/lib/vendor/celluloid/lib/celluloid/logger.rb +0 -32
- data/lib/vendor/celluloid/lib/celluloid/mailbox.rb +0 -124
- data/lib/vendor/celluloid/lib/celluloid/receivers.rb +0 -66
- data/lib/vendor/celluloid/lib/celluloid/registry.rb +0 -33
- data/lib/vendor/celluloid/lib/celluloid/responses.rb +0 -26
- data/lib/vendor/celluloid/lib/celluloid/rspec.rb +0 -2
- data/lib/vendor/celluloid/lib/celluloid/signals.rb +0 -50
- data/lib/vendor/celluloid/lib/celluloid/supervisor.rb +0 -57
- data/lib/vendor/celluloid/lib/celluloid/task.rb +0 -73
- data/lib/vendor/celluloid/lib/celluloid/tcp_server.rb +0 -33
- data/lib/vendor/celluloid/lib/celluloid/timers.rb +0 -109
- data/lib/vendor/celluloid/lib/celluloid/version.rb +0 -4
- data/lib/vendor/dataflow/HISTORY +0 -52
- data/lib/vendor/dataflow/LICENSE +0 -19
- data/lib/vendor/dataflow/README.textile +0 -290
- data/lib/vendor/dataflow/Rakefile +0 -36
- data/lib/vendor/dataflow/dataflow.rb +0 -124
- data/lib/vendor/dataflow/dataflow/actor.rb +0 -22
- data/lib/vendor/dataflow/dataflow/equality.rb +0 -44
- data/lib/vendor/dataflow/dataflow/future_queue.rb +0 -24
- data/lib/vendor/dataflow/dataflow/port.rb +0 -54
- data/lib/vendor/dataflow/examples/barrier.rb +0 -9
- data/lib/vendor/dataflow/examples/data_driven.rb +0 -17
- data/lib/vendor/dataflow/examples/dataflow_http_gets.rb +0 -13
- data/lib/vendor/dataflow/examples/flow.rb +0 -20
- data/lib/vendor/dataflow/examples/future_http_gets.rb +0 -12
- data/lib/vendor/dataflow/examples/future_queue.rb +0 -11
- data/lib/vendor/dataflow/examples/instance_variables.rb +0 -15
- data/lib/vendor/dataflow/examples/laziness.rb +0 -9
- data/lib/vendor/dataflow/examples/local_variables.rb +0 -11
- data/lib/vendor/dataflow/examples/messages.rb +0 -26
- data/lib/vendor/dataflow/examples/port_http_gets.rb +0 -13
- data/lib/vendor/dataflow/examples/port_send.rb +0 -10
- data/lib/vendor/dataflow/examples/ring.rb +0 -21
- data/lib/vendor/dataflow/spec/actor_spec.rb +0 -28
- data/lib/vendor/dataflow/spec/anonymous_variables_spec.rb +0 -21
- data/lib/vendor/dataflow/spec/barrier_spec.rb +0 -25
- data/lib/vendor/dataflow/spec/by_need_spec.rb +0 -55
- data/lib/vendor/dataflow/spec/dataflow_spec.rb +0 -151
- data/lib/vendor/dataflow/spec/equality_spec.rb +0 -40
- data/lib/vendor/dataflow/spec/flow_spec.rb +0 -25
- data/lib/vendor/dataflow/spec/forker_spec.rb +0 -28
- data/lib/vendor/dataflow/spec/future_queue_spec.rb +0 -31
- data/lib/vendor/dataflow/spec/inspect_spec.rb +0 -19
- data/lib/vendor/dataflow/spec/need_later_spec.rb +0 -12
- data/lib/vendor/dataflow/spec/port_spec.rb +0 -26
- data/lib/vendor/dataflow/spec/spec.opts +0 -1
- data/lib/vendor/dataflow/spec/spec_helper.rb +0 -10
@@ -16,6 +16,7 @@ require 'escape'
|
|
16
16
|
require 'json'
|
17
17
|
|
18
18
|
require 'engineyard-serverside/version'
|
19
|
+
require 'engineyard-serverside/about'
|
19
20
|
require 'engineyard-serverside/strategies/git'
|
20
21
|
require 'engineyard-serverside/task'
|
21
22
|
require 'engineyard-serverside/server'
|
@@ -25,8 +26,8 @@ require 'engineyard-serverside/lockfile_parser'
|
|
25
26
|
require 'engineyard-serverside/cli'
|
26
27
|
require 'engineyard-serverside/configuration'
|
27
28
|
require 'engineyard-serverside/deprecation'
|
28
|
-
require 'engineyard-serverside/future'
|
29
29
|
require 'engineyard-serverside/shell'
|
30
|
+
require 'engineyard-serverside/propagator'
|
30
31
|
|
31
32
|
|
32
33
|
module EY
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module EY
|
3
|
+
module Serverside
|
4
|
+
module About
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def gem_name
|
8
|
+
"engineyard-serverside"
|
9
|
+
end
|
10
|
+
|
11
|
+
def version
|
12
|
+
EY::Serverside::VERSION
|
13
|
+
end
|
14
|
+
|
15
|
+
def name_with_version
|
16
|
+
"#{gem_name} #{version}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def gem_filename
|
20
|
+
"#{gem_name}-#{version}.gem"
|
21
|
+
end
|
22
|
+
|
23
|
+
def gem_file
|
24
|
+
File.join(Gem.dir, 'cache', gem_filename)
|
25
|
+
end
|
26
|
+
|
27
|
+
def gem_binary
|
28
|
+
File.join(Gem.default_bindir, 'gem')
|
29
|
+
end
|
30
|
+
|
31
|
+
def binary
|
32
|
+
File.expand_path("../../../bin/#{gem_name}", __FILE__)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -136,57 +136,10 @@ module EY
|
|
136
136
|
|
137
137
|
private
|
138
138
|
|
139
|
-
# Put the same engineyard-serverside on all the servers (Used to be public but is unused as an actual CLI command now)
|
140
|
-
def propagate(servers, config, shell)
|
141
|
-
gem_filename = "engineyard-serverside-#{EY::Serverside::VERSION}.gem"
|
142
|
-
local_gem_file = File.join(Gem.dir, 'cache', gem_filename)
|
143
|
-
remote_gem_file = File.join(Dir.tmpdir, gem_filename)
|
144
|
-
gem_binary = File.join(Gem.default_bindir, 'gem')
|
145
|
-
|
146
|
-
servers = servers.remote
|
147
|
-
|
148
|
-
return if servers.empty?
|
149
|
-
|
150
|
-
shell.status "Propagating engineyard-serverside #{EY::Serverside::VERSION} to #{servers.size} server#{servers.size == 1 ? '' : 's' }."
|
151
|
-
|
152
|
-
commands = servers.map do |server|
|
153
|
-
shell.debug "Building propagate commands for #{server.hostname}"
|
154
|
-
|
155
|
-
egrep_escaped_version = EY::Serverside::VERSION.gsub(/\./, '\.')
|
156
|
-
# the [,)] is to stop us from looking for e.g. 0.5.1, seeing
|
157
|
-
# 0.5.11, and mistakenly thinking 0.5.1 is there
|
158
|
-
has_gem_cmd = "#{gem_binary} list engineyard-serverside | grep \"engineyard-serverside\" | egrep -q '#{egrep_escaped_version}[,)]'"
|
159
|
-
|
160
|
-
proc do
|
161
|
-
exists = shell.logged_system(server.command_on_server('sh -l -c', has_gem_cmd))
|
162
|
-
if exists.success?
|
163
|
-
exists # Future expects logged system result object
|
164
|
-
else # doesn't have this exact version
|
165
|
-
shell.status "Installing engineyard-serverside on #{server.hostname}"
|
166
|
-
|
167
|
-
shell.logged_system(Escape.shell_command([
|
168
|
-
'scp', '-i', config.paths.internal_key.to_s,
|
169
|
-
"-o", "StrictHostKeyChecking=no",
|
170
|
-
local_gem_file,
|
171
|
-
"#{config.user}@#{server.hostname}:#{remote_gem_file}",
|
172
|
-
]))
|
173
|
-
install_gem_cmd = "#{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'"
|
174
|
-
shell.logged_system(server.command_on_server('sudo sh -l -c', install_gem_cmd))
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
futures = EY::Serverside::Future.call(commands)
|
180
|
-
unless EY::Serverside::Future.success?(futures)
|
181
|
-
failures = futures.select {|f| f.error? }.map {|f| f.inspect}.join("\n")
|
182
|
-
raise EY::Serverside::RemoteFailure.new(failures)
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
139
|
def init_and_propagate(*args)
|
187
140
|
config, shell = init(*args)
|
188
141
|
servers = load_servers(config)
|
189
|
-
|
142
|
+
Propagator.call(servers, config, shell)
|
190
143
|
[servers, config, shell]
|
191
144
|
end
|
192
145
|
|
@@ -196,7 +149,7 @@ module EY
|
|
196
149
|
:verbose => config.verbose,
|
197
150
|
:log_path => File.join(ENV['HOME'], "#{config.app}-#{action}.log")
|
198
151
|
)
|
199
|
-
shell.debug "Initializing
|
152
|
+
shell.debug "Initializing #{About.name_with_version}."
|
200
153
|
[config, shell]
|
201
154
|
end
|
202
155
|
|
@@ -62,6 +62,7 @@ module EY
|
|
62
62
|
def_option :branch, 'master'
|
63
63
|
def_option :bundle_without, 'test development'
|
64
64
|
def_option :current_roles, []
|
65
|
+
def_option :current_name, nil
|
65
66
|
def_option :asset_roles, [:app_master, :app, :solo]
|
66
67
|
def_option :copy_exclude, []
|
67
68
|
def_option(:user) { ENV['USER'] }
|
@@ -153,12 +153,10 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
153
153
|
# task
|
154
154
|
def push_code
|
155
155
|
shell.status "Pushing code to all servers"
|
156
|
-
|
156
|
+
servers.remote.run_on_each do |server|
|
157
157
|
cmd = server.sync_directory_command(paths.repository_cache)
|
158
|
-
|
158
|
+
shell.logged_system(cmd)
|
159
159
|
end
|
160
|
-
futures = EY::Serverside::Future.call(commands)
|
161
|
-
EY::Serverside::Future.success?(futures)
|
162
160
|
end
|
163
161
|
|
164
162
|
# task
|
@@ -415,7 +413,7 @@ WRAP
|
|
415
413
|
end
|
416
414
|
|
417
415
|
def base_callback_command_for(what)
|
418
|
-
cmd = [
|
416
|
+
cmd = [About.binary, 'hook', what.to_s]
|
419
417
|
cmd << '--app' << config.app
|
420
418
|
cmd << '--environment-name' << config.environment_name
|
421
419
|
cmd << '--account-name' << config.account_name
|
@@ -426,8 +424,7 @@ WRAP
|
|
426
424
|
end
|
427
425
|
|
428
426
|
def serverside_bin
|
429
|
-
|
430
|
-
File.join(basedir, 'bin', 'engineyard-serverside')
|
427
|
+
About.binary
|
431
428
|
end
|
432
429
|
|
433
430
|
def puts_deploy_failure
|
@@ -497,7 +494,7 @@ WRAP
|
|
497
494
|
clean_bundle_on_system_version_change
|
498
495
|
|
499
496
|
bundler_version, install_switches = bundler_config
|
500
|
-
sudo "#{clean_environment} && #{
|
497
|
+
sudo "#{clean_environment} && #{About.binary} install_bundler #{bundler_version}"
|
501
498
|
run "#{clean_environment} && cd #{paths.active_release} && ruby -S bundle _#{bundler_version}_ install #{install_switches}"
|
502
499
|
|
503
500
|
write_system_version
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'engineyard-serverside/about'
|
2
|
+
|
3
|
+
module EY
|
4
|
+
module Serverside
|
5
|
+
# Put the same engineyard-serverside on all the servers
|
6
|
+
class Propagator
|
7
|
+
def self.call(*args)
|
8
|
+
new(*args).call
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :config, :shell
|
12
|
+
|
13
|
+
def initialize(servers, config, shell, options={})
|
14
|
+
@remote_servers = servers.remote
|
15
|
+
@config, @shell = config, shell
|
16
|
+
end
|
17
|
+
|
18
|
+
# servers that need to have the gem installed
|
19
|
+
def servers
|
20
|
+
@servers ||= find_servers_missing_gem
|
21
|
+
end
|
22
|
+
|
23
|
+
# Find the servers that need the gem, then install the gem on them
|
24
|
+
def call
|
25
|
+
servers.any? && propagate
|
26
|
+
end
|
27
|
+
|
28
|
+
def remote_gem_file
|
29
|
+
File.join(Dir.tmpdir, About.gem_filename)
|
30
|
+
end
|
31
|
+
|
32
|
+
def gem_binary
|
33
|
+
File.join(Gem.default_bindir, 'gem')
|
34
|
+
end
|
35
|
+
|
36
|
+
# the [,)] is to stop us from looking for e.g. 0.5.1, seeing
|
37
|
+
# 0.5.11, and mistakenly thinking 0.5.1 is there
|
38
|
+
def check_command
|
39
|
+
%{#{gem_binary} list #{About.gem_name} | grep "#{About.gem_name}" | egrep -q "#{About.version.gsub(/\./, '\.')}[,)]"}
|
40
|
+
end
|
41
|
+
|
42
|
+
def scp_command(server)
|
43
|
+
Escape.shell_command([
|
44
|
+
'scp',
|
45
|
+
'-i', config.paths.internal_key.to_s,
|
46
|
+
"-o", "StrictHostKeyChecking=no",
|
47
|
+
About.gem_file,
|
48
|
+
"#{server.authority}:#{remote_gem_file}",
|
49
|
+
])
|
50
|
+
end
|
51
|
+
|
52
|
+
def install_command
|
53
|
+
"#{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'"
|
54
|
+
end
|
55
|
+
|
56
|
+
def count_servers(set)
|
57
|
+
"#{set.size} server#{set.size == 1 ? '' : 's'}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def find_servers_missing_gem
|
61
|
+
return @remote_servers if @remote_servers.empty?
|
62
|
+
shell.status "Verifying #{About.name_with_version} on #{count_servers(@remote_servers)}."
|
63
|
+
@remote_servers.select_in_parallel do |server|
|
64
|
+
!shell.logged_system(server.command_on_server('sh -l -c', check_command)).success?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def propagate
|
69
|
+
shell.status "Propagating #{About.name_with_version} to #{count_servers(servers)}."
|
70
|
+
servers.run_on_each { |server| shell.logged_system(scp_command(server)) }
|
71
|
+
servers.run_on_each { |server| shell.logged_system(server.command_on_server('sudo sh -l -c', install_command)) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'set'
|
2
|
+
require 'tempfile'
|
2
3
|
|
3
4
|
module EY
|
4
5
|
module Serverside
|
@@ -7,8 +8,8 @@ module EY
|
|
7
8
|
new(server_hash[:hostname], Set.new(server_hash[:roles].map{|r|r.to_sym}), server_hash[:name], server_hash[:user])
|
8
9
|
end
|
9
10
|
|
10
|
-
def
|
11
|
-
|
11
|
+
def authority
|
12
|
+
"#{user}@#{hostname}"
|
12
13
|
end
|
13
14
|
|
14
15
|
def role
|
@@ -63,27 +63,41 @@ module EY
|
|
63
63
|
end
|
64
64
|
|
65
65
|
# Run a command on this set of servers.
|
66
|
-
def run(shell, cmd, &
|
67
|
-
|
66
|
+
def run(shell, cmd, &block)
|
67
|
+
run_on_each do |server|
|
68
|
+
exec_cmd = server.command_on_server('sh -l -c', cmd, &block)
|
69
|
+
shell.logged_system(exec_cmd)
|
70
|
+
end
|
68
71
|
end
|
69
72
|
|
70
73
|
# Run a sudo command on this set of servers.
|
71
|
-
def sudo(shell, cmd, &
|
72
|
-
|
74
|
+
def sudo(shell, cmd, &block)
|
75
|
+
run_on_each do |server|
|
76
|
+
exec_cmd = server.command_on_server('sudo sh -l -c', cmd, &block)
|
77
|
+
shell.logged_system(exec_cmd)
|
78
|
+
end
|
73
79
|
end
|
74
80
|
|
75
|
-
|
76
|
-
|
77
|
-
def
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
81
|
+
# Makes a thread for each server and executes the block,
|
82
|
+
# returning an array of return values
|
83
|
+
def map_in_parallel(&block)
|
84
|
+
threads = map { |server| Thread.new { block.call(server) } }
|
85
|
+
threads.map { |t| t.value }
|
86
|
+
end
|
82
87
|
|
83
|
-
|
88
|
+
def select_in_parallel(&block)
|
89
|
+
results = map_in_parallel { |server| block.call(server) ? server : nil }.compact
|
90
|
+
self.class.new results
|
91
|
+
end
|
84
92
|
|
85
|
-
|
86
|
-
|
93
|
+
# Makes a theard for each server and executes the block,
|
94
|
+
# Assumes that the return value of the block is a CommandResult
|
95
|
+
# and ensures that all the command results were successful.
|
96
|
+
def run_on_each(&block)
|
97
|
+
results = map_in_parallel(&block)
|
98
|
+
failures = results.reject {|result| result.success? }
|
99
|
+
if failures.any?
|
100
|
+
message = failures.map { |f| f.inspect }.join("\n")
|
87
101
|
raise EY::Serverside::RemoteFailure.new(failures)
|
88
102
|
end
|
89
103
|
end
|
@@ -51,15 +51,15 @@ module EY
|
|
51
51
|
# $ cmd blah do \
|
52
52
|
# > something more
|
53
53
|
# > end
|
54
|
-
def
|
55
|
-
|
56
|
-
end
|
54
|
+
def command_show(cmd) debug cmd.gsub(/^/,' > ').sub(/>/, '$') end
|
55
|
+
def command_out(msg) debug msg.gsub(/^/,' ') end
|
56
|
+
def command_err(msg) unknown msg.gsub(/^/,' ') end
|
57
57
|
|
58
58
|
def logged_system(cmd)
|
59
|
-
|
59
|
+
command_show(cmd)
|
60
60
|
output = ""
|
61
|
-
outio = YieldIO.new { |msg| output << msg;
|
62
|
-
errio = YieldIO.new { |msg| output << msg;
|
61
|
+
outio = YieldIO.new { |msg| output << msg; command_out(msg) }
|
62
|
+
errio = YieldIO.new { |msg| output << msg; command_err(msg) }
|
63
63
|
result = spawn_process(cmd, outio, errio)
|
64
64
|
CommandResult.new(cmd, result.exitstatus, output)
|
65
65
|
end
|
@@ -31,8 +31,8 @@ module EY
|
|
31
31
|
def checkout
|
32
32
|
shell.status "Deploying revision #{short_log_message(to_checkout)}"
|
33
33
|
in_repository_cache do
|
34
|
-
(run("git checkout -
|
35
|
-
run("git reset
|
34
|
+
(run("git checkout -f '#{to_checkout}'") ||
|
35
|
+
run("git reset --hard '#{to_checkout}'")) &&
|
36
36
|
run("git submodule sync") &&
|
37
37
|
run("git submodule update --init") &&
|
38
38
|
run("git clean -dfq")
|
@@ -42,7 +42,12 @@ module EY
|
|
42
42
|
def to_checkout
|
43
43
|
return @to_checkout if @opts_ref == opts[:ref]
|
44
44
|
@opts_ref = opts[:ref]
|
45
|
-
|
45
|
+
clean_local_branch(@opts_ref)
|
46
|
+
@to_checkout = remote_branch?(@opts_ref) ? "origin/#{@opts_ref}" : @opts_ref
|
47
|
+
end
|
48
|
+
|
49
|
+
def clean_local_branch(ref)
|
50
|
+
system("#{git} show-branch #{ref} > /dev/null 2>&1 && #{git} branch -D #{ref} > /dev/null 2>&1")
|
46
51
|
end
|
47
52
|
|
48
53
|
def gc_repository_cache
|
@@ -79,7 +84,7 @@ module EY
|
|
79
84
|
"git --git-dir #{repository_cache}/.git --work-tree #{repository_cache}"
|
80
85
|
end
|
81
86
|
|
82
|
-
def
|
87
|
+
def remote_branch?(ref)
|
83
88
|
system("#{git} show-branch origin/#{ref} > /dev/null 2>&1")
|
84
89
|
end
|
85
90
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EY::Serverside::Propagator do
|
4
|
+
let(:config) do
|
5
|
+
EY::Serverside::Deploy::Configuration.new({
|
6
|
+
'app' => 'app',
|
7
|
+
'deploy_to' => deploy_dir.to_s,
|
8
|
+
'user' => ENV['USER'],
|
9
|
+
})
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:servers) do
|
13
|
+
EY::Serverside::Servers.from_hashes(
|
14
|
+
[
|
15
|
+
{:user => config.user, :hostname => 'localhost', :roles => %w[solo]},
|
16
|
+
{:user => config.user, :hostname => '127.0.0.1', :roles => %w[util], :name => 'myutil'},
|
17
|
+
]
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:solo) { servers.roles(:solo).first }
|
22
|
+
let(:util) { servers.roles(:util).first }
|
23
|
+
|
24
|
+
let(:shell) { mock('shell') }
|
25
|
+
let(:check_command) { util.command_on_server('sh -l -c', subject.check_command) }
|
26
|
+
let(:scp_command) { subject.scp_command(util) }
|
27
|
+
let(:install_command) { util.command_on_server('sudo sh -l -c', subject.install_command) }
|
28
|
+
|
29
|
+
subject do
|
30
|
+
EY::Serverside::Propagator.new(servers, config, shell)
|
31
|
+
end
|
32
|
+
|
33
|
+
def stub_shell_command(command, success, output="STUB OUTPUT")
|
34
|
+
shell.should_receive(:logged_system).once.ordered.with(command).and_return do
|
35
|
+
test_shell.command_show(command)
|
36
|
+
EY::Serverside::Shell::CommandResult.new(command, success ? 0 : 1, output)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
before do
|
41
|
+
shell.stub(:status) do |msg|
|
42
|
+
test_shell.status(msg) # hax so you can see the output with VERBOSE
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "no remote servers" do
|
47
|
+
subject { EY::Serverside::Propagator.new(test_servers, config, shell) }
|
48
|
+
|
49
|
+
it "returns without doing anything" do
|
50
|
+
shell.should_not_receive(:logged_system)
|
51
|
+
subject.call
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "all servers have the gem" do
|
56
|
+
before do
|
57
|
+
stub_shell_command(check_command, true)
|
58
|
+
shell.should_not_receive(:logged_system).with(scp_command)
|
59
|
+
shell.should_not_receive(:logged_system).with(install_command)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "finds no servers" do
|
63
|
+
subject.servers.should be_empty
|
64
|
+
subject.call
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with a server missing the gem" do
|
69
|
+
before do
|
70
|
+
stub_shell_command(check_command, false)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "finds servers that need the gem installed and installs it" do
|
74
|
+
stub_shell_command(scp_command, true)
|
75
|
+
stub_shell_command(install_command, true)
|
76
|
+
|
77
|
+
subject.servers.to_a.should == [util]
|
78
|
+
subject.call
|
79
|
+
end
|
80
|
+
|
81
|
+
it "raises if the scp fails" do
|
82
|
+
stub_shell_command(scp_command, false)
|
83
|
+
shell.should_not_receive(:logged_system).with(install_command)
|
84
|
+
|
85
|
+
lambda { subject.call }.should raise_error(EY::Serverside::RemoteFailure)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "raises if the install fails" do
|
89
|
+
stub_shell_command(scp_command, true)
|
90
|
+
stub_shell_command(install_command, false)
|
91
|
+
|
92
|
+
lambda { subject.call }.should raise_error(EY::Serverside::RemoteFailure)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|