engineyard 0.5.0 → 0.5.2

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.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module EY
2
2
  require 'engineyard/ruby_ext'
3
3
 
4
- VERSION = "0.5.0"
4
+ VERSION = "0.5.2"
5
5
 
6
6
  autoload :API, 'engineyard/api'
7
7
  autoload :Collection, 'engineyard/collection'
@@ -1,10 +1,11 @@
1
1
  module EY
2
2
  module Model
3
- class Environment < ApiStruct.new(:id, :name, :instances_count, :apps, :app_master, :username, :api)
3
+ class Environment < ApiStruct.new(:id, :name, :instances, :instances_count, :apps, :app_master, :username, :api)
4
4
  def self.from_hash(hash)
5
5
  super.tap do |env|
6
6
  env.username = hash['ssh_username']
7
7
  env.apps = App.from_array(env.apps, :api => env.api)
8
+ env.instances = Instance.from_array(hash['instances'], :environment => env)
8
9
  env.app_master = Instance.from_hash(env.app_master.merge(:environment => env)) if env.app_master
9
10
  end
10
11
  end
@@ -17,10 +18,6 @@ module EY
17
18
  Log.from_array(api_get("/environments/#{id}/logs")["logs"])
18
19
  end
19
20
 
20
- def instances
21
- Instance.from_array(api_get("/environments/#{id}/instances")["instances"], :environment => self)
22
- end
23
-
24
21
  def app_master!
25
22
  master = app_master
26
23
  if master.nil?
@@ -2,8 +2,8 @@ require 'escape'
2
2
 
3
3
  module EY
4
4
  module Model
5
- class Instance < ApiStruct.new(:id, :role, :status, :amazon_id, :public_hostname, :environment)
6
- EYSD_VERSION = "~>0.4.1"
5
+ class Instance < ApiStruct.new(:id, :role, :name, :status, :amazon_id, :public_hostname, :environment)
6
+ EYSD_VERSION = "~>0.5.0"
7
7
  CHECK_SCRIPT = <<-SCRIPT
8
8
  require "rubygems"
9
9
  requirement = Gem::Requirement.new("#{EYSD_VERSION}")
@@ -31,40 +31,36 @@ exit(17) # required_version < current_version
31
31
 
32
32
 
33
33
  def deploy(app, ref, migration_command=nil, extra_configuration=nil)
34
- deploy_cmd = [eysd_path, 'deploy', '--app', app.name, '--branch', ref]
34
+ deploy_args = ['--app', app.name, '--branch', ref]
35
35
 
36
36
  if extra_configuration
37
- deploy_cmd << '--config' << extra_configuration.to_json
37
+ deploy_args << '--config' << extra_configuration.to_json
38
38
  end
39
39
 
40
40
  if migration_command
41
- deploy_cmd << "--migrate" << migration_command
41
+ deploy_args << "--migrate" << migration_command
42
42
  end
43
43
 
44
- ssh Escape.shell_command(deploy_cmd)
44
+ invoke_eysd_deploy(deploy_args)
45
45
  end
46
46
 
47
47
  def rollback(app, extra_configuration=nil)
48
- deploy_cmd = [eysd_path, 'deploy', 'rollback', '--app', app.name]
48
+ deploy_args = ['rollback', '--app', app.name]
49
49
 
50
50
  if extra_configuration
51
- deploy_cmd << '--config' << extra_configuration.to_json
51
+ deploy_args << '--config' << extra_configuration.to_json
52
52
  end
53
53
 
54
- ssh Escape.shell_command(deploy_cmd)
54
+ invoke_eysd_deploy(deploy_args)
55
55
  end
56
56
 
57
57
 
58
58
  def put_up_maintenance_page(app)
59
- ssh Escape.shell_command([
60
- eysd_path, 'deploy', 'enable_maintenance_page', '--app', app.name
61
- ])
59
+ invoke_eysd_deploy(['enable_maintenance_page', '--app', app.name])
62
60
  end
63
61
 
64
62
  def take_down_maintenance_page(app)
65
- ssh Escape.shell_command([
66
- eysd_path, 'deploy', 'disable_maintenance_page', '--app', app.name
67
- ])
63
+ invoke_eysd_deploy(['disable_maintenance_page', '--app', app.name])
68
64
  end
69
65
 
70
66
 
@@ -122,6 +118,18 @@ exit(17) # required_version < current_version
122
118
  end
123
119
  end
124
120
 
121
+ def invoke_eysd_deploy(deploy_args)
122
+ start = [eysd_path, 'deploy']
123
+ instance_args = environment.instances.inject(['--instances']) do |command, inst|
124
+ instance_tuple = [inst.public_hostname, inst.role]
125
+ instance_tuple << inst.name if inst.name
126
+
127
+ command << instance_tuple.join(',')
128
+ end
129
+
130
+ ssh Escape.shell_command(start + deploy_args + instance_args)
131
+ end
132
+
125
133
  def eysd_path
126
134
  "/usr/local/ey_resin/ruby/bin/eysd"
127
135
  end
@@ -60,17 +60,19 @@ describe "EY::Model::Environment#instances" do
60
60
  given "it has an api"
61
61
 
62
62
  it "returns instances" do
63
- env = EY::Model::Environment.from_hash({
64
- "id" => 10291,
65
- "api" => @api,
66
- })
67
-
68
63
  instance_data = {
69
64
  "id" => "1",
70
65
  "role" => "app_master",
71
66
  "amazon_id" => "i-likebeer",
72
67
  "public_hostname" => "banana_master"
73
68
  }
69
+
70
+ env = EY::Model::Environment.from_hash({
71
+ "id" => 10291,
72
+ "api" => @api,
73
+ "instances" => [instance_data],
74
+ })
75
+
74
76
  FakeWeb.register_uri(:get,
75
77
  "https://cloud.engineyard.com/api/v2/environments/#{env.id}/instances",
76
78
  :body => {"instances" => [instance_data]}.to_json,
@@ -95,7 +97,7 @@ describe "EY::Model::Environment#app_master!" do
95
97
  "id" => 11830,
96
98
  "name" => "guinea-pigs-are-delicious",
97
99
  "app_master" => app_master,
98
- "instances" => [app_master],
100
+ "instances" => [app_master].compact,
99
101
  })
100
102
  end
101
103
 
data/spec/ey/ssh_spec.rb CHANGED
@@ -30,24 +30,9 @@ describe "ey ssh" do
30
30
  end
31
31
 
32
32
  def verify_ran(scenario)
33
- ssh_target = scenario[:ssh_username] + '@' + scenario[:master_ip]
33
+ ssh_target = scenario[:ssh_username] + '@' + scenario[:master_hostname]
34
34
  @raw_ssh_commands.should == ["ssh #{ssh_target}"]
35
35
  end
36
36
 
37
37
  it_should_behave_like "it takes an environment name"
38
38
  end
39
-
40
- describe "ey ssh ENV" do
41
- given "integration"
42
-
43
- before(:all) do
44
- api_scenario "one app, many similarly-named environments"
45
- end
46
-
47
- it "doesn't require you to be in any app's directory if the name is unambiguous" do
48
- Dir.chdir(Dir.tmpdir) do
49
- ey "ssh -e prod", :prepend_to_path => {'ssh' => print_my_args_ssh}
50
- @raw_ssh_commands.should == ["ssh turkey@174.129.198.124"]
51
- end
52
- end
53
- end
@@ -143,47 +143,76 @@ private
143
143
  [{
144
144
  "ssh_username" => "turkey",
145
145
  "instances" => [{
146
- "public_hostname" => "174.129.198.124",
147
146
  "status" => "running",
148
- "id" => 27220}],
147
+ "id" => 27220,
148
+ "amazon_id" => 'i-ddbbdd92',
149
+ "role" => "solo",
150
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}],
149
151
  "name" => "giblets",
150
152
  "apps" => [],
151
153
  "instances_count" => 1,
152
154
  "stack_name" => "nginx_mongrel",
153
155
  "id" => 200,
154
156
  "app_master" => {
155
- "public_hostname" => "174.129.198.124",
156
157
  "status" => "running",
157
- "id" => 27220}}]
158
+ "id" => 27220,
159
+ "amazon_id" => 'i-ddbbdd92',
160
+ "role" => "solo",
161
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}}]
158
162
  end
159
163
  end # UnlinkedApp
160
164
 
161
165
  class LinkedApp < Empty
166
+ def _instances
167
+ [{
168
+ "id" => 27220,
169
+ "role" => "app_master",
170
+ "name" => nil,
171
+ "status" => "running",
172
+ "amazon_id" => 'i-ddbbdd92',
173
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com",
174
+ }, {
175
+ "id" => 22721,
176
+ "name" => nil,
177
+ "role" => "db_master",
178
+ "status" => "running",
179
+ "amazon_id" => "i-d4cdddbf",
180
+ "public_hostname" => "ec2-174-129-142-53.compute-1.amazonaws.com",
181
+ }, {
182
+ "id" => 22722,
183
+ "role" => "app",
184
+ "name" => nil,
185
+ "status" => "building",
186
+ "amazon_id" => "i-d2e3f1b9",
187
+ "public_hostname" => "ec2-72-44-46-66.compute-1.amazonaws.com",
188
+ }, {
189
+ "id" => 22723,
190
+ "role" => "util",
191
+ "name" => "fluffy",
192
+ "status" => "running",
193
+ "amazon_id" => "i-80e3f1eb",
194
+ "public_hostname" => "ec2-184-73-116-228.compute-1.amazonaws.com",
195
+ }]
196
+ end
197
+
162
198
  def apps
163
199
  [{"name" => "rails232app",
164
200
  "environments" => [{"ssh_username" => "turkey",
165
- "instances" => [{"public_hostname" => "174.129.198.124",
166
- "status" => "running",
167
- "id" => 27220}],
201
+ "instances" => _instances,
168
202
  "name" => "giblets",
169
203
  "apps" => [{"name" => "rails232app",
170
204
  "repository_uri" => git_remote}],
171
205
  "instances_count" => 1,
172
206
  "stack_name" => "nginx_mongrel",
173
207
  "id" => 200,
174
- "app_master" => {"public_hostname" => "174.129.198.124",
175
- "status" => "running",
176
- "id" => 27220}}],
208
+ "app_master" => _instances.first}],
177
209
  "repository_uri" => git_remote}]
178
210
  end
179
211
 
180
212
  def environments
181
213
  [{
182
214
  "ssh_username" => "turkey",
183
- "instances" => [{
184
- "public_hostname" => "174.129.198.124",
185
- "status" => "running",
186
- "id" => 27220}],
215
+ "instances" => _instances,
187
216
  "name" => "giblets",
188
217
  "apps" => [{
189
218
  "name" => "rails232app",
@@ -191,10 +220,7 @@ private
191
220
  "instances_count" => 1,
192
221
  "stack_name" => "nginx_mongrel",
193
222
  "id" => 200,
194
- "app_master" => {
195
- "public_hostname" => "174.129.198.124",
196
- "status" => "running",
197
- "id" => 27220}}]
223
+ "app_master" => _instances[0]}]
198
224
  end
199
225
 
200
226
  def logs(env_id)
@@ -233,17 +259,23 @@ private
233
259
  [{"name" => "rails232app",
234
260
  "environments" => [{
235
261
  "ssh_username" => "turkey",
236
- "instances" => [{"public_hostname" => "174.129.198.124",
262
+ "instances" => [{
237
263
  "status" => "running",
238
- "id" => 27220}],
264
+ "id" => 27220,
265
+ "amazon_id" => 'i-ddbbdd92',
266
+ "role" => "solo",
267
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}],
239
268
  "name" => "giblets",
240
269
  "apps" => apps,
241
270
  "instances_count" => 1,
242
271
  "stack_name" => "nginx_mongrel",
243
272
  "id" => 200,
244
- "app_master" => {"public_hostname" => "174.129.198.124",
273
+ "app_master" => {
245
274
  "status" => "running",
246
- "id" => 27220}
275
+ "id" => 27220,
276
+ "amazon_id" => 'i-ddbbdd92',
277
+ "role" => "solo",
278
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}
247
279
  }, {
248
280
  "ssh_username" => "ham",
249
281
  "instances" => [],
@@ -261,9 +293,11 @@ private
261
293
  [{
262
294
  "ssh_username" => "turkey",
263
295
  "instances" => [{
264
- "public_hostname" => "174.129.198.124",
265
296
  "status" => "running",
266
- "id" => 27220}],
297
+ "id" => 27220,
298
+ "amazon_id" => 'i-ddbbdd92',
299
+ "role" => "solo",
300
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}],
267
301
  "name" => "giblets",
268
302
  "apps" => [{
269
303
  "name" => "rails232app",
@@ -272,9 +306,11 @@ private
272
306
  "stack_name" => "nginx_mongrel",
273
307
  "id" => 200,
274
308
  "app_master" => {
275
- "public_hostname" => "174.129.198.124",
276
309
  "status" => "running",
277
- "id" => 27220}
310
+ "id" => 27220,
311
+ "amazon_id" => 'i-ddbbdd92',
312
+ "role" => "solo",
313
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}
278
314
  }, {
279
315
  "ssh_username" => "ham",
280
316
  "instances" => [],
@@ -301,18 +337,22 @@ private
301
337
  "environments" => [{
302
338
  "ssh_username" => "turkey",
303
339
  "instances" => [{
304
- "public_hostname" => "174.129.198.124",
305
340
  "status" => "running",
306
- "id" => 27220}],
341
+ "id" => 27220,
342
+ "amazon_id" => 'i-ddbbdd92',
343
+ "role" => "solo",
344
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}],
307
345
  "name" => "railsapp_production",
308
346
  "apps" => apps,
309
347
  "instances_count" => 1,
310
348
  "stack_name" => "nginx_mongrel",
311
349
  "id" => 200,
312
350
  "app_master" => {
313
- "public_hostname" => "174.129.198.124",
314
351
  "status" => "running",
315
352
  "id" => 27220,
353
+ "amazon_id" => 'i-ddbbdd92',
354
+ "role" => "solo",
355
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com",
316
356
  },
317
357
  }, {
318
358
  "ssh_username" => "ham",
@@ -320,6 +360,7 @@ private
320
360
  "public_hostname" => '127.3.2.1',
321
361
  "status" => "running",
322
362
  "id" => 63066,
363
+ "role" => "solo",
323
364
  }],
324
365
  "name" => "railsapp_staging",
325
366
  "apps" => apps,
@@ -330,13 +371,15 @@ private
330
371
  "public_hostname" => '127.3.2.1',
331
372
  "status" => "running",
332
373
  "id" => 63066,
374
+ "role" => "solo",
333
375
  },
334
376
  }, {
335
377
  "ssh_username" => "ham",
336
378
  "instances" => [{
337
- "public_hostname" => '127.44.55.66',
338
379
  "status" => "running",
339
380
  "id" => 59395,
381
+ "role" => "solo",
382
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com",
340
383
  }],
341
384
  "name" => "railsapp_staging_2",
342
385
  "apps" => apps,
@@ -347,6 +390,7 @@ private
347
390
  "public_hostname" => '127.44.55.66',
348
391
  "status" => "running",
349
392
  "id" => 59395,
393
+ "role" => "solo",
350
394
  },
351
395
  }],
352
396
  "repository_uri" => git_remote}]
@@ -356,9 +400,11 @@ private
356
400
  [{
357
401
  "ssh_username" => "turkey",
358
402
  "instances" => [{
359
- "public_hostname" => "174.129.198.124",
360
403
  "status" => "running",
361
- "id" => 27220}],
404
+ "id" => 27220,
405
+ "amazon_id" => 'i-ddbbdd92',
406
+ "role" => "solo",
407
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}],
362
408
  "name" => "railsapp_production",
363
409
  "apps" => [{
364
410
  "name" => "rails232app",
@@ -367,15 +413,19 @@ private
367
413
  "stack_name" => "nginx_mongrel",
368
414
  "id" => 200,
369
415
  "app_master" => {
370
- "public_hostname" => "174.129.198.124",
416
+ "public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com",
371
417
  "status" => "running",
372
- "id" => 27220}
418
+ "id" => 27220,
419
+ "amazon_id" => 'i-ddbbdd92',
420
+ "role" => "solo"},
373
421
  }, {
374
422
  "ssh_username" => "ham",
375
423
  "instances" => [{
376
424
  "public_hostname" => '127.3.2.1',
377
425
  "status" => "running",
378
426
  "id" => 63066,
427
+ "amazon_id" => 'i-09fec72a',
428
+ "role" => "solo",
379
429
  }],
380
430
  "name" => "railsapp_staging",
381
431
  "apps" => [{
@@ -388,6 +438,8 @@ private
388
438
  "public_hostname" => '127.3.2.1',
389
439
  "status" => "running",
390
440
  "id" => 63066,
441
+ "amazon_id" => 'i-09fec72a',
442
+ "role" => "solo",
391
443
  },
392
444
  }, {
393
445
  "ssh_username" => "chicken",
@@ -395,6 +447,8 @@ private
395
447
  "public_hostname" => '127.44.55.66',
396
448
  "status" => "running",
397
449
  "id" => 59395,
450
+ "amazon_id" => 'i-1aa1e271',
451
+ "role" => "solo",
398
452
  }],
399
453
  "name" => "railsapp_staging_2",
400
454
  "apps" => [{
@@ -407,6 +461,8 @@ private
407
461
  "public_hostname" => '127.44.55.66',
408
462
  "status" => "running",
409
463
  "id" => 59395,
464
+ "amazon_id" => 'i-1aa1e271',
465
+ "role" => "solo",
410
466
  },
411
467
  }]
412
468
  end
@@ -2,7 +2,7 @@ module Spec
2
2
  module Helpers
3
3
  module SharedIntegrationTestUtils
4
4
 
5
- def run_ey(command_options, ey_options)
5
+ def run_ey(command_options, ey_options={})
6
6
  if respond_to?(:extra_ey_options) # needed for ssh tests
7
7
  ey_options.merge!(extra_ey_options)
8
8
  end
@@ -30,10 +30,10 @@ shared_examples_for "it takes an environment name" do
30
30
  api_scenario "one app, one environment"
31
31
  run_ey({:env => nil}, {:debug => true})
32
32
  verify_ran(make_scenario({
33
- :environment => 'giblets',
34
- :application => 'rails232app',
35
- :master_ip => '174.129.198.124',
36
- :ssh_username => 'turkey',
33
+ :environment => 'giblets',
34
+ :application => 'rails232app',
35
+ :master_hostname => 'ec2-174-129-198-124.compute-1.amazonaws.com',
36
+ :ssh_username => 'turkey',
37
37
  }))
38
38
  end
39
39
 
@@ -57,10 +57,10 @@ shared_examples_for "it takes an environment name" do
57
57
  api_scenario "one app, many similarly-named environments"
58
58
  run_ey({:env => 'prod'}, {:debug => true})
59
59
  verify_ran(make_scenario({
60
- :environment => 'railsapp_production',
61
- :application => 'rails232app',
62
- :master_ip => '174.129.198.124',
63
- :ssh_username => 'turkey',
60
+ :environment => 'railsapp_production',
61
+ :application => 'rails232app',
62
+ :master_hostname => 'ec2-174-129-198-124.compute-1.amazonaws.com',
63
+ :ssh_username => 'turkey',
64
64
  }))
65
65
  end
66
66
  end
@@ -75,6 +75,26 @@ end
75
75
  shared_examples_for "it invokes eysd" do
76
76
  include Spec::Helpers::SharedIntegrationTestUtils
77
77
 
78
+ it "passes along instance information to eysd" do
79
+ api_scenario "one app, one environment"
80
+ run_ey({:env => 'giblets'})
81
+
82
+ instance_args = [
83
+ Regexp.quote("ec2-174-129-198-124.compute-1.amazonaws.com,app_master"),
84
+ Regexp.quote("ec2-174-129-142-53.compute-1.amazonaws.com,db_master"),
85
+ Regexp.quote("ec2-72-44-46-66.compute-1.amazonaws.com,app"),
86
+ Regexp.quote("ec2-184-73-116-228.compute-1.amazonaws.com,util,fluffy"),
87
+ ]
88
+
89
+ # they should all be mentioned
90
+ instance_args.each do |i|
91
+ @ssh_commands.last.should =~ /#{i}/
92
+ end
93
+
94
+ # after the option '--instances'
95
+ @ssh_commands.last.should match(/--instances (#{instance_args.join('|')})/)
96
+ end
97
+
78
98
  context "eysd install" do
79
99
  before(:all) do
80
100
  api_scenario "one app, one environment"
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 0
9
- version: 0.5.0
8
+ - 2
9
+ version: 0.5.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - EY Cloud Team
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-06-16 00:00:00 -07:00
17
+ date: 2010-06-17 00:00:00 -07:00
18
18
  default_executable: ey
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency