engineyard 1.4.29 → 1.7.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +139 -4
- data/bin/ey +1 -7
- data/lib/engineyard.rb +1 -22
- data/lib/engineyard/cli.rb +192 -94
- data/lib/engineyard/cli/#recipes.rb# +32 -0
- data/lib/engineyard/cli/api.rb +42 -28
- data/lib/engineyard/cli/recipes.rb +13 -6
- data/lib/engineyard/cli/ui.rb +103 -42
- data/lib/engineyard/cli/web.rb +16 -10
- data/lib/engineyard/config.rb +92 -18
- data/lib/engineyard/deploy_config.rb +66 -0
- data/lib/engineyard/deploy_config/migrate.rb +125 -0
- data/lib/engineyard/deploy_config/ref.rb +56 -0
- data/lib/engineyard/error.rb +38 -78
- data/lib/engineyard/repo.rb +75 -27
- data/lib/engineyard/serverside_runner.rb +133 -0
- data/lib/engineyard/thor.rb +110 -18
- data/lib/engineyard/version.rb +1 -1
- data/spec/engineyard/cli/api_spec.rb +10 -16
- data/spec/engineyard/cli_spec.rb +0 -11
- data/spec/engineyard/config_spec.rb +1 -8
- data/spec/engineyard/deploy_config_spec.rb +203 -0
- data/spec/engineyard/eyrc_spec.rb +2 -0
- data/spec/engineyard/repo_spec.rb +57 -34
- data/spec/ey/deploy_spec.rb +102 -52
- data/spec/ey/list_environments_spec.rb +69 -14
- data/spec/ey/login_spec.rb +11 -7
- data/spec/ey/logout_spec.rb +4 -4
- data/spec/ey/logs_spec.rb +6 -6
- data/spec/ey/recipes/apply_spec.rb +1 -1
- data/spec/ey/recipes/download_spec.rb +1 -1
- data/spec/ey/recipes/upload_spec.rb +6 -6
- data/spec/ey/rollback_spec.rb +3 -3
- data/spec/ey/ssh_spec.rb +9 -9
- data/spec/ey/status_spec.rb +2 -2
- data/spec/ey/whoami_spec.rb +9 -8
- data/spec/spec_helper.rb +18 -15
- data/spec/support/{fake_awsm.rb → git_repos.rb} +0 -14
- data/spec/support/helpers.rb +84 -28
- data/spec/support/matchers.rb +0 -16
- data/spec/support/shared_behavior.rb +83 -103
- metadata +65 -51
- data/lib/engineyard/api.rb +0 -117
- data/lib/engineyard/collection.rb +0 -7
- data/lib/engineyard/collection/abstract.rb +0 -71
- data/lib/engineyard/collection/apps.rb +0 -8
- data/lib/engineyard/collection/environments.rb +0 -8
- data/lib/engineyard/model.rb +0 -12
- data/lib/engineyard/model/account.rb +0 -8
- data/lib/engineyard/model/api_struct.rb +0 -33
- data/lib/engineyard/model/app.rb +0 -32
- data/lib/engineyard/model/deployment.rb +0 -90
- data/lib/engineyard/model/environment.rb +0 -194
- data/lib/engineyard/model/instance.rb +0 -166
- data/lib/engineyard/model/log.rb +0 -9
- data/lib/engineyard/model/user.rb +0 -6
- data/lib/engineyard/resolver.rb +0 -134
- data/lib/engineyard/rest_client_ext.rb +0 -9
- data/lib/engineyard/ruby_ext.rb +0 -9
- data/spec/engineyard/api_spec.rb +0 -39
- data/spec/engineyard/collection/apps_spec.rb +0 -16
- data/spec/engineyard/collection/environments_spec.rb +0 -16
- data/spec/engineyard/model/api_struct_spec.rb +0 -41
- data/spec/engineyard/model/environment_spec.rb +0 -198
- data/spec/engineyard/model/instance_spec.rb +0 -27
- data/spec/engineyard/resolver_spec.rb +0 -112
- data/spec/support/fake_awsm.ru +0 -245
- data/spec/support/scenarios.rb +0 -417
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe "EY::Model::Instance#has_app_code?" do
|
4
|
-
it "is true for solos" do
|
5
|
-
EY::Model::Instance.from_hash("role" => "solo").should have_app_code
|
6
|
-
end
|
7
|
-
|
8
|
-
it "is true for app masters" do
|
9
|
-
EY::Model::Instance.from_hash("role" => "app_master").should have_app_code
|
10
|
-
end
|
11
|
-
|
12
|
-
it "is true for app slaves" do
|
13
|
-
EY::Model::Instance.from_hash("role" => "app").should have_app_code
|
14
|
-
end
|
15
|
-
|
16
|
-
it "is true for utilities" do
|
17
|
-
EY::Model::Instance.from_hash("role" => "util").should have_app_code
|
18
|
-
end
|
19
|
-
|
20
|
-
it "is false for DB masters" do
|
21
|
-
EY::Model::Instance.from_hash("role" => "db_master").should_not have_app_code
|
22
|
-
end
|
23
|
-
|
24
|
-
it "is false for DB slaves" do
|
25
|
-
EY::Model::Instance.from_hash("role" => "db_slave").should_not have_app_code
|
26
|
-
end
|
27
|
-
end
|
@@ -1,112 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe EY::Resolver do
|
4
|
-
def mock_api
|
5
|
-
return @mock_api if @mock_api
|
6
|
-
apps = Object.new
|
7
|
-
def apps.named(name, *args)
|
8
|
-
result = EY::Model::App.from_hash(:name => name)
|
9
|
-
result.stub!(:environments => [])
|
10
|
-
result
|
11
|
-
end
|
12
|
-
environments = Object.new
|
13
|
-
def environments.named(name, *args)
|
14
|
-
result = EY::Model::Environment.from_hash(:name => name)
|
15
|
-
result.stub!(:apps => [])
|
16
|
-
result
|
17
|
-
end
|
18
|
-
@mock_api = mock("api", :apps => apps, :environments => environments)
|
19
|
-
end
|
20
|
-
|
21
|
-
def resolver
|
22
|
-
@resolver ||= EY::Resolver.new(mock_api).tap do |r|
|
23
|
-
r.instance_variable_set("@app_deployments", [])
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def new_app_deployment(options)
|
28
|
-
resolver.instance_variable_get("@app_deployments") << options
|
29
|
-
options
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
before do
|
34
|
-
@production = new_app_deployment(:environment_name => "app_production", :app_name => "app", :account_name => "ey", :repository_uri => "git://github.com/repo/app.git")
|
35
|
-
@staging = new_app_deployment(:environment_name => "app_staging" , :app_name => "app", :account_name => "ey", :repository_uri => "git://github.com/repo/app.git")
|
36
|
-
@big = new_app_deployment(:environment_name => "bigapp_staging", :app_name => "bigapp", :account_name => "ey", :repository_uri => "git://github.com/repo/bigapp.git")
|
37
|
-
@ey_dup = new_app_deployment(:environment_name => "app_duplicate" , :app_name => "app_duplicate", :account_name => "ey", :repository_uri => "git://github.com/repo/dup.git")
|
38
|
-
@sumo = new_app_deployment(:environment_name => "sumo_wrestler" , :app_name => "app_duplicate", :account_name => "ey", :repository_uri => "git://github.com/repo/dup.git")
|
39
|
-
@me_dup = new_app_deployment(:environment_name => "app_duplicate" , :app_name => "app_duplicate", :account_name => "me", :repository_uri => "git://github.com/repo/dup.git")
|
40
|
-
end
|
41
|
-
|
42
|
-
def repo(url)
|
43
|
-
r = mock("repo", :has_remote? => false)
|
44
|
-
r.stub!(:has_remote?).with(url).and_return(true)
|
45
|
-
r
|
46
|
-
end
|
47
|
-
|
48
|
-
describe "#fetch" do
|
49
|
-
it "raises argument error if the conditions are empty" do
|
50
|
-
lambda { resolver.app_and_environment({}) }.should raise_error(ArgumentError)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "raises when there is no app match" do
|
54
|
-
lambda { resolver.app_and_environment(:environment_name => 'app_duplicate', :app_name => 'smallapp') }.should raise_error(EY::InvalidAppError)
|
55
|
-
end
|
56
|
-
|
57
|
-
it "raises when there is no environment match" do
|
58
|
-
lambda { resolver.app_and_environment(:environment_name => 'gibberish', :app_name => 'app') }.should raise_error(EY::NoEnvironmentError)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "raises when there are no matches" do
|
62
|
-
lambda { resolver.app_and_environment(:environment_name => 'app_duplicate', :app_name => 'bigapp') }.should raise_error(EY::NoMatchesError)
|
63
|
-
lambda { resolver.app_and_environment(:repo => repo("git://github.com/repo/app.git"), :environment_name => 'app_duplicate') }.should raise_error(EY::NoMatchesError)
|
64
|
-
end
|
65
|
-
|
66
|
-
it "raises when there is more than one match" do
|
67
|
-
lambda { resolver.app_and_environment(:app_name => "app") }.should raise_error(EY::MultipleMatchesError)
|
68
|
-
lambda { resolver.app_and_environment(:account_name => "ey", :app_name => "app") }.should raise_error(EY::MultipleMatchesError)
|
69
|
-
lambda { resolver.app_and_environment(:repo => repo("git://github.com/repo/dup.git")) }.should raise_error(EY::MultipleMatchesError)
|
70
|
-
lambda { resolver.app_and_environment(:repo => repo("git://github.com/repo/app.git")) }.should raise_error(EY::MultipleMatchesError)
|
71
|
-
end
|
72
|
-
|
73
|
-
it "does not include duplicate copies of apps across accounts when raising a more than one match error" do
|
74
|
-
do_include = "--environment='sumo_wrestler' --app='app_duplicate' --account='ey'"
|
75
|
-
do_not_include = "--environment='sumo_wrestler' --app='app_duplicate' --account='me'"
|
76
|
-
lambda do
|
77
|
-
resolver.app_and_environment(:repo => repo("git://github.com/repo/dup.git"))
|
78
|
-
end.should raise_error(EY::MultipleMatchesError) {|e|
|
79
|
-
e.message.should include(do_include)
|
80
|
-
e.message.should_not include(do_not_include)
|
81
|
-
}
|
82
|
-
end
|
83
|
-
|
84
|
-
it "returns one deployment whene there is only one match" do
|
85
|
-
resolver.app_and_environment(:account_name => "ey", :app_name => "big").should resolve_to(@big)
|
86
|
-
resolver.app_and_environment(:environment_name => "production").should resolve_to(@production)
|
87
|
-
resolver.app_and_environment(:repo => repo("git://github.com/repo/bigapp.git")).should resolve_to(@big)
|
88
|
-
resolver.app_and_environment(:repo => repo("git://github.com/repo/app.git"), :environment_name => "staging").should resolve_to(@staging)
|
89
|
-
end
|
90
|
-
|
91
|
-
it "doesn't care about case" do
|
92
|
-
resolver.app_and_environment(:account_name => "EY", :app_name => "big").should resolve_to(@big)
|
93
|
-
resolver.app_and_environment(:account_name => "ey", :app_name => "BiG").should resolve_to(@big)
|
94
|
-
end
|
95
|
-
|
96
|
-
it "returns the match when an app is specified even when there is a repo" do
|
97
|
-
resolver.app_and_environment(:account_name => "ey", :app_name => "bigapp", :repo => repo("git://github.com/repo/app.git")).should resolve_to(@big)
|
98
|
-
end
|
99
|
-
|
100
|
-
it "returns the specific match even if there is a partial match" do
|
101
|
-
resolver.app_and_environment(:environment_name => 'app_staging', :app_name => 'app').should resolve_to(@staging)
|
102
|
-
resolver.app_and_environment(:environment_name => "app_staging").should resolve_to(@staging)
|
103
|
-
resolver.app_and_environment(:app_name => "app", :environment_name => "staging").should resolve_to(@staging)
|
104
|
-
end
|
105
|
-
|
106
|
-
it "scopes searches under the correct account" do
|
107
|
-
resolver.app_and_environment(:account_name => "ey", :environment_name => "dup", :app_name => "dup").should resolve_to(@ey_dup)
|
108
|
-
resolver.app_and_environment(:account_name => "me", :environment_name => "dup").should resolve_to(@me_dup)
|
109
|
-
resolver.app_and_environment(:account_name => "me", :app_name => "dup").should resolve_to(@me_dup)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
data/spec/support/fake_awsm.ru
DELETED
@@ -1,245 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'sinatra/base'
|
3
|
-
require 'json'
|
4
|
-
require File.expand_path('../scenarios', __FILE__)
|
5
|
-
|
6
|
-
class FakeAwsm < Sinatra::Base
|
7
|
-
SCENARIOS = {
|
8
|
-
"empty" => Scenario::Base,
|
9
|
-
"one app, one environment, not linked" => Scenario::UnlinkedApp,
|
10
|
-
"two apps" => Scenario::TwoApps,
|
11
|
-
"one app, one environment" => Scenario::LinkedApp,
|
12
|
-
"two accounts, two apps, two environments, ambiguous" => Scenario::MultipleAmbiguousAccounts,
|
13
|
-
"one app, one environment, no instances" => Scenario::LinkedAppNotRunning,
|
14
|
-
"one app, one environment, app master red" => Scenario::LinkedAppRedMaster,
|
15
|
-
"one app, many environments" => Scenario::OneAppManyEnvs,
|
16
|
-
"one app, many similarly-named environments" => Scenario::OneAppManySimilarlyNamedEnvs,
|
17
|
-
"two apps, same git uri" => Scenario::TwoAppsSameGitUri,
|
18
|
-
}
|
19
|
-
|
20
|
-
def initialize(*_)
|
21
|
-
super
|
22
|
-
# the class var is because the object passed to #run is #dup-ed on
|
23
|
-
# every request. It makes sense; you hardly ever want to keep
|
24
|
-
# state in your application object (accidentally or otherwise),
|
25
|
-
# but in this situation that's exactly what we want to do.
|
26
|
-
@@cloud_mock = CloudMock.new(Scenario::Base.new('git://example.com'))
|
27
|
-
end
|
28
|
-
|
29
|
-
before { content_type "application/json" }
|
30
|
-
|
31
|
-
get "/" do
|
32
|
-
content_type :html
|
33
|
-
"OMG"
|
34
|
-
end
|
35
|
-
|
36
|
-
put "/scenario" do
|
37
|
-
new_scenario = SCENARIOS[params[:scenario]]
|
38
|
-
unless new_scenario
|
39
|
-
status(400)
|
40
|
-
return {"ok" => "false", "message" => "wtf is the #{params[:scenario]} scenario?"}.to_json
|
41
|
-
end
|
42
|
-
@@cloud_mock = CloudMock.new(new_scenario.new(params[:remote]))
|
43
|
-
{"ok" => "true"}.to_json
|
44
|
-
end
|
45
|
-
|
46
|
-
get "/api/v2/current_user" do
|
47
|
-
{ "user" => { "id" => 1, "name" => "User Name", "email" => "test@test.test" } }.to_json
|
48
|
-
end
|
49
|
-
|
50
|
-
get "/api/v2/apps" do
|
51
|
-
raise('No user agent header') unless env['HTTP_USER_AGENT'] =~ %r#^EngineYardCLI/#
|
52
|
-
{"apps" => @@cloud_mock.apps}.to_json
|
53
|
-
end
|
54
|
-
|
55
|
-
get "/api/v2/environments" do
|
56
|
-
{"environments" => @@cloud_mock.environments}.to_json
|
57
|
-
end
|
58
|
-
|
59
|
-
get "/api/v2/environments/:env_id/logs" do
|
60
|
-
{"logs" => @@cloud_mock.logs(params[:env_id].to_i)}.to_json
|
61
|
-
end
|
62
|
-
|
63
|
-
get "/api/v2/environments/:env_id/recipes" do
|
64
|
-
redirect '/fakes3/recipe'
|
65
|
-
end
|
66
|
-
|
67
|
-
get "/fakes3/recipe" do
|
68
|
-
content_type "binary/octet-stream"
|
69
|
-
status(200)
|
70
|
-
|
71
|
-
tempdir = File.join(Dir.tmpdir, "ey_test_cmds_#{Time.now.tv_sec}#{Time.now.tv_usec}_#{$$}")
|
72
|
-
Dir.mkdir(tempdir)
|
73
|
-
Dir.mkdir("#{tempdir}/cookbooks")
|
74
|
-
File.open("#{tempdir}/cookbooks/README", 'w') do |f|
|
75
|
-
f.write "Remove this file to clone an upstream git repository of cookbooks\n"
|
76
|
-
end
|
77
|
-
|
78
|
-
Dir.chdir(tempdir) { `tar czf - cookbooks` }
|
79
|
-
end
|
80
|
-
|
81
|
-
post "/api/v2/environments/:env_id/recipes" do
|
82
|
-
if params[:file][:tempfile]
|
83
|
-
files = `tar --list -z -f "#{params[:file][:tempfile].path}"`.split(/\n/)
|
84
|
-
if files.empty?
|
85
|
-
status(400)
|
86
|
-
"No files in uploaded tarball"
|
87
|
-
else
|
88
|
-
status(204)
|
89
|
-
""
|
90
|
-
end
|
91
|
-
else
|
92
|
-
status(400)
|
93
|
-
"Recipe file not uploaded"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
put "/api/v2/environments/:env_id/update_instances" do
|
98
|
-
status(202)
|
99
|
-
""
|
100
|
-
end
|
101
|
-
|
102
|
-
put "/api/v2/environments/:env_id/run_custom_recipes" do
|
103
|
-
status(202)
|
104
|
-
""
|
105
|
-
end
|
106
|
-
|
107
|
-
get "/api/v2/apps/:app_id/environments/:environment_id/deployments/last" do
|
108
|
-
{
|
109
|
-
"deployment" => {
|
110
|
-
"id" => 3,
|
111
|
-
"ref" => "HEAD",
|
112
|
-
"resolved_ref" => "HEAD",
|
113
|
-
"commit" => 'a'*40,
|
114
|
-
"user_name" => "User Name",
|
115
|
-
"migrate_command" => "rake db:migrate --trace",
|
116
|
-
"created_at" => Time.now.utc - 3600,
|
117
|
-
"finished_at" => Time.now.utc - 3400,
|
118
|
-
"successful" => true,
|
119
|
-
}
|
120
|
-
}.to_json
|
121
|
-
end
|
122
|
-
|
123
|
-
post "/api/v2/apps/:app_id/environments/:environment_id/deployments" do
|
124
|
-
{"deployment" => params[:deployment].merge({"id" => 2, "commit" => 'a'*40, "resolved_ref" => "resolved-#{params[:deployment][:ref]}"})}.to_json
|
125
|
-
end
|
126
|
-
|
127
|
-
put "/api/v2/apps/:app_id/environments/:environment_id/deployments/:deployment_id/finished" do
|
128
|
-
{"deployment" => params[:deployment].merge({"id" => 2, "finished_at" => Time.now})}.to_json
|
129
|
-
end
|
130
|
-
|
131
|
-
post "/api/v2/authenticate" do
|
132
|
-
if valid_user?
|
133
|
-
{"api_token" => "deadbeef", "ok" => true}.to_json
|
134
|
-
else
|
135
|
-
status(401)
|
136
|
-
{"ok" => false}.to_json
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
private
|
141
|
-
|
142
|
-
def valid_user?
|
143
|
-
params[:email] == "test@test.test" &&
|
144
|
-
params[:password] == "test"
|
145
|
-
end
|
146
|
-
|
147
|
-
class CloudMock
|
148
|
-
def initialize(initial_conditions)
|
149
|
-
@accounts, @apps, @envs, @keys, @app_joins, @key_joins = [], [], [], [], [], []
|
150
|
-
@next_id = 1
|
151
|
-
|
152
|
-
initial_conditions.starting_accounts.each {|a| add_account(a) }
|
153
|
-
initial_conditions.starting_apps.each {|a| add_app(a) }
|
154
|
-
initial_conditions.starting_environments.each {|e| add_environment(e) }
|
155
|
-
initial_conditions.starting_app_joins.each {|(app_id, env_id)| link_app(app_id, env_id) }
|
156
|
-
end
|
157
|
-
|
158
|
-
def add_account(acc)
|
159
|
-
acc["id"] ||= next_id
|
160
|
-
@accounts << acc
|
161
|
-
acc
|
162
|
-
end
|
163
|
-
|
164
|
-
def add_app(app)
|
165
|
-
app["id"] ||= next_id
|
166
|
-
app["account"] ||= @accounts.first
|
167
|
-
@apps << app
|
168
|
-
app
|
169
|
-
end
|
170
|
-
|
171
|
-
def add_environment(env)
|
172
|
-
env["id"] ||= next_id
|
173
|
-
env["account"] ||= @accounts.first
|
174
|
-
|
175
|
-
unless env.has_key?("app_master")
|
176
|
-
master = env["instances"].find{ |i| %w[solo app_master].include?(i["role"]) }
|
177
|
-
env.merge!("app_master" => master)
|
178
|
-
end
|
179
|
-
|
180
|
-
@envs << env
|
181
|
-
env
|
182
|
-
end
|
183
|
-
|
184
|
-
def link_app(app_id, env_id)
|
185
|
-
app = @apps.find {|a| a["id"] == app_id } or raise "No such app id:#{app_id}"
|
186
|
-
env = @envs.find {|e| e["id"] == env_id } or raise "No such environment id:#{env_id}"
|
187
|
-
if app["account"]["id"] != env["account"]["id"]
|
188
|
-
raise "App #{app_id} in account #{app["account"]["id"]} cannot be attached to environment #{env_id} in account #{env["account"]["id"]}"
|
189
|
-
end
|
190
|
-
@app_joins << [app_id, env_id]
|
191
|
-
@app_joins.uniq!
|
192
|
-
end
|
193
|
-
|
194
|
-
def apps
|
195
|
-
@apps.dup.map do |app|
|
196
|
-
app.merge("environments" => joined_envs(app))
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
def logs(env_id)
|
201
|
-
[{
|
202
|
-
"id" => env_id,
|
203
|
-
"role" => "app_master",
|
204
|
-
"main" => "MAIN LOG OUTPUT",
|
205
|
-
"custom" => "CUSTOM LOG OUTPUT"
|
206
|
-
}]
|
207
|
-
end
|
208
|
-
|
209
|
-
def environments
|
210
|
-
@envs.dup.map do |env|
|
211
|
-
env.merge("apps" => joined_apps(env))
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
private
|
216
|
-
|
217
|
-
def next_id
|
218
|
-
id = @next_id
|
219
|
-
@next_id += 1
|
220
|
-
id
|
221
|
-
end
|
222
|
-
|
223
|
-
def joined_envs(app)
|
224
|
-
related_objects(app, @envs, @app_joins)
|
225
|
-
end
|
226
|
-
|
227
|
-
def joined_apps(env)
|
228
|
-
related_objects(env, @apps, @app_joins.map {|j| j.reverse})
|
229
|
-
end
|
230
|
-
|
231
|
-
def related_objects(obj, candidates, relation)
|
232
|
-
candidate_table = candidates.inject({}) do |table, candidate|
|
233
|
-
table.merge(candidate["id"] => candidate)
|
234
|
-
end
|
235
|
-
|
236
|
-
relation.find_all do |(obj_id, candidate_id)|
|
237
|
-
obj["id"] == obj_id
|
238
|
-
end.map do |(obj_id, candidate_id)|
|
239
|
-
candidate_table[candidate_id]
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
run FakeAwsm.new
|
data/spec/support/scenarios.rb
DELETED
@@ -1,417 +0,0 @@
|
|
1
|
-
module Scenario
|
2
|
-
class Base
|
3
|
-
attr_accessor :git_remote
|
4
|
-
|
5
|
-
def initialize(git_remote)
|
6
|
-
self.git_remote = git_remote
|
7
|
-
end
|
8
|
-
|
9
|
-
def starting_accounts() [{"name" => "main"}] end
|
10
|
-
def starting_apps() [] end
|
11
|
-
def starting_environments() [] end
|
12
|
-
def starting_app_joins() [] end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
class LinkedApp < Base
|
17
|
-
def _instances
|
18
|
-
[{
|
19
|
-
"id" => 27220,
|
20
|
-
"role" => "app_master",
|
21
|
-
"name" => nil,
|
22
|
-
"status" => "running",
|
23
|
-
"amazon_id" => 'i-ddbbdd92',
|
24
|
-
"public_hostname" => "app_master_hostname.compute-1.amazonaws.com",
|
25
|
-
}, {
|
26
|
-
"id" => 22721,
|
27
|
-
"name" => nil,
|
28
|
-
"role" => "db_master",
|
29
|
-
"status" => "running",
|
30
|
-
"amazon_id" => "i-d4cdddbf",
|
31
|
-
"public_hostname" => "db_master_hostname.compute-1.amazonaws.com",
|
32
|
-
}, {
|
33
|
-
"id" => 22724,
|
34
|
-
"name" => nil,
|
35
|
-
"role" => "db_slave",
|
36
|
-
"status" => "running",
|
37
|
-
"amazon_id" => "i-asdfasdfaj",
|
38
|
-
"public_hostname" => "db_slave_1_hostname.compute-1.amazonaws.com",
|
39
|
-
}, {
|
40
|
-
"id" => 22725,
|
41
|
-
"name" => nil,
|
42
|
-
"role" => "db_slave",
|
43
|
-
"status" => "running",
|
44
|
-
"amazon_id" => "i-asdfasdfaj",
|
45
|
-
"public_hostname" => "db_slave_2_hostname.compute-1.amazonaws.com",
|
46
|
-
}, {
|
47
|
-
"id" => 22722,
|
48
|
-
"role" => "app",
|
49
|
-
"name" => nil,
|
50
|
-
"status" => "building",
|
51
|
-
"amazon_id" => "i-d2e3f1b9",
|
52
|
-
"public_hostname" => "app_hostname.compute-1.amazonaws.com",
|
53
|
-
}, {
|
54
|
-
"id" => 22723,
|
55
|
-
"role" => "util",
|
56
|
-
"name" => "fluffy",
|
57
|
-
"status" => "running",
|
58
|
-
"amazon_id" => "i-80e3f1eb",
|
59
|
-
"public_hostname" => "util_fluffy_hostname.compute-1.amazonaws.com",
|
60
|
-
}, {
|
61
|
-
"id" => 22727,
|
62
|
-
"role" => "util",
|
63
|
-
"name" => "rocky",
|
64
|
-
"status" => "running",
|
65
|
-
"amazon_id" => "i-80etf1eb",
|
66
|
-
"public_hostname" => "util_rocky_hostname.compute-1.amazonaws.com",
|
67
|
-
}]
|
68
|
-
end
|
69
|
-
private :_instances
|
70
|
-
|
71
|
-
def starting_apps
|
72
|
-
[{
|
73
|
-
"id" => 1001,
|
74
|
-
"name" => "rails232app",
|
75
|
-
"repository_uri" => git_remote}]
|
76
|
-
end
|
77
|
-
|
78
|
-
def starting_environments
|
79
|
-
[{
|
80
|
-
"id" => 200,
|
81
|
-
"ssh_username" => "turkey",
|
82
|
-
"instances" => _instances,
|
83
|
-
"name" => "giblets",
|
84
|
-
"instances_count" => 4,
|
85
|
-
"app_server_stack_name" => "nginx_mongrel",
|
86
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
87
|
-
"deployment_configurations" => {
|
88
|
-
"rails232app" => {
|
89
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
90
|
-
}
|
91
|
-
},
|
92
|
-
"framework_env" => "production"}]
|
93
|
-
end
|
94
|
-
|
95
|
-
def starting_app_joins
|
96
|
-
[[1001, 200]]
|
97
|
-
end
|
98
|
-
|
99
|
-
end # LinkedApp
|
100
|
-
|
101
|
-
class MultipleAmbiguousAccounts < LinkedApp
|
102
|
-
def starting_accounts
|
103
|
-
super + [{"name" => "account_2", "id" => 256}]
|
104
|
-
end
|
105
|
-
|
106
|
-
def starting_apps
|
107
|
-
apps = super
|
108
|
-
new_app = apps.first.dup
|
109
|
-
new_app["id"] += 1000
|
110
|
-
new_app["account"] = starting_accounts.last
|
111
|
-
apps + [new_app]
|
112
|
-
end
|
113
|
-
|
114
|
-
def starting_environments
|
115
|
-
envs = super
|
116
|
-
new_env = envs.first.dup
|
117
|
-
new_env["id"] += 1000
|
118
|
-
new_env["account"] = starting_accounts.last
|
119
|
-
envs + [new_env]
|
120
|
-
end
|
121
|
-
|
122
|
-
def starting_app_joins
|
123
|
-
joins = super
|
124
|
-
new_join = [joins.first[0] + 1000,
|
125
|
-
joins.first[1] + 1000]
|
126
|
-
joins + [new_join]
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
class UnlinkedApp < Base
|
131
|
-
def starting_apps
|
132
|
-
[{
|
133
|
-
"id" => 1001,
|
134
|
-
"name" => "rails232app",
|
135
|
-
"repository_uri" => git_remote}]
|
136
|
-
end
|
137
|
-
|
138
|
-
def starting_environments
|
139
|
-
[{
|
140
|
-
"ssh_username" => "turkey",
|
141
|
-
"instances" => [{
|
142
|
-
"status" => "running",
|
143
|
-
"id" => 27220,
|
144
|
-
"amazon_id" => 'i-ddbbdd92',
|
145
|
-
"role" => "solo",
|
146
|
-
"public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com"}],
|
147
|
-
"name" => "giblets",
|
148
|
-
"instances_count" => 1,
|
149
|
-
"id" => 200,
|
150
|
-
"app_server_stack_name" => "nginx_mongrel",
|
151
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
152
|
-
"framework_env" => "production"}]
|
153
|
-
end
|
154
|
-
end # UnlinkedApp
|
155
|
-
|
156
|
-
class LinkedAppNotRunning < Base
|
157
|
-
def starting_apps
|
158
|
-
[{
|
159
|
-
"id" => 1001,
|
160
|
-
"name" => "rails232app",
|
161
|
-
"repository_uri" => git_remote}]
|
162
|
-
end
|
163
|
-
|
164
|
-
def starting_environments
|
165
|
-
[{
|
166
|
-
"ssh_username" => "turkey",
|
167
|
-
"instances" => [],
|
168
|
-
"name" => "giblets",
|
169
|
-
"instances_count" => 0,
|
170
|
-
"id" => 200,
|
171
|
-
"app_server_stack_name" => "nginx_mongrel",
|
172
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
173
|
-
"deployment_configurations" => {
|
174
|
-
"rails232app" => {
|
175
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
176
|
-
}
|
177
|
-
},
|
178
|
-
"framework_env" => "production"}]
|
179
|
-
end
|
180
|
-
|
181
|
-
def starting_app_joins
|
182
|
-
[[1001, 200]]
|
183
|
-
end
|
184
|
-
end # LinkedAppNotRunning
|
185
|
-
|
186
|
-
class LinkedAppRedMaster < LinkedApp
|
187
|
-
def starting_environments
|
188
|
-
envs = super
|
189
|
-
envs[0]["instances"][0]["status"] = "error"
|
190
|
-
envs
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
class OneAppManyEnvs < Base
|
195
|
-
def starting_apps
|
196
|
-
[{
|
197
|
-
"id" => 1001,
|
198
|
-
"name" => "rails232app",
|
199
|
-
"repository_uri" => git_remote}]
|
200
|
-
end
|
201
|
-
|
202
|
-
def starting_app_joins
|
203
|
-
[
|
204
|
-
[1001, 200],
|
205
|
-
[1001, 202],
|
206
|
-
]
|
207
|
-
end
|
208
|
-
|
209
|
-
def starting_environments
|
210
|
-
[{
|
211
|
-
"ssh_username" => "turkey",
|
212
|
-
"instances" => [{
|
213
|
-
"status" => "running",
|
214
|
-
"id" => 27220,
|
215
|
-
"amazon_id" => 'i-ddbbdd92',
|
216
|
-
"role" => "solo",
|
217
|
-
"public_hostname" => "app_master_hostname.compute-1.amazonaws.com"}],
|
218
|
-
"name" => "giblets",
|
219
|
-
"instances_count" => 1,
|
220
|
-
"id" => 200,
|
221
|
-
"app_server_stack_name" => "nginx_mongrel",
|
222
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
223
|
-
"framework_env" => "production",
|
224
|
-
"deployment_configurations" => {
|
225
|
-
"rails232app" => {
|
226
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
227
|
-
}
|
228
|
-
},
|
229
|
-
}, {
|
230
|
-
"ssh_username" => "ham",
|
231
|
-
"instances" => [],
|
232
|
-
"name" => "bakon",
|
233
|
-
"instances_count" => 0,
|
234
|
-
"app_server_stack_name" => "nginx_passenger",
|
235
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
236
|
-
"id" => 202,
|
237
|
-
"deployment_configurations" => {
|
238
|
-
"rails232app" => {
|
239
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
240
|
-
}
|
241
|
-
},
|
242
|
-
}, {
|
243
|
-
"ssh_username" => "hamburger",
|
244
|
-
"instances" => [],
|
245
|
-
"name" => "beef",
|
246
|
-
"instances_count" => 0,
|
247
|
-
"app_server_stack_name" => "nginx_passenger",
|
248
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
249
|
-
"id" => 206,
|
250
|
-
}]
|
251
|
-
end
|
252
|
-
end # OneAppTwoEnvs
|
253
|
-
|
254
|
-
class TwoApps < Base
|
255
|
-
def railsapp_master
|
256
|
-
{
|
257
|
-
"status" => "running",
|
258
|
-
"name" => nil,
|
259
|
-
"role" => "solo",
|
260
|
-
"public_hostname" => "ec2-174-129-7-113.compute-1.amazonaws.com",
|
261
|
-
"id" => 35707,
|
262
|
-
"amazon_id" => "i-0911f063",
|
263
|
-
}
|
264
|
-
end
|
265
|
-
private :railsapp_master
|
266
|
-
|
267
|
-
def keycollector_master
|
268
|
-
{
|
269
|
-
"status" => "running",
|
270
|
-
"name" => nil,
|
271
|
-
"role" => "solo",
|
272
|
-
"public_hostname" => "app_master_hostname.compute-1.amazonaws.com",
|
273
|
-
"id" => 75428,
|
274
|
-
"amazon_id" => "i-051195b9",
|
275
|
-
}
|
276
|
-
end
|
277
|
-
private :keycollector_master
|
278
|
-
|
279
|
-
def starting_apps
|
280
|
-
[{
|
281
|
-
"id" => 3202,
|
282
|
-
"name" => "keycollector",
|
283
|
-
"repository_uri" => "git@github.com:smerritt/keycollector.git",
|
284
|
-
}, {
|
285
|
-
"id" => 6125,
|
286
|
-
"name" => "rails232app",
|
287
|
-
"repository_uri" => "git://github.com/smerritt/rails232app.git"}]
|
288
|
-
end
|
289
|
-
|
290
|
-
def starting_app_joins
|
291
|
-
[
|
292
|
-
[6125, 200],
|
293
|
-
[3202, 439],
|
294
|
-
]
|
295
|
-
end
|
296
|
-
|
297
|
-
def starting_environments
|
298
|
-
[{
|
299
|
-
"id" => 200,
|
300
|
-
"name" => "giblets",
|
301
|
-
"framework_env" => "staging",
|
302
|
-
"ssh_username" => "turkey",
|
303
|
-
"instances_count" => 1,
|
304
|
-
"instances" => [railsapp_master],
|
305
|
-
"app_server_stack_name" => "nginx_unicorn",
|
306
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
307
|
-
"deployment_configurations" => {
|
308
|
-
"rails232app" => {
|
309
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
310
|
-
}
|
311
|
-
},
|
312
|
-
}, {
|
313
|
-
"id" => 439,
|
314
|
-
"framework_env" => "production",
|
315
|
-
"name" => "keycollector_production",
|
316
|
-
"ssh_username" => "deploy",
|
317
|
-
"instances_count" => 1,
|
318
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
319
|
-
"app_server_stack_name" => "nginx_mongrel",
|
320
|
-
"instances" => [keycollector_master],
|
321
|
-
"deployment_configurations" => {
|
322
|
-
"keycollector" => {
|
323
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
324
|
-
}
|
325
|
-
},
|
326
|
-
}]
|
327
|
-
end
|
328
|
-
end # TwoApps
|
329
|
-
|
330
|
-
class TwoAppsSameGitUri < TwoApps
|
331
|
-
def starting_apps
|
332
|
-
apps = super
|
333
|
-
apps.each do |app|
|
334
|
-
app["repository_uri"] = "git://github.com/engineyard/dup.git"
|
335
|
-
end
|
336
|
-
apps
|
337
|
-
end
|
338
|
-
end # TwoAppsSameGitUri
|
339
|
-
|
340
|
-
class OneAppManySimilarlyNamedEnvs < Base
|
341
|
-
def starting_apps
|
342
|
-
[{
|
343
|
-
"id" => 1001,
|
344
|
-
"name" => "rails232app",
|
345
|
-
"repository_uri" => git_remote}]
|
346
|
-
end
|
347
|
-
|
348
|
-
def starting_environments
|
349
|
-
[{
|
350
|
-
"id" => 200,
|
351
|
-
"ssh_username" => "turkey",
|
352
|
-
"instances" => [{
|
353
|
-
"status" => "running",
|
354
|
-
"id" => 27220,
|
355
|
-
"amazon_id" => 'i-ddbbdd92',
|
356
|
-
"role" => "solo",
|
357
|
-
"public_hostname" => "app_master_hostname.compute-1.amazonaws.com"}],
|
358
|
-
"name" => "railsapp_production",
|
359
|
-
"instances_count" => 1,
|
360
|
-
"load_balancer_ip_address" => '127.0.0.0',
|
361
|
-
"app_server_stack_name" => "nginx_mongrel",
|
362
|
-
"framework_env" => "production",
|
363
|
-
"deployment_configurations" => {
|
364
|
-
"rails232app" => {
|
365
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
366
|
-
}
|
367
|
-
},
|
368
|
-
}, {
|
369
|
-
"id" => 202,
|
370
|
-
"ssh_username" => "ham",
|
371
|
-
"instances" => [{
|
372
|
-
"public_hostname" => '127.3.2.1',
|
373
|
-
"status" => "running",
|
374
|
-
"id" => 63066,
|
375
|
-
"role" => "solo",
|
376
|
-
}],
|
377
|
-
"name" => "railsapp_staging",
|
378
|
-
"instances_count" => 1,
|
379
|
-
"load_balancer_ip_address" => '127.3.2.1',
|
380
|
-
"app_server_stack_name" => "nginx_passenger",
|
381
|
-
"framework_env" => "production",
|
382
|
-
"deployment_configurations" => {
|
383
|
-
"rails232app" => {
|
384
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
385
|
-
}
|
386
|
-
},
|
387
|
-
}, {
|
388
|
-
"ssh_username" => "ham",
|
389
|
-
"instances" => [{
|
390
|
-
"status" => "running",
|
391
|
-
"id" => 59395,
|
392
|
-
"role" => "solo",
|
393
|
-
"public_hostname" => "ec2-174-129-198-124.compute-1.amazonaws.com",
|
394
|
-
}],
|
395
|
-
"name" => "railsapp_staging_2",
|
396
|
-
"instances_count" => 1,
|
397
|
-
"app_server_stack_name" => "nginx_passenger",
|
398
|
-
"id" => 204,
|
399
|
-
"load_balancer_ip_address" => '127.0.0.2',
|
400
|
-
"framework_env" => "production",
|
401
|
-
"deployment_configurations" => {
|
402
|
-
"rails232app" => {
|
403
|
-
'migrate' => {'command' => 'rake db:migrate', 'perform' => true}
|
404
|
-
}
|
405
|
-
},
|
406
|
-
}]
|
407
|
-
end
|
408
|
-
|
409
|
-
def starting_app_joins
|
410
|
-
[
|
411
|
-
[1001, 200],
|
412
|
-
[1001, 202],
|
413
|
-
[1001, 204],
|
414
|
-
]
|
415
|
-
end
|
416
|
-
end # OneAppManySimilarlyNamedEnvs
|
417
|
-
end
|