engineyard 0.2.9 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/lib/engineyard.rb +1 -17
  2. data/lib/engineyard/account.rb +13 -49
  3. data/lib/engineyard/account/app.rb +18 -0
  4. data/lib/engineyard/account/app_master.rb +12 -0
  5. data/lib/engineyard/account/environment.rb +31 -0
  6. data/lib/engineyard/account/log.rb +18 -0
  7. data/lib/engineyard/api.rb +4 -2
  8. data/lib/engineyard/cli.rb +34 -11
  9. data/lib/engineyard/cli/ui.rb +1 -1
  10. data/spec/engineyard/api_spec.rb +6 -6
  11. data/spec/engineyard/cli/api_spec.rb +1 -1
  12. data/spec/engineyard/config_spec.rb +9 -9
  13. data/spec/ey/deploy_spec.rb +40 -21
  14. data/spec/ey/logs_spec.rb +28 -0
  15. data/spec/spec_helper.rb +12 -13
  16. data/spec/support/fake_awsm.ru +251 -0
  17. data/spec/support/helpers.rb +50 -38
  18. data/spec/support/ruby_ext.rb +29 -0
  19. metadata +52 -102
  20. data/lib/vendor/thor.rb +0 -244
  21. data/lib/vendor/thor/actions.rb +0 -275
  22. data/lib/vendor/thor/actions/create_file.rb +0 -103
  23. data/lib/vendor/thor/actions/directory.rb +0 -91
  24. data/lib/vendor/thor/actions/empty_directory.rb +0 -134
  25. data/lib/vendor/thor/actions/file_manipulation.rb +0 -223
  26. data/lib/vendor/thor/actions/inject_into_file.rb +0 -104
  27. data/lib/vendor/thor/base.rb +0 -540
  28. data/lib/vendor/thor/core_ext/file_binary_read.rb +0 -9
  29. data/lib/vendor/thor/core_ext/hash_with_indifferent_access.rb +0 -75
  30. data/lib/vendor/thor/core_ext/ordered_hash.rb +0 -100
  31. data/lib/vendor/thor/error.rb +0 -30
  32. data/lib/vendor/thor/group.rb +0 -271
  33. data/lib/vendor/thor/invocation.rb +0 -180
  34. data/lib/vendor/thor/parser.rb +0 -4
  35. data/lib/vendor/thor/parser/argument.rb +0 -67
  36. data/lib/vendor/thor/parser/arguments.rb +0 -150
  37. data/lib/vendor/thor/parser/option.rb +0 -128
  38. data/lib/vendor/thor/parser/options.rb +0 -169
  39. data/lib/vendor/thor/rake_compat.rb +0 -66
  40. data/lib/vendor/thor/runner.rb +0 -314
  41. data/lib/vendor/thor/shell.rb +0 -83
  42. data/lib/vendor/thor/shell/basic.rb +0 -239
  43. data/lib/vendor/thor/shell/color.rb +0 -108
  44. data/lib/vendor/thor/task.rb +0 -102
  45. data/lib/vendor/thor/util.rb +0 -230
  46. data/lib/vendor/thor/version.rb +0 -3
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey logs" do
4
+ before(:all) do
5
+ ENV['CLOUD_URL'] = EY.fake_awsm
6
+ FakeWeb.allow_net_connect = true
7
+
8
+ FakeFS.deactivate!
9
+ ENV['EYRC'] = "/tmp/eyrc"
10
+ token = { ENV['CLOUD_URL'] => {
11
+ "api_token" => "f81a1706ddaeb148cfb6235ddecfc1cf"} }
12
+ File.open(ENV['EYRC'], "w"){|f| YAML.dump(token, f) }
13
+ end
14
+
15
+ after(:all) do
16
+ ENV['CLOUD_URL'] = nil
17
+ FakeFS.activate!
18
+ FakeWeb.allow_net_connect = false
19
+ end
20
+
21
+ it "runs when environment is known" do
22
+ api_scenario "one app, one environment"
23
+ ey "logs giblets"
24
+ @out.should match(/MAIN LOG OUTPUT/)
25
+ @out.should match(/CUSTOM LOG OUTPUT/)
26
+ @err.should be_empty
27
+ end
28
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
+ EY_ROOT = File.expand_path("../..", __FILE__)
1
2
  begin
2
- require File.expand_path('../../.bundle/environment', __FILE__)
3
+ require File.join(EY_ROOT, ".bundle/environment.rb")
3
4
  rescue LoadError
4
- require "rubygems"; require "bundler"; Bundler.setup
5
+ puts "Can't load bundler environment. You need to run `bundle lock`."
6
+ exit
5
7
  end
6
8
 
7
9
  # Bundled gems
@@ -9,15 +11,20 @@ require 'fakeweb'
9
11
  require 'fakefs/safe'
10
12
 
11
13
  # Engineyard gem
12
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.join(EY_ROOT, "lib"))
13
15
  require 'engineyard'
14
16
 
15
17
  # Spec stuff
16
18
  require 'spec/autorun'
17
- require 'support/helpers'
18
19
  require 'yaml'
20
+ support = Dir[File.join(EY_ROOT,'/spec/support/*.rb')]
21
+ support.each{|helper| require helper }
22
+
23
+ EY.start_fake_awsm
19
24
 
20
25
  Spec::Runner.configure do |config|
26
+ config.include Spec::Helpers
27
+
21
28
  config.before(:all) do
22
29
  FakeWeb.allow_net_connect = false
23
30
  FakeFS.activate!
@@ -26,15 +33,7 @@ Spec::Runner.configure do |config|
26
33
  end
27
34
 
28
35
  config.before(:each) do
29
- EY.config = nil
30
36
  FakeFS::FileSystem.clear
31
- end
32
-
33
- def load_config(file="ey.yml")
34
- YAML.load_file(File.expand_path(file))
35
- end
36
-
37
- def write_config(data, file = "ey.yml")
38
- File.open(file, "w"){|f| YAML.dump(data, f) }
37
+ EY.instance_eval{ @config = nil }
39
38
  end
40
39
  end
@@ -0,0 +1,251 @@
1
+ require 'rubygems'
2
+ require 'sinatra/base'
3
+ require 'json'
4
+
5
+ class FakeAwsm < Sinatra::Base
6
+
7
+ def initialize(*_)
8
+ super
9
+ # the class var is because the object passed to #run is #dup-ed on
10
+ # every request. It makes sense; you hardly ever want to keep
11
+ # state in your application object (accidentally or otherwise),
12
+ # but in this situation that's exactly what we want to do.
13
+ @@scenario = Scenario::Empty # have to start somewhere
14
+ end
15
+
16
+ before { content_type "application/json" }
17
+
18
+ get "/" do
19
+ content_type :html
20
+ "OMG"
21
+ end
22
+
23
+ put "/scenario" do
24
+ new_scenario = case params[:scenario]
25
+ when "empty"
26
+ Scenario::Empty
27
+ when "one app, one environment, not linked"
28
+ Scenario::UnlinkedApp
29
+ when "one app, one environment"
30
+ Scenario::LinkedApp
31
+ when "one app, two environments"
32
+ Scenario::OneAppTwoEnvs
33
+ end
34
+ if new_scenario
35
+ @@scenario = new_scenario
36
+ {"ok" => "true"}.to_json
37
+ else
38
+ status(400)
39
+ {"ok" => "false", "message" => "wtf is the #{params[:scenario]} scenario?"}.to_json
40
+ end
41
+ end
42
+
43
+ get "/api/v2/apps" do
44
+ {"apps" => @@scenario.apps}.to_json
45
+ end
46
+
47
+ get "/api/v2/environments" do
48
+ {"environments" => @@scenario.environments}.to_json
49
+ end
50
+
51
+ get "/api/v2/environments/:env_id/logs" do
52
+ {"logs" => @@scenario.logs(params[:env_id])}.to_json
53
+ end
54
+
55
+ post "/api/v2/authenticate" do
56
+ if valid_user?
57
+ {"api_token" => "deadbeef", "ok" => true}.to_json
58
+ else
59
+ status(401)
60
+ {"ok" => false}.to_json
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def valid_user?
67
+ params[:email] == "test@test.test" &&
68
+ params[:password] == "test"
69
+ end
70
+
71
+ module FindableGitRemote
72
+ # Since we have to find something in `git remote -v` that
73
+ # corresponds to an app in cloud.ey in order to do anything, we
74
+ # simulate this by faking out the API to have whatever git
75
+ # remote we'll find anyway.
76
+ def git_remote
77
+ remotes = []
78
+ `git remote -v`.each_line do |line|
79
+ parts = line.split(/\t/)
80
+ # the remote will look like
81
+ # "git@github.com:engineyard/engineyard.git (fetch)\n"
82
+ # so we need to chop it up a bit
83
+ remotes << parts[1].gsub(/\s.*$/, "") if parts[1]
84
+ end
85
+ remotes.first
86
+ end
87
+ end
88
+
89
+ module Scenario
90
+ class Empty
91
+ def self.apps
92
+ []
93
+ end
94
+
95
+ def self.environments
96
+ []
97
+ end
98
+ end
99
+
100
+ class UnlinkedApp
101
+ extend FindableGitRemote
102
+
103
+ def self.apps
104
+ [{
105
+ "name" => "rails232app",
106
+ "environments" => [],
107
+ "repository_uri" => git_remote}]
108
+ end
109
+
110
+ def self.environments
111
+ [{
112
+ "ssh_username" => "turkey",
113
+ "instances" => [{
114
+ "public_hostname" => "174.129.198.124",
115
+ "status" => "running",
116
+ "id" => 27220}],
117
+ "name" => "giblets",
118
+ "apps" => [],
119
+ "instances_count" => 1,
120
+ "stack_name" => "nginx_mongrel",
121
+ "id" => 200,
122
+ "app_master" => {
123
+ "public_hostname" => "174.129.198.124",
124
+ "status" => "running",
125
+ "id" => 27220}}]
126
+ end
127
+ end
128
+
129
+ class LinkedApp
130
+ extend FindableGitRemote
131
+
132
+ def self.apps
133
+ [{"name" => "rails232app",
134
+ "environments" => [{"ssh_username" => "turkey",
135
+ "instances" => [{"public_hostname" => "174.129.198.124",
136
+ "status" => "running",
137
+ "id" => 27220}],
138
+ "name" => "giblets",
139
+ "apps" => [{"name" => "rails232app",
140
+ "repository_uri" => git_remote}],
141
+ "instances_count" => 1,
142
+ "stack_name" => "nginx_mongrel",
143
+ "id" => 200,
144
+ "app_master" => {"public_hostname" => "174.129.198.124",
145
+ "status" => "running",
146
+ "id" => 27220}}],
147
+ "repository_uri" => git_remote}]
148
+ end
149
+
150
+ def self.environments
151
+ [{
152
+ "ssh_username" => "turkey",
153
+ "instances" => [{
154
+ "public_hostname" => "174.129.198.124",
155
+ "status" => "running",
156
+ "id" => 27220}],
157
+ "name" => "giblets",
158
+ "apps" => [{
159
+ "name" => "rails232app",
160
+ "repository_uri" => git_remote}],
161
+ "instances_count" => 1,
162
+ "stack_name" => "nginx_mongrel",
163
+ "id" => 200,
164
+ "app_master" => {
165
+ "public_hostname" => "174.129.198.124",
166
+ "status" => "running",
167
+ "id" => 27220}}]
168
+ end
169
+
170
+ def self.logs(env_id)
171
+ [{
172
+ "id" => env_id,
173
+ "role" => "app_master",
174
+ "main" => "MAIN LOG OUTPUT",
175
+ "custom" => "CUSTOM LOG OUTPUT"
176
+ }]
177
+ end
178
+ end
179
+
180
+ class OneAppTwoEnvs
181
+ extend FindableGitRemote
182
+
183
+ def self.apps
184
+ apps = [{
185
+ "name" => "rails232app",
186
+ "repository_uri" => git_remote
187
+ }]
188
+
189
+ [{"name" => "rails232app",
190
+ "environments" => [{
191
+ "ssh_username" => "turkey",
192
+ "instances" => [{"public_hostname" => "174.129.198.124",
193
+ "status" => "running",
194
+ "id" => 27220}],
195
+ "name" => "giblets",
196
+ "apps" => apps,
197
+ "instances_count" => 1,
198
+ "stack_name" => "nginx_mongrel",
199
+ "id" => 200,
200
+ "app_master" => {"public_hostname" => "174.129.198.124",
201
+ "status" => "running",
202
+ "id" => 27220}
203
+ }, {
204
+ "ssh_username" => "ham",
205
+ "instances" => [],
206
+ "name" => "bakon",
207
+ "apps" => apps,
208
+ "instances_count" => 0,
209
+ "stack_name" => "nginx_passenger",
210
+ "id" => 8371,
211
+ "app_master" => nil,
212
+ }],
213
+ "repository_uri" => git_remote}]
214
+ end
215
+
216
+ def self.environments
217
+ [{
218
+ "ssh_username" => "turkey",
219
+ "instances" => [{
220
+ "public_hostname" => "174.129.198.124",
221
+ "status" => "running",
222
+ "id" => 27220}],
223
+ "name" => "giblets",
224
+ "apps" => [{
225
+ "name" => "rails232app",
226
+ "repository_uri" => git_remote}],
227
+ "instances_count" => 1,
228
+ "stack_name" => "nginx_mongrel",
229
+ "id" => 200,
230
+ "app_master" => {
231
+ "public_hostname" => "174.129.198.124",
232
+ "status" => "running",
233
+ "id" => 27220}
234
+ }, {
235
+ "ssh_username" => "ham",
236
+ "instances" => [],
237
+ "name" => "bakon",
238
+ "apps" => [{
239
+ "name" => "rails232app",
240
+ "repository_uri" => git_remote}],
241
+ "instances_count" => 0,
242
+ "stack_name" => "nginx_passenger",
243
+ "id" => 8371,
244
+ "app_master" => nil,
245
+ }]
246
+ end
247
+ end
248
+ end
249
+ end
250
+
251
+ run FakeAwsm.new
@@ -1,46 +1,58 @@
1
- module Kernel
2
- def capture_stdio(input = nil, &block)
3
- require 'stringio'
4
- org_stdin, $stdin = $stdin, StringIO.new(input) if input
5
- org_stdout, $stdout = $stdout, StringIO.new
6
- yield
7
- return @out = $stdout.string
8
- ensure
9
- $stdout = org_stdout
10
- $stdin = org_stdin
11
- end
12
- alias capture_stdout capture_stdio
13
- end
1
+ require 'ey_merkin'
2
+ require "rest_client"
3
+
4
+ module Spec
5
+ module Helpers
6
+ def ey(cmd = nil, options = {})
7
+ require "open3"
8
+ hide_err = options.delete(:hide_err)
9
+ ENV['DEBUG'] = options.delete(:debug)
10
+
11
+ args = options.map { |k,v| "--#{k} #{v}"}.join(" ")
12
+ eybin = File.expand_path('../bundled_ey', __FILE__)
13
+
14
+ @in, @out, @err = Open3.popen3("#{eybin} #{cmd} #{args}")
15
+
16
+ yield @in if block_given?
17
+ @err = @err.read_available_bytes
18
+ @out = @out.read_available_bytes
19
+ @ssh_commands = @out.split(/\n/).find_all do |line|
20
+ line =~ /^ssh/
21
+ end.map do |line|
22
+ line.sub(/^.*?\"/, '').sub(/\"$/, '')
23
+ end
24
+
25
+ puts @err unless @err.empty? || hide_err
26
+ @out
27
+ end
14
28
 
15
- class IO
16
- def read_available_bytes(chunk_size = 1024, select_timeout = 5)
17
- buffer = []
29
+ def api_scenario(scenario)
30
+ response = ::RestClient.put(EY.fake_awsm + '/scenario', {"scenario" => scenario}, {})
31
+ raise "Setting scenario failed: #{response.inspect}" unless response.code == 200
32
+ end
18
33
 
19
- while self.class.select([self], nil, nil, select_timeout)
20
- begin
21
- buffer << self.readpartial(chunk_size)
22
- rescue(EOFError)
23
- break
24
- end
34
+ def read_yaml(file="ey.yml")
35
+ YAML.load_file(File.expand_path(file))
25
36
  end
26
37
 
27
- return buffer.join
38
+ def write_yaml(data, file = "ey.yml")
39
+ File.open(file, "w"){|f| YAML.dump(data, f) }
40
+ end
28
41
  end
29
42
  end
30
43
 
31
- def ey(cmd = nil, options = {})
32
- require "open3"
33
- hide_err = options.delete(:hide_err)
34
-
35
- args = options.map { |k,v| "--#{k} #{v}"}.join(" ")
36
- eybin = File.expand_path('../bundled_ey', __FILE__)
37
-
38
- @in, @out, @err = Open3.popen3("#{eybin} #{cmd} #{args}")
39
-
40
- yield @in if block_given?
41
- @err = @err.read_available_bytes
42
- @out = @out.read_available_bytes
43
-
44
- puts @err unless @err.empty? || hide_err
45
- @out
44
+ module EY
45
+ class << self
46
+ def fake_awsm
47
+ @fake_awsm ||= begin
48
+ unless system("ruby -c spec/support/fake_awsm.ru > /dev/null")
49
+ raise SyntaxError, "There is a syntax error in fake_awsm.ru! fix it!"
50
+ end
51
+ config_ru = File.join(EY_ROOT, "spec/support/fake_awsm.ru")
52
+ @server = EY::Merkin.start_server(config_ru)
53
+ "http://localhost:#{@server.port}"
54
+ end
55
+ end
56
+ alias_method :start_fake_awsm, :fake_awsm
57
+ end
46
58
  end
@@ -0,0 +1,29 @@
1
+ module Kernel
2
+ def capture_stdio(input = nil, &block)
3
+ require 'stringio'
4
+ org_stdin, $stdin = $stdin, StringIO.new(input) if input
5
+ org_stdout, $stdout = $stdout, StringIO.new
6
+ yield
7
+ return @out = $stdout.string
8
+ ensure
9
+ $stdout = org_stdout
10
+ $stdin = org_stdin
11
+ end
12
+ alias capture_stdout capture_stdio
13
+ end
14
+
15
+ class IO
16
+ def read_available_bytes(chunk_size = 1024, select_timeout = 5)
17
+ buffer = []
18
+
19
+ while self.class.select([self], nil, nil, select_timeout)
20
+ begin
21
+ buffer << self.readpartial(chunk_size)
22
+ rescue(EOFError)
23
+ break
24
+ end
25
+ end
26
+
27
+ return buffer.join
28
+ end
29
+ end