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
data/README.rdoc
CHANGED
@@ -20,10 +20,15 @@ The ey.yml file allows options to be saved for each environment to which an appl
|
|
20
20
|
---
|
21
21
|
environments:
|
22
22
|
env_production:
|
23
|
-
migrate: false
|
24
|
-
migration_command: rake fancy:migrate
|
25
|
-
branch: deploy
|
26
|
-
default: true
|
23
|
+
migrate: false # run migration command on every deploy
|
24
|
+
migration_command: rake fancy:migrate # default migration command
|
25
|
+
branch: deploy # default branch to deploy
|
26
|
+
default: true # make this environment default
|
27
|
+
bundle_without: test development mygroup # exclude groups on bundle install
|
28
|
+
copy_exclude: # don't rsync the following dirs
|
29
|
+
- .git
|
30
|
+
verbose: true # always run verbose deploy (unless overriden on command line)
|
31
|
+
|
27
32
|
|
28
33
|
This ey.yml file will turn off default migrations, set the default command to "rake fancy:migrate" and set the default deploy branch to "deploy".
|
29
34
|
|
@@ -208,3 +213,133 @@ Command:
|
|
208
213
|
|
209
214
|
Description:
|
210
215
|
Remove the current API key from ~/.eyrc or env variable $EYRC
|
216
|
+
|
217
|
+
|
218
|
+
== API Client
|
219
|
+
|
220
|
+
This library also contains a Ruby ey_api library to the Engine Yard Cloud API.
|
221
|
+
|
222
|
+
Setup:
|
223
|
+
|
224
|
+
token = EY::CloudClient.authenticate("your@email.com", "password")
|
225
|
+
ey_api = EY::CloudClient.new(token)
|
226
|
+
|
227
|
+
Current User:
|
228
|
+
|
229
|
+
user = ey_api.current_user
|
230
|
+
user.class # => EY::CloudClient::User
|
231
|
+
user.name # => "Your Name"
|
232
|
+
user.email # => "your@email.com"
|
233
|
+
|
234
|
+
Apps:
|
235
|
+
|
236
|
+
apps = ey_api.apps # loads all your app data at once; caches result
|
237
|
+
|
238
|
+
app = apps.find {|app| app.name == 'myapp'}
|
239
|
+
app.class # => EY::CloudClient::App
|
240
|
+
app.name # => 'myapp'
|
241
|
+
app.id # => 123
|
242
|
+
app.repository_uri # => git@github.com:myaccount/myapp.git
|
243
|
+
|
244
|
+
app.account.class # => EY::CloudClient::Account
|
245
|
+
|
246
|
+
app.app_environments.first.class # => EY::CloudClient::AppEnvironment
|
247
|
+
app.app_environments.map {|e| e.environment.name} # => ['myapp_production', 'myapp_staging']
|
248
|
+
|
249
|
+
Create a new application (to be booted within Environments):
|
250
|
+
|
251
|
+
account = EY::CloudClient::Account.new(ey_api, {:id => 4212, :name => 'drnic'})
|
252
|
+
app = EY::CloudClient::App.create(ey_api,
|
253
|
+
"account" => account
|
254
|
+
"name" => "myapp",
|
255
|
+
"repository_uri" => "git@github.com:mycompany/myapp.git",
|
256
|
+
"app_type_id" => "rails3",
|
257
|
+
})
|
258
|
+
|
259
|
+
Valid `app_type_id` are: `rack, rails2, rails3, rails4, sinatra, nodejs`. For some your account may require an early access feature to be enabled.
|
260
|
+
|
261
|
+
Accounts:
|
262
|
+
|
263
|
+
account = app.account
|
264
|
+
account.class # => EY::CloudClient::Account
|
265
|
+
account.id # => 1234
|
266
|
+
account.name # => 'myaccount'
|
267
|
+
|
268
|
+
Keypairs:
|
269
|
+
|
270
|
+
Upload your SSH public keys before you create Environments.
|
271
|
+
|
272
|
+
keypair = EY::CloudClient::Keypair.create(ey_api, {
|
273
|
+
"name" => 'laptop',
|
274
|
+
"public_key" => "ssh-rsa OTHERKEYPAIR"
|
275
|
+
})
|
276
|
+
|
277
|
+
Environments:
|
278
|
+
|
279
|
+
envs = ey_api.environments # loads all your environment data at once; caches result
|
280
|
+
|
281
|
+
env = envs.find {|e| e.name == 'myapp_production'}
|
282
|
+
env.class # => EY::CloudClient::Environment
|
283
|
+
env.name # => 'myapp_production'
|
284
|
+
env.id # => 2345
|
285
|
+
env.framework_env # => "production"
|
286
|
+
env.app_server_stack_name # => "nginx_thin"
|
287
|
+
env.deployment_configurations # => {"myapp"=>{"name"=>"myapp", "uri"=>nil, "migrate"=>{"command"=>"rake db:migrate", "perform"=>false}, "repository_uri"=>"git@github.com:myaccount/myapp.git", "id"=>123, "domain_name"=>"_"}}
|
288
|
+
env.load_balancer_ip_address # => "1.2.3.4"
|
289
|
+
|
290
|
+
# if environment isn't booted
|
291
|
+
env.instances_count # => 0
|
292
|
+
env.app_master # => nil
|
293
|
+
env.instances.count # => []
|
294
|
+
|
295
|
+
# if environment is booted
|
296
|
+
env.instances_count # => 1
|
297
|
+
env.app_master.class # => EY::CloudClient::Instance
|
298
|
+
env.instances.first.class # => EY::CloudClient::Instance
|
299
|
+
|
300
|
+
Create a new environment (for a given App):
|
301
|
+
|
302
|
+
app = EY::CloudClient::App.new(ey_api, {:id => 4212, :name => 'drnic'})
|
303
|
+
env = EY::CloudClient::Environment.create(ey_api,
|
304
|
+
"app" => app,
|
305
|
+
"name" => 'myapp_production',
|
306
|
+
"app_server_stack_name" => 'nginx_thin', # default: nginx_passenger3
|
307
|
+
"region" => 'us-west-1', # default: us-east-1
|
308
|
+
"framework_env" => 'staging' # default: production
|
309
|
+
})
|
310
|
+
|
311
|
+
|
312
|
+
Valid `app_server_stack_name` values: `nginx_unicorn, nginx_passenger3, nginx_nodejs, nginx_thin, nginx_puma`. For some your account may require an early access feature to be enabled.
|
313
|
+
|
314
|
+
Instances:
|
315
|
+
|
316
|
+
instance = env.instances.first
|
317
|
+
instance.class # => EY::CloudClient::Instance
|
318
|
+
instance.id # => 12345
|
319
|
+
instance.role # => "solo"
|
320
|
+
instance.status # => "running"
|
321
|
+
instance.amazon_id # => "i-abcdefg"
|
322
|
+
instance.hostname # => "ec2-1-2-3-4.compute-1.amazonaws.com"
|
323
|
+
instance.public_hostname # => "ec2-1-2-3-4.compute-1.amazonaws.com" # alias of hostname
|
324
|
+
|
325
|
+
Debugging:
|
326
|
+
|
327
|
+
Setup for debugging:
|
328
|
+
|
329
|
+
ENV['DEBUG']='1'
|
330
|
+
require 'engineyard/cli'
|
331
|
+
EY.ui = EY::CLI::UI.new
|
332
|
+
|
333
|
+
The API commands will print internal information:
|
334
|
+
|
335
|
+
app = EY::CloudClient::App.create(ey_api, account, 'myapp2', 'git@github.com:myaccount/myapp2.git', 'rails3')
|
336
|
+
Token YOURTOKEN
|
337
|
+
Request POST https://cloud.engineyard.com/api/v2/accounts/1234/apps
|
338
|
+
Params {"app"=>{"name"=>"myapp2", "app_type_id"=>"rails3", "repository_uri"=>"git@github.com:myaccount/myapp2.git"}}
|
339
|
+
Response
|
340
|
+
{"app"=>
|
341
|
+
{"environments"=>[],
|
342
|
+
"name"=>"myapp2",
|
343
|
+
"repository_uri"=>"git@github.com:myaccount/myapp2.git",
|
344
|
+
"account"=>{"name"=>"myaccount", "id"=>1234},
|
345
|
+
"id"=>12345}}
|
data/bin/ey
CHANGED
data/lib/engineyard.rb
CHANGED
@@ -1,32 +1,11 @@
|
|
1
1
|
thor_lib = File.expand_path(File.join(File.dirname(__FILE__), 'vendor', 'thor', 'lib'))
|
2
2
|
$:.unshift thor_lib
|
3
|
+
require 'engineyard-cloud-client'
|
3
4
|
|
4
5
|
module EY
|
5
|
-
require 'engineyard/ruby_ext'
|
6
6
|
require 'engineyard/version'
|
7
7
|
require 'engineyard/error'
|
8
8
|
require 'engineyard/config'
|
9
9
|
|
10
|
-
autoload :API, 'engineyard/api'
|
11
|
-
autoload :Collection, 'engineyard/collection'
|
12
|
-
autoload :Model, 'engineyard/model'
|
13
10
|
autoload :Repo, 'engineyard/repo'
|
14
|
-
autoload :Resolver, 'engineyard/resolver'
|
15
|
-
|
16
|
-
class UI
|
17
|
-
# stub debug outside of the CLI
|
18
|
-
def debug(*); end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.ui
|
22
|
-
@ui ||= UI.new
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.ui=(ui)
|
26
|
-
@ui = ui
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.config
|
30
|
-
@config ||= EY::Config.new
|
31
|
-
end
|
32
11
|
end
|
data/lib/engineyard/cli.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'engineyard'
|
2
2
|
require 'engineyard/error'
|
3
3
|
require 'engineyard/thor'
|
4
|
+
require 'engineyard/deploy_config'
|
5
|
+
require 'engineyard/serverside_runner'
|
4
6
|
|
5
7
|
module EY
|
6
8
|
class CLI < EY::Thor
|
@@ -8,13 +10,25 @@ module EY
|
|
8
10
|
require 'engineyard/cli/web'
|
9
11
|
require 'engineyard/cli/api'
|
10
12
|
require 'engineyard/cli/ui'
|
13
|
+
require 'engineyard/error'
|
14
|
+
require 'engineyard-cloud-client/errors'
|
11
15
|
|
12
16
|
include Thor::Actions
|
13
17
|
|
14
18
|
def self.start(*)
|
15
|
-
|
16
|
-
EY.ui = EY::CLI::UI.new
|
19
|
+
ui = EY::CLI::UI.new
|
17
20
|
super
|
21
|
+
rescue EY::Error, EY::CloudClient::Error => e
|
22
|
+
ui.print_exception(e)
|
23
|
+
raise
|
24
|
+
rescue Interrupt => e
|
25
|
+
puts
|
26
|
+
ui.print_exception(e)
|
27
|
+
ui.say("Quitting...")
|
28
|
+
raise
|
29
|
+
rescue Exception => e
|
30
|
+
ui.print_exception(e)
|
31
|
+
raise
|
18
32
|
end
|
19
33
|
|
20
34
|
desc "deploy [--environment ENVIRONMENT] [--ref GIT-REF]",
|
@@ -23,67 +37,95 @@ module EY
|
|
23
37
|
This command must be run with the current directory containing the app to be
|
24
38
|
deployed. If ey.yml specifies a default branch then the ref parameter can be
|
25
39
|
omitted. Furthermore, if a default branch is specified but a different command
|
26
|
-
is supplied the deploy will fail unless --
|
40
|
+
is supplied the deploy will fail unless -R or --force-ref is used.
|
27
41
|
|
28
|
-
Migrations are run based on the
|
29
|
-
|
30
|
-
|
31
|
-
can also be skipped
|
42
|
+
Migrations are run based on the settings in your ey.yml file.
|
43
|
+
With each deploy the default migration setting can be overriden by
|
44
|
+
specifying --migrate or --migrate 'rake db:migrate'.
|
45
|
+
Migrations can also be skipped by using --no-migrate.
|
32
46
|
DESC
|
33
|
-
method_option :
|
34
|
-
:lazy_default => true,
|
35
|
-
:desc => "Force a deploy of the specified git ref even if a default is set in ey.yml."
|
36
|
-
method_option :ignore_bad_master, :type => :boolean,
|
47
|
+
method_option :ignore_bad_master, :type => :boolean, :aliases => %w(--ignore-bad-bridge),
|
37
48
|
:desc => "Force a deploy even if the master is in a bad state"
|
38
49
|
method_option :migrate, :type => :string, :aliases => %w(-m),
|
39
50
|
:lazy_default => true,
|
40
|
-
:desc => "Run migrations via [MIGRATE], defaults to '
|
41
|
-
method_option :environment, :type => :string, :aliases => %w(-e),
|
42
|
-
:desc => "Environment in which to deploy this application"
|
51
|
+
:desc => "Run migrations via [MIGRATE], defaults to '#{EY::DeployConfig::Migrate::DEFAULT}'; use --no-migrate to avoid running migrations"
|
43
52
|
method_option :ref, :type => :string, :aliases => %w(-r --branch --tag),
|
53
|
+
:required => true, :default => '',
|
44
54
|
:desc => "Git ref to deploy. May be a branch, a tag, or a SHA. Use -R to deploy a different ref if a default is set."
|
55
|
+
method_option :force_ref, :type => :string, :aliases => %w(--ignore-default-branch -R),
|
56
|
+
:lazy_default => true,
|
57
|
+
:desc => "Force a deploy of the specified git ref even if a default is set in ey.yml."
|
58
|
+
method_option :environment, :type => :string, :aliases => %w(-e),
|
59
|
+
:required => true, :default => false,
|
60
|
+
:desc => "Environment in which to deploy this application"
|
45
61
|
method_option :app, :type => :string, :aliases => %w(-a),
|
62
|
+
:required => true, :default => '',
|
46
63
|
:desc => "Name of the application to deploy"
|
47
64
|
method_option :account, :type => :string, :aliases => %w(-c),
|
65
|
+
:required => true, :default => '',
|
48
66
|
:desc => "Name of the account in which the environment can be found"
|
49
67
|
method_option :verbose, :type => :boolean, :aliases => %w(-v),
|
50
68
|
:desc => "Be verbose"
|
51
69
|
method_option :extra_deploy_hook_options, :type => :hash, :default => {},
|
52
70
|
:desc => "Additional options to be made available in deploy hooks (in the 'config' hash)"
|
53
71
|
def deploy
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
environment.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
72
|
+
ui.info "Loading application data from EY Cloud..."
|
73
|
+
|
74
|
+
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
75
|
+
app_env.environment.ignore_bad_bridge = options[:ignore_bad_master]
|
76
|
+
|
77
|
+
env_config = config.environment_config(app_env.environment_name)
|
78
|
+
deploy_config = EY::DeployConfig.new(options, env_config, repo, ui)
|
79
|
+
|
80
|
+
deployment = app_env.new_deployment({
|
81
|
+
:ref => deploy_config.ref,
|
82
|
+
:migrate => deploy_config.migrate,
|
83
|
+
:migrate_command => deploy_config.migrate_command,
|
84
|
+
:extra_config => deploy_config.extra_config,
|
85
|
+
})
|
86
|
+
|
87
|
+
runner = serverside_runner(app_env, deploy_config.verbose)
|
88
|
+
|
89
|
+
out = EY::CLI::UI::Tee.new(ui.out, deployment.out)
|
90
|
+
err = EY::CLI::UI::Tee.new(ui.err, deployment.err)
|
91
|
+
|
92
|
+
ui.info "Beginning deploy..."
|
93
|
+
begin
|
94
|
+
deployment.start
|
95
|
+
ui.show_deployment(deployment)
|
96
|
+
out << "Deploy initiated.\n"
|
97
|
+
|
98
|
+
runner.deploy do |args|
|
99
|
+
args.config = deployment.config if deployment.config
|
100
|
+
if deployment.migrate
|
101
|
+
args.migrate = deployment.migrate_command
|
102
|
+
else
|
103
|
+
args.migrate = false
|
104
|
+
end
|
105
|
+
args.ref = deployment.resolved_ref
|
106
|
+
end
|
107
|
+
deployment.successful = runner.call(out, err)
|
108
|
+
rescue Interrupt
|
109
|
+
err << "Interrupted. Deployment halted.\n"
|
110
|
+
ui.warn "Recording canceled deployment in EY Cloud..."
|
111
|
+
ui.warn "WARNING: Interrupting again may result in a never-finished deployment in the deployment history on EY Cloud."
|
112
|
+
raise
|
113
|
+
rescue StandardError => e
|
114
|
+
deployment.err << "Error encountered during deploy.\n#{e.class} #{e}\n"
|
115
|
+
ui.print_exception(e)
|
116
|
+
raise
|
117
|
+
ensure
|
118
|
+
deployment.finished
|
119
|
+
|
120
|
+
if deployment.successful?
|
121
|
+
ui.info "Successful deployment recorded on EY Cloud"
|
122
|
+
ui.info "Deploy complete"
|
123
|
+
ui.info "Now you can run `ey launch' to open the application in a browser."
|
124
|
+
else
|
125
|
+
ui.info "Failed deployment recorded on EY Cloud"
|
126
|
+
raise EY::Error, "Deploy failed"
|
127
|
+
end
|
81
128
|
end
|
82
|
-
|
83
|
-
rescue NoEnvironmentError => e
|
84
|
-
# Give better feedback about why we couldn't find the environment.
|
85
|
-
exists = api.environments.named(options[:environment])
|
86
|
-
raise exists ? EnvironmentUnlinkedError.new(options[:environment]) : e
|
87
129
|
end
|
88
130
|
|
89
131
|
desc "status", "Show the deployment status of the app"
|
@@ -92,18 +134,25 @@ module EY
|
|
92
134
|
application and environment.
|
93
135
|
DESC
|
94
136
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
137
|
+
:required => true, :default => '',
|
95
138
|
:desc => "Environment where the application is deployed"
|
96
139
|
method_option :app, :type => :string, :aliases => %w(-a),
|
140
|
+
:required => true, :default => '',
|
97
141
|
:desc => "Name of the application"
|
98
142
|
method_option :account, :type => :string, :aliases => %w(-c),
|
143
|
+
:required => true, :default => '',
|
99
144
|
:desc => "Name of the account in which the application can be found"
|
100
145
|
def status
|
101
|
-
|
102
|
-
deployment =
|
146
|
+
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
147
|
+
deployment = app_env.last_deployment
|
103
148
|
if deployment
|
104
|
-
|
149
|
+
ui.say "# Status of last deployment of #{app_env.to_hierarchy_str}:"
|
150
|
+
ui.say "#"
|
151
|
+
ui.show_deployment(deployment)
|
152
|
+
ui.say "#"
|
153
|
+
ui.deployment_result(deployment)
|
105
154
|
else
|
106
|
-
raise EY::Error, "Application #{app.name}
|
155
|
+
raise EY::Error, "Application #{app_env.app.name} has not been deployed on #{app_env.environment.name}."
|
107
156
|
end
|
108
157
|
end
|
109
158
|
|
@@ -113,27 +162,55 @@ module EY
|
|
113
162
|
display all environments, including those for this app.
|
114
163
|
DESC
|
115
164
|
|
116
|
-
method_option :all, :type => :boolean, :aliases => %(-
|
117
|
-
|
165
|
+
method_option :all, :type => :boolean, :aliases => %(-A),
|
166
|
+
:desc => "Show all environments (ignores --app, --account, and --environment arguments)"
|
167
|
+
method_option :simple, :type => :boolean, :aliases => %(-s),
|
168
|
+
:desc => "Display one environment per line with no extra output"
|
169
|
+
method_option :app, :type => :string, :aliases => %w(-a),
|
170
|
+
:required => true, :default => '',
|
171
|
+
:desc => "Show environments for this application"
|
172
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
173
|
+
:required => true, :default => '',
|
174
|
+
:desc => "Show environments in this account"
|
175
|
+
method_option :environment, :type => :string, :aliases => %w(-e),
|
176
|
+
:required => true, :default => '',
|
177
|
+
:desc => "Show environments matching environment name"
|
118
178
|
def environments
|
119
179
|
if options[:all] && options[:simple]
|
120
180
|
# just put each env
|
121
181
|
puts api.environments.map {|env| env.name}
|
122
182
|
elsif options[:all]
|
123
|
-
|
183
|
+
ui.print_envs(api.apps, config.default_environment, options[:simple], config.endpoint)
|
124
184
|
else
|
125
|
-
|
185
|
+
remotes = nil
|
186
|
+
if options[:app] == ''
|
187
|
+
repo.fail_on_no_remotes!
|
188
|
+
remotes = repo.remotes
|
189
|
+
end
|
190
|
+
|
191
|
+
resolver = api.resolve_app_environments({
|
192
|
+
:account_name => options[:account],
|
193
|
+
:app_name => options[:app],
|
194
|
+
:environment_name => options[:environment],
|
195
|
+
:remotes => remotes,
|
196
|
+
})
|
197
|
+
|
198
|
+
resolver.no_matches do |errors|
|
199
|
+
messages = errors
|
200
|
+
messages << "Use #{self.class.send(:banner_base)} environments --all to see all environments."
|
201
|
+
raise EY::NoMatchesError.new(messages.join("\n"))
|
202
|
+
end
|
203
|
+
|
204
|
+
apps = resolver.matches.map { |app_env| app_env.app }.uniq
|
126
205
|
|
127
206
|
if apps.size > 1
|
128
207
|
message = "This git repo matches multiple Applications in EY Cloud:\n"
|
129
208
|
apps.each { |app| message << "\t#{app.name}\n" }
|
130
209
|
message << "The following environments contain those applications:\n\n"
|
131
|
-
|
132
|
-
elsif apps.empty?
|
133
|
-
EY.ui.warn(NoAppError.new(repo).message + "\nUse #{self.class.send(:banner_base)} environments --all to see all environments.")
|
210
|
+
ui.warn(message)
|
134
211
|
end
|
135
212
|
|
136
|
-
|
213
|
+
ui.print_envs(apps, config.default_environment, options[:simple], config.endpoint)
|
137
214
|
end
|
138
215
|
end
|
139
216
|
map "envs" => :environments
|
@@ -150,12 +227,14 @@ module EY
|
|
150
227
|
DESC
|
151
228
|
|
152
229
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
230
|
+
:required => true, :default => '',
|
153
231
|
:desc => "Environment to rebuild"
|
154
232
|
method_option :account, :type => :string, :aliases => %w(-c),
|
233
|
+
:required => true, :default => '',
|
155
234
|
:desc => "Name of the account in which the environment can be found"
|
156
235
|
def rebuild
|
157
236
|
environment = fetch_environment(options[:environment], options[:account])
|
158
|
-
|
237
|
+
ui.debug("Rebuilding #{environment.name}")
|
159
238
|
environment.rebuild
|
160
239
|
end
|
161
240
|
map "update" => :rebuild
|
@@ -167,21 +246,32 @@ module EY
|
|
167
246
|
DESC
|
168
247
|
|
169
248
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
249
|
+
:required => true, :default => '',
|
170
250
|
:desc => "Environment in which to roll back the application"
|
171
251
|
method_option :app, :type => :string, :aliases => %w(-a),
|
252
|
+
:required => true, :default => '',
|
172
253
|
:desc => "Name of the application to roll back"
|
173
254
|
method_option :account, :type => :string, :aliases => %w(-c),
|
255
|
+
:required => true, :default => '',
|
174
256
|
:desc => "Name of the account in which the environment can be found"
|
175
257
|
method_option :verbose, :type => :boolean, :aliases => %w(-v),
|
176
258
|
:desc => "Be verbose"
|
177
259
|
method_option :extra_deploy_hook_options, :type => :hash, :default => {},
|
178
260
|
:desc => "Additional options to be made available in deploy hooks (in the 'config' hash)"
|
179
261
|
def rollback
|
180
|
-
|
262
|
+
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
263
|
+
env_config = config.environment_config(app_env.environment_name)
|
264
|
+
deploy_config = EY::DeployConfig.new(options, env_config, repo, ui)
|
265
|
+
|
266
|
+
ui.info("Rolling back #{app_env.to_hierarchy_str}")
|
181
267
|
|
182
|
-
|
183
|
-
|
184
|
-
|
268
|
+
runner = serverside_runner(app_env, deploy_config.verbose)
|
269
|
+
runner.rollback do |args|
|
270
|
+
args.config = deploy_config.extra_config if deploy_config.extra_config
|
271
|
+
end
|
272
|
+
|
273
|
+
if runner.call(ui.out, ui.err)
|
274
|
+
ui.info "Rollback complete"
|
185
275
|
else
|
186
276
|
raise EY::Error, "Rollback failed"
|
187
277
|
end
|
@@ -199,8 +289,10 @@ module EY
|
|
199
289
|
$ #{banner_base} ssh "rm -f /some/file" -e my-environment --all
|
200
290
|
DESC
|
201
291
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
292
|
+
:required => true, :default => '',
|
202
293
|
:desc => "Environment to ssh into"
|
203
294
|
method_option :account, :type => :string, :aliases => %w(-c),
|
295
|
+
:required => true, :default => '',
|
204
296
|
:desc => "Name of the account in which the environment can be found"
|
205
297
|
method_option :all, :type => :boolean, :aliases => %(-a),
|
206
298
|
:desc => "Run command on all servers"
|
@@ -235,8 +327,7 @@ module EY
|
|
235
327
|
return lambda {|instance| %w(solo db_master db_slave).include?(instance.role) } if opts[:db_servers ]
|
236
328
|
return lambda {|instance| %w(solo db_master ).include?(instance.role) } if opts[:db_master ]
|
237
329
|
return lambda {|instance| %w(db_slave ).include?(instance.role) } if opts[:db_slaves ]
|
238
|
-
return lambda {|instance| %w(util
|
239
|
-
opts[:utilities].include?(instance.name) } if opts[:utilities ]
|
330
|
+
return lambda {|instance| %w(util).include?(instance.role) && opts[:utilities].include?(instance.name) } if opts[:utilities]
|
240
331
|
return lambda {|instance| %w(solo app_master ).include?(instance.role) }
|
241
332
|
end
|
242
333
|
|
@@ -264,22 +355,24 @@ module EY
|
|
264
355
|
displayed beneath the main configuration logs.
|
265
356
|
DESC
|
266
357
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
358
|
+
:required => true, :default => '',
|
267
359
|
:desc => "Environment with the interesting logs"
|
268
360
|
method_option :account, :type => :string, :aliases => %w(-c),
|
361
|
+
:required => true, :default => '',
|
269
362
|
:desc => "Name of the account in which the environment can be found"
|
270
363
|
def logs
|
271
364
|
environment = fetch_environment(options[:environment], options[:account])
|
272
365
|
environment.logs.each do |log|
|
273
|
-
|
366
|
+
ui.info log.instance_name
|
274
367
|
|
275
368
|
if log.main
|
276
|
-
|
277
|
-
|
369
|
+
ui.info "Main logs for #{environment.name}:"
|
370
|
+
ui.say log.main
|
278
371
|
end
|
279
372
|
|
280
373
|
if log.custom
|
281
|
-
|
282
|
-
|
374
|
+
ui.info "Custom logs for #{environment.name}:"
|
375
|
+
ui.say log.custom
|
283
376
|
end
|
284
377
|
end
|
285
378
|
end
|
@@ -292,7 +385,7 @@ module EY
|
|
292
385
|
|
293
386
|
desc "version", "Print version number."
|
294
387
|
def version
|
295
|
-
|
388
|
+
ui.say %{engineyard version #{EY::VERSION}}
|
296
389
|
end
|
297
390
|
map ["-v", "--version"] => :version
|
298
391
|
|
@@ -302,38 +395,38 @@ module EY
|
|
302
395
|
base = self.class.send(:banner_base)
|
303
396
|
list = self.class.printable_tasks
|
304
397
|
|
305
|
-
|
306
|
-
|
307
|
-
|
398
|
+
ui.say "Usage:"
|
399
|
+
ui.say " #{base} [--help] [--version] COMMAND [ARGS]"
|
400
|
+
ui.say
|
308
401
|
|
309
|
-
|
402
|
+
ui.say "Deploy commands:"
|
310
403
|
deploy_cmds = %w(deploy environments logs rebuild rollback status)
|
311
404
|
deploy_cmds.map! do |name|
|
312
405
|
list.find{|task| task[0] =~ /^#{base} #{name}/ }
|
313
406
|
end
|
314
407
|
list -= deploy_cmds
|
315
408
|
|
316
|
-
|
317
|
-
|
409
|
+
ui.print_help(deploy_cmds)
|
410
|
+
ui.say
|
318
411
|
|
319
412
|
self.class.subcommands.each do |name|
|
320
413
|
klass = self.class.subcommand_class_for(name)
|
321
414
|
list.reject!{|cmd| cmd[0] =~ /^#{base} #{name}/}
|
322
|
-
|
415
|
+
ui.say "#{name.capitalize} commands:"
|
323
416
|
tasks = klass.printable_tasks.reject{|t| t[0] =~ /help$/ }
|
324
|
-
|
325
|
-
|
417
|
+
ui.print_help(tasks)
|
418
|
+
ui.say
|
326
419
|
end
|
327
420
|
|
328
421
|
%w(help version).each{|n| list.reject!{|c| c[0] =~ /^#{base} #{n}/ } }
|
329
422
|
if list.any?
|
330
|
-
|
331
|
-
|
332
|
-
|
423
|
+
ui.say "Other commands:"
|
424
|
+
ui.print_help(list)
|
425
|
+
ui.say
|
333
426
|
end
|
334
427
|
|
335
428
|
self.class.send(:class_options_help, shell)
|
336
|
-
|
429
|
+
ui.say "See '#{base} help COMMAND' for more information on a specific command."
|
337
430
|
elsif klass = self.class.subcommand_class_for(cmds.first)
|
338
431
|
klass.new.help(*cmds[1..-1])
|
339
432
|
else
|
@@ -341,20 +434,25 @@ module EY
|
|
341
434
|
end
|
342
435
|
end
|
343
436
|
|
344
|
-
desc "launch [--environment ENVIRONMENT] [--account ACCOUNT]", "Open application in browser."
|
437
|
+
desc "launch [--app APP] [--environment ENVIRONMENT] [--account ACCOUNT]", "Open application in browser."
|
345
438
|
method_option :environment, :type => :string, :aliases => %w(-e),
|
346
|
-
:
|
439
|
+
:required => true, :default => '',
|
440
|
+
:desc => "Environment where the application is deployed"
|
441
|
+
method_option :app, :type => :string, :aliases => %w(-a),
|
442
|
+
:required => true, :default => '',
|
443
|
+
:desc => "Name of the application"
|
347
444
|
method_option :account, :type => :string, :aliases => %w(-c),
|
348
|
-
:
|
445
|
+
:required => true, :default => '',
|
446
|
+
:desc => "Name of the account in which the application can be found"
|
349
447
|
def launch
|
350
|
-
|
351
|
-
|
448
|
+
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
449
|
+
Launchy.open(app_env.uri)
|
352
450
|
end
|
353
451
|
|
354
452
|
desc "whoami", "Who am I logged in as?"
|
355
453
|
def whoami
|
356
|
-
|
357
|
-
|
454
|
+
current_user = api.current_user
|
455
|
+
ui.say "#{current_user.name} (#{current_user.email})"
|
358
456
|
end
|
359
457
|
|
360
458
|
desc "login", "Log in and verify access to EY Cloud."
|
@@ -366,10 +464,10 @@ module EY
|
|
366
464
|
def logout
|
367
465
|
eyrc = EYRC.load
|
368
466
|
if eyrc.delete_api_token
|
369
|
-
|
370
|
-
|
467
|
+
ui.say "API token removed: #{eyrc.path}"
|
468
|
+
ui.say "Run any other command to login again."
|
371
469
|
else
|
372
|
-
|
470
|
+
ui.say "Already logged out. Run any other command to login again."
|
373
471
|
end
|
374
472
|
end
|
375
473
|
|