engineyard 1.4.29 → 1.7.0.pre2
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/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
|
|