engineyard 1.3.13 → 1.3.14
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/engineyard/model/instance.rb +36 -9
- data/lib/engineyard/version.rb +1 -1
- data/spec/ey/deploy_spec.rb +30 -30
- data/spec/support/helpers.rb +71 -7
- metadata +9 -9
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'escape'
|
2
|
-
require '
|
2
|
+
require 'net/ssh'
|
3
3
|
|
4
4
|
module EY
|
5
5
|
module Model
|
@@ -74,20 +74,47 @@ module EY
|
|
74
74
|
def ssh(remote_command, verbose, &block)
|
75
75
|
raise(ArgumentError, "Block required!") unless block
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
raw_cmd << "#{environment.username}@#{hostname}"
|
80
|
-
raw_cmd << remote_command
|
81
|
-
|
82
|
-
cmd = Escape.shell_command(raw_cmd)
|
77
|
+
exit_code = nil
|
78
|
+
cmd = Escape.shell_command(['bash', '-lc', remote_command])
|
83
79
|
EY.ui.debug(cmd)
|
84
80
|
puts cmd if verbose
|
85
81
|
if ENV["NO_SSH"]
|
86
82
|
block.call("NO_SSH is set. No output.")
|
87
83
|
true
|
88
84
|
else
|
89
|
-
|
90
|
-
|
85
|
+
begin
|
86
|
+
Net::SSH.start(hostname, environment.username, :paranoid => false) do |net_ssh|
|
87
|
+
net_ssh.open_channel do |channel|
|
88
|
+
channel.exec cmd do |_, success|
|
89
|
+
unless success
|
90
|
+
block.call "Remote command execution failed"
|
91
|
+
return false
|
92
|
+
end
|
93
|
+
|
94
|
+
channel.on_data do |_, data|
|
95
|
+
block.call data
|
96
|
+
end
|
97
|
+
|
98
|
+
channel.on_extended_data do |_, _, data|
|
99
|
+
block.call data
|
100
|
+
end
|
101
|
+
|
102
|
+
channel.on_request("exit-status") do |_, data|
|
103
|
+
exit_code = data.read_long
|
104
|
+
end
|
105
|
+
|
106
|
+
channel.on_request("exit-signal") do |_, data|
|
107
|
+
exit_code = 255
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
net_ssh.loop
|
113
|
+
end
|
114
|
+
exit_code.zero?
|
115
|
+
rescue Net::SSH::AuthenticationFailed
|
116
|
+
raise EY::Error, "Authentication Failed: Please add your environment's ssh key with: ssh-add path/to/key"
|
117
|
+
end
|
91
118
|
end
|
92
119
|
end
|
93
120
|
|
data/lib/engineyard/version.rb
CHANGED
data/spec/ey/deploy_spec.rb
CHANGED
@@ -53,25 +53,25 @@ describe "ey deploy" do
|
|
53
53
|
context "with invalid input" do
|
54
54
|
it "complains when there is no app" do
|
55
55
|
api_scenario "empty"
|
56
|
-
|
56
|
+
fast_failing_ey ["deploy"]
|
57
57
|
@err.should include(%|no application configured|)
|
58
58
|
end
|
59
59
|
|
60
60
|
it "complains when the specified environment does not contain the app" do
|
61
61
|
api_scenario "one app, one environment, not linked"
|
62
|
-
|
62
|
+
fast_failing_ey %w[deploy -e giblets -r master]
|
63
63
|
@err.should match(/there is no application configured/i)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "complains when environment is not specified and app is in >1 environment" do
|
67
67
|
api_scenario "one app, many environments"
|
68
|
-
|
68
|
+
fast_failing_ey %w[deploy]
|
69
69
|
@err.should match(/multiple app deployments possible/i)
|
70
70
|
end
|
71
71
|
|
72
72
|
it "complains when the app master is in a non-running state" do
|
73
73
|
api_scenario "one app, one environment, app master red"
|
74
|
-
|
74
|
+
fast_failing_ey %w[deploy --environment giblets --ref master]
|
75
75
|
@err.should_not match(/No running instances/i)
|
76
76
|
@err.should match(/running.*\(green\)/)
|
77
77
|
end
|
@@ -83,24 +83,24 @@ describe "ey deploy" do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
it "finds engineyard-serverside despite its being buried in the filesystem" do
|
86
|
-
|
86
|
+
fast_ey %w[deploy]
|
87
87
|
@ssh_commands.last.should =~ %r{/usr/local/ey_resin/ruby/bin/engineyard-serverside}
|
88
88
|
end
|
89
89
|
|
90
90
|
it "defaults to 'rake db:migrate'" do
|
91
|
-
|
91
|
+
fast_ey %w[deploy]
|
92
92
|
@ssh_commands.last.should =~ /engineyard-serverside.*deploy/
|
93
93
|
@ssh_commands.last.should =~ /--migrate 'rake db:migrate --trace'/
|
94
94
|
end
|
95
95
|
|
96
96
|
it "can be disabled with --no-migrate" do
|
97
|
-
|
97
|
+
fast_ey %w[deploy --no-migrate]
|
98
98
|
@ssh_commands.last.should =~ /engineyard-serverside.*deploy/
|
99
99
|
@ssh_commands.last.should_not =~ /--migrate/
|
100
100
|
end
|
101
101
|
|
102
102
|
it "uses the default when --migrate is specified with no value" do
|
103
|
-
|
103
|
+
fast_ey %w[deploy --migrate]
|
104
104
|
@ssh_commands.last.should match(/--migrate 'rake db:migrate --trace'/)
|
105
105
|
end
|
106
106
|
|
@@ -111,7 +111,7 @@ describe "ey deploy" do
|
|
111
111
|
after { File.unlink 'ey.yml' }
|
112
112
|
|
113
113
|
it "migrates with the custom command by default" do
|
114
|
-
|
114
|
+
fast_ey %w[deploy]
|
115
115
|
@ssh_commands.last.should =~ /--migrate 'thor fancy:migrate'/
|
116
116
|
end
|
117
117
|
end
|
@@ -121,18 +121,18 @@ describe "ey deploy" do
|
|
121
121
|
after { File.unlink 'ey.yml' }
|
122
122
|
|
123
123
|
it "does not migrate by default" do
|
124
|
-
|
124
|
+
fast_ey %w[deploy]
|
125
125
|
@ssh_commands.last.should =~ /engineyard-serverside.*deploy/
|
126
126
|
@ssh_commands.last.should_not =~ /--migrate/
|
127
127
|
end
|
128
128
|
|
129
129
|
it "can be turned back on with --migrate" do
|
130
|
-
|
130
|
+
fast_ey ["deploy", "--migrate", "rake fancy:migrate"]
|
131
131
|
@ssh_commands.last.should =~ /--migrate 'rake fancy:migrate'/
|
132
132
|
end
|
133
133
|
|
134
134
|
it "migrates with the default when --migrate is specified with no value" do
|
135
|
-
|
135
|
+
fast_ey %w[deploy --migrate]
|
136
136
|
@ssh_commands.last.should match(/--migrate 'rake db:migrate --trace'/)
|
137
137
|
end
|
138
138
|
end
|
@@ -142,7 +142,7 @@ describe "ey deploy" do
|
|
142
142
|
after { File.unlink 'ey.yml' }
|
143
143
|
|
144
144
|
it "migrates with the default" do
|
145
|
-
|
145
|
+
fast_ey %w[deploy]
|
146
146
|
@ssh_commands.last.should match(/--migrate 'rake db:migrate --trace'/)
|
147
147
|
end
|
148
148
|
end
|
@@ -155,12 +155,12 @@ describe "ey deploy" do
|
|
155
155
|
after { File.unlink 'ey.yml' }
|
156
156
|
|
157
157
|
it "does not migrate by default" do
|
158
|
-
|
158
|
+
fast_ey %w[deploy]
|
159
159
|
@ssh_commands.last.should_not match(/--migrate/)
|
160
160
|
end
|
161
161
|
|
162
162
|
it "migrates with the custom command when --migrate is specified with no value" do
|
163
|
-
|
163
|
+
fast_ey %w[deploy --migrate]
|
164
164
|
@ssh_commands.last.should match(/--migrate 'thor fancy:migrate'/)
|
165
165
|
end
|
166
166
|
end
|
@@ -172,7 +172,7 @@ describe "ey deploy" do
|
|
172
172
|
end
|
173
173
|
|
174
174
|
it "passes the framework environment" do
|
175
|
-
|
175
|
+
fast_ey %w[deploy]
|
176
176
|
@ssh_commands.last.should match(/--framework-env production/)
|
177
177
|
end
|
178
178
|
end
|
@@ -199,27 +199,27 @@ describe "ey deploy" do
|
|
199
199
|
|
200
200
|
context "without a configured default branch" do
|
201
201
|
it "defaults to the checked-out local branch" do
|
202
|
-
|
202
|
+
fast_ey %w[deploy]
|
203
203
|
@ssh_commands.last.should =~ /--ref resolved-current-branch/
|
204
204
|
end
|
205
205
|
|
206
206
|
it "deploys another branch if given" do
|
207
|
-
|
207
|
+
fast_ey %w[deploy --ref master]
|
208
208
|
@ssh_commands.last.should =~ /--ref resolved-master/
|
209
209
|
end
|
210
210
|
|
211
211
|
it "deploys a tag if given" do
|
212
|
-
|
212
|
+
fast_ey %w[deploy --ref v1]
|
213
213
|
@ssh_commands.last.should =~ /--ref resolved-v1/
|
214
214
|
end
|
215
215
|
|
216
216
|
it "allows using --branch to specify a branch" do
|
217
|
-
|
217
|
+
fast_ey %w[deploy --branch master]
|
218
218
|
@ssh_commands.last.should match(/--ref resolved-master/)
|
219
219
|
end
|
220
220
|
|
221
221
|
it "allows using --tag to specify the tag" do
|
222
|
-
|
222
|
+
fast_ey %w[deploy --tag v1]
|
223
223
|
@ssh_commands.last.should match(/--ref resolved-v1/)
|
224
224
|
end
|
225
225
|
end
|
@@ -234,7 +234,7 @@ describe "ey deploy" do
|
|
234
234
|
end
|
235
235
|
|
236
236
|
it "gets passed along to engineyard-serverside" do
|
237
|
-
|
237
|
+
fast_ey %w[deploy]
|
238
238
|
@ssh_commands.last.should =~ /--config '\{\"bert\":\"ernie\"\}'/
|
239
239
|
end
|
240
240
|
end
|
@@ -249,17 +249,17 @@ describe "ey deploy" do
|
|
249
249
|
end
|
250
250
|
|
251
251
|
it "deploys the default branch by default" do
|
252
|
-
|
252
|
+
fast_ey %w[deploy]
|
253
253
|
@ssh_commands.last.should =~ /--ref resolved-master/
|
254
254
|
end
|
255
255
|
|
256
256
|
it "complains about a non-default branch without --ignore-default_branch" do
|
257
|
-
|
257
|
+
fast_failing_ey %w[deploy -r current-branch]
|
258
258
|
@err.should =~ /deploy branch is set to "master"/
|
259
259
|
end
|
260
260
|
|
261
261
|
it "deploys a non-default branch with --ignore-default-branch" do
|
262
|
-
|
262
|
+
fast_ey %w[deploy -r current-branch --ignore-default-branch]
|
263
263
|
@ssh_commands.last.should =~ /--ref resolved-current-branch/
|
264
264
|
end
|
265
265
|
end
|
@@ -271,7 +271,7 @@ describe "ey deploy" do
|
|
271
271
|
end
|
272
272
|
|
273
273
|
it "lets you choose by complete name even if the complete name is ambiguous" do
|
274
|
-
|
274
|
+
fast_ey %w[deploy --environment railsapp_staging]
|
275
275
|
@out.should match(/Beginning deploy for.*'railsapp_staging'/)
|
276
276
|
end
|
277
277
|
end
|
@@ -304,7 +304,7 @@ describe "ey deploy" do
|
|
304
304
|
after { File.unlink("ey.yml") }
|
305
305
|
|
306
306
|
it "overrides what's in ey.yml" do
|
307
|
-
|
307
|
+
fast_ey %w[deploy --extra-deploy-hook-options beer:esb]
|
308
308
|
extra_deploy_hook_options['beer'].should == 'esb'
|
309
309
|
end
|
310
310
|
end
|
@@ -325,14 +325,14 @@ describe "ey deploy" do
|
|
325
325
|
end
|
326
326
|
|
327
327
|
it "allows you to specify an app when not in a directory" do
|
328
|
-
|
328
|
+
fast_ey %w[deploy --app rails232app --ref master]
|
329
329
|
@ssh_commands.last.should match(/--app rails232app/)
|
330
330
|
@ssh_commands.last.should match(/--ref resolved-master/)
|
331
331
|
end
|
332
332
|
|
333
333
|
it "requires that you specify a ref when specifying the application" do
|
334
334
|
Dir.chdir(File.expand_path("~")) do
|
335
|
-
|
335
|
+
fast_failing_ey %w[deploy --app rails232app]
|
336
336
|
@err.should match(/you must also specify the ref to deploy/)
|
337
337
|
end
|
338
338
|
end
|
@@ -343,7 +343,7 @@ describe "ey deploy" do
|
|
343
343
|
|
344
344
|
before(:all) do
|
345
345
|
api_scenario "one app, one environment", "user@git.host:path/to/repo.git"
|
346
|
-
|
346
|
+
fast_ey ["deploy"]
|
347
347
|
@deploy_command = @ssh_commands.find {|c| c =~ /engineyard-serverside.*deploy/ }
|
348
348
|
end
|
349
349
|
|
data/spec/support/helpers.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
require 'engineyard/cli'
|
2
|
+
|
1
3
|
require 'realweb'
|
2
|
-
require
|
4
|
+
require 'rest_client'
|
3
5
|
require 'open4'
|
6
|
+
require 'stringio'
|
4
7
|
|
5
8
|
module Spec
|
6
9
|
module Helpers
|
@@ -16,6 +19,56 @@ module Spec
|
|
16
19
|
NonzeroExitStatus = Class.new(UnexpectedExit)
|
17
20
|
ZeroExitStatus = Class.new(UnexpectedExit)
|
18
21
|
|
22
|
+
def fast_ey(args)
|
23
|
+
err, out = StringIO.new, StringIO.new
|
24
|
+
capture_stderr_into(err) do
|
25
|
+
capture_stdout_into(out) do
|
26
|
+
with_env('DEBUG' => 'true') do
|
27
|
+
EY::CLI.start(args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
ensure
|
32
|
+
@err, @out = err.string, out.string
|
33
|
+
@raw_ssh_commands, @ssh_commands = extract_ssh_commands(@out)
|
34
|
+
end
|
35
|
+
|
36
|
+
def fast_failing_ey(*args)
|
37
|
+
begin
|
38
|
+
fast_ey(*args)
|
39
|
+
raise ZeroExitStatus
|
40
|
+
rescue SystemExit => exit_status
|
41
|
+
# SystemExit typically indicates a bogus command, which we
|
42
|
+
# here in expected-to-fail land are entirely happy with.
|
43
|
+
nil
|
44
|
+
rescue EY::Error => e
|
45
|
+
more_err, more_out = StringIO.new, StringIO.new
|
46
|
+
|
47
|
+
capture_stderr_into(more_err) do
|
48
|
+
capture_stdout_into(more_out) do
|
49
|
+
EY.ui.print_exception(e)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
@err << more_err.string
|
54
|
+
@out << more_out.string
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def capture_stderr_into(stream)
|
59
|
+
$stderr = stream
|
60
|
+
yield
|
61
|
+
ensure
|
62
|
+
$stderr = STDERR
|
63
|
+
end
|
64
|
+
|
65
|
+
def capture_stdout_into(stream)
|
66
|
+
$stdout = stream
|
67
|
+
yield
|
68
|
+
ensure
|
69
|
+
$stdout = STDOUT
|
70
|
+
end
|
71
|
+
|
19
72
|
def ey(cmd = nil, options = {}, &block)
|
20
73
|
hide_err = options.has_key?(:hide_err) ? options[:hide_err] : options[:expect_failure]
|
21
74
|
path_prepends = options[:prepend_to_path]
|
@@ -54,14 +107,26 @@ module Spec
|
|
54
107
|
end
|
55
108
|
end
|
56
109
|
|
57
|
-
@raw_ssh_commands = @out
|
58
|
-
|
110
|
+
@raw_ssh_commands, @ssh_commands = extract_ssh_commands(@out)
|
111
|
+
|
112
|
+
puts @err unless @err.empty? || hide_err
|
113
|
+
@out
|
114
|
+
end
|
115
|
+
|
116
|
+
def extract_ssh_commands(output)
|
117
|
+
raw_ssh_commands = @out.split(/\n/).find_all do |line|
|
118
|
+
line =~ /^bash -lc/ || line =~ /^ssh/
|
59
119
|
end
|
60
120
|
|
61
|
-
|
121
|
+
ssh_commands = raw_ssh_commands.map do |cmd|
|
62
122
|
# Strip off everything up to and including user@host, leaving
|
63
123
|
# just the command that the remote system would run
|
64
|
-
|
124
|
+
#
|
125
|
+
# XXX: this is a really icky icky.
|
126
|
+
# engineyard gem was written as if shelling out to run serverside
|
127
|
+
# and running an ssh command will always be the same. This is a nasty
|
128
|
+
# hack to get it working with Net::SSH for now so we can repair 1.9.2.
|
129
|
+
ssh_prefix_removed = cmd.gsub(/^bash -lc /, '').gsub(/^ssh .*?\w+@\S*\s*/, '')
|
65
130
|
|
66
131
|
# Its arguments have been double-escaped: one layer is to get
|
67
132
|
# them through our local shell and into ssh, and the other
|
@@ -72,8 +137,7 @@ module Spec
|
|
72
137
|
`echo #{just_the_remote_command}`.strip
|
73
138
|
end
|
74
139
|
|
75
|
-
|
76
|
-
@out
|
140
|
+
[raw_ssh_commands, ssh_commands]
|
77
141
|
end
|
78
142
|
|
79
143
|
def api_scenario(scenario, remote = "user@git.host:path/to/repo.git")
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: engineyard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 14
|
10
|
+
version: 1.3.14
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- EY Cloud Team
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-11 00:00:00 -08:00
|
19
19
|
default_executable: ey
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -118,14 +118,14 @@ dependencies:
|
|
118
118
|
requirements:
|
119
119
|
- - ~>
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
hash:
|
121
|
+
hash: 33
|
122
122
|
segments:
|
123
|
-
-
|
123
|
+
- 2
|
124
124
|
- 0
|
125
|
-
-
|
126
|
-
version:
|
125
|
+
- 23
|
126
|
+
version: 2.0.23
|
127
127
|
requirement: *id007
|
128
|
-
name:
|
128
|
+
name: net-ssh
|
129
129
|
prerelease: false
|
130
130
|
type: :runtime
|
131
131
|
description: This gem allows you to deploy your rails application to the Engine Yard cloud directly from the command line.
|