engineyard 2.3.3 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/lib/engineyard/cli.rb +269 -167
- data/lib/engineyard/cli/api.rb +1 -1
- data/lib/engineyard/cli/recipes.rb +27 -23
- data/lib/engineyard/cli/ui.rb +1 -1
- data/lib/engineyard/cli/web.rb +33 -33
- data/lib/engineyard/serverside_runner.rb +8 -4
- data/lib/engineyard/templates/ey.yml.erb +4 -1
- data/lib/engineyard/thor.rb +12 -12
- data/lib/engineyard/version.rb +2 -2
- data/spec/ey/scp_spec.rb +176 -0
- data/spec/ey/servers_spec.rb +66 -0
- data/spec/support/helpers.rb +1 -1
- metadata +76 -65
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NmE3MWNiYjFlYzk1NDE3MmNlY2UxZjFkNTNkNGNlMDNhYTMzYzIzYQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a21285072c40633408e1d024bb659a4afe81e032
|
4
|
+
data.tar.gz: c08bd05835ef584a8baee421bfd53b78ef4b5767
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NWYyMGRhYzVlNThhODY1YWIwZjU2NmI0MGVmNDFlZmFlNDY2YWM5ZGE0ZGI1
|
11
|
-
MDI1MzM1YTAyZDcxN2MyYjM1MDg3ODZhNzVmNjVkNDI5ZTQ5ZmQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YmU5ZDc5YzhiNWMzNTU2YWM3MTMyM2JjNDQ4M2ViYmIwNjU1ODE5YzlkZmYz
|
14
|
-
MTU1ZmRlYTgyOWNhNDAxYzI5YTIyYjc5MTJhOGNiYWIwNDhjMzAyOTNiN2Y2
|
15
|
-
ZWY1Mjk2Y2VmZmEzOTVhY2FkOTJjYmIzMWY2NWZhZDdjNjE3MjI=
|
6
|
+
metadata.gz: 211d35f2316b84133b6603c17ad18febb909f43617d4ce1c31b0fd425d7cd6f78a89c73a49f7f52ffb27c633aa41ad917d6428a012f2872902c8d95767476742
|
7
|
+
data.tar.gz: bac2d6e8a5b19a4b54a32f08121cae917540e730e5ddd065394e6f6691d1cbb9dd74d5e154ecdec0800d12181fd7529b790d7aa0444f263923c0880e7e6a3d50
|
data/lib/engineyard/cli.rb
CHANGED
@@ -20,7 +20,7 @@ module EY
|
|
20
20
|
def self.start(given_args=ARGV, config={})
|
21
21
|
Thor::Base.shell = EY::CLI::UI
|
22
22
|
ui = EY::CLI::UI.new
|
23
|
-
super(given_args, {:
|
23
|
+
super(given_args, {shell: ui}.merge(config))
|
24
24
|
rescue Thor::Error, EY::Error, EY::CloudClient::Error => e
|
25
25
|
ui.print_exception(e)
|
26
26
|
raise
|
@@ -37,9 +37,9 @@ module EY
|
|
37
37
|
raise
|
38
38
|
end
|
39
39
|
|
40
|
-
class_option :api_token, :
|
41
|
-
class_option :serverside_version, :
|
42
|
-
class_option :quiet, :
|
40
|
+
class_option :api_token, type: :string, desc: "Use API_TOKEN to authenticate this command"
|
41
|
+
class_option :serverside_version, type: :string, desc: "Please use with care! Override deploy system version (same as ENV variable ENGINEYARD_SERVERSIDE_VERSION)"
|
42
|
+
class_option :quiet, aliases: %w[-q], type: :boolean, desc: "Quieter CLI output."
|
43
43
|
|
44
44
|
desc "init",
|
45
45
|
"Initialize the current directory with an ey.yml configuration file."
|
@@ -53,8 +53,8 @@ module EY
|
|
53
53
|
IMPORTANT: THE GENERATED FILE '#{EY::Config.pathname_for_write}'
|
54
54
|
MUST BE COMMITTED TO YOUR REPOSITORY OR OPTIONS WILL NOT BE LOADED.
|
55
55
|
DESC
|
56
|
-
method_option :path, :
|
57
|
-
:
|
56
|
+
method_option :path, type: :string, aliases: %w(-p),
|
57
|
+
desc: "Path for ey.yml (supported paths: #{EY::Config::CONFIG_FILES.join(', ')})"
|
58
58
|
def init
|
59
59
|
unless EY::Repo.exist?
|
60
60
|
raise EY::Error, "Working directory is not a repository. Aborting."
|
@@ -96,30 +96,30 @@ Go look at it, then add it to your repository!
|
|
96
96
|
specifying --migrate or --migrate 'rake db:migrate'.
|
97
97
|
Migrations can also be skipped by using --no-migrate.
|
98
98
|
DESC
|
99
|
-
method_option :ignore_bad_master, :
|
100
|
-
:
|
101
|
-
method_option :migrate, :
|
102
|
-
:
|
103
|
-
:
|
104
|
-
method_option :ref, :
|
105
|
-
:
|
106
|
-
:
|
107
|
-
method_option :force_ref, :
|
108
|
-
:
|
109
|
-
:
|
110
|
-
method_option :environment, :
|
111
|
-
:
|
112
|
-
:
|
113
|
-
method_option :app, :
|
114
|
-
:
|
115
|
-
:
|
116
|
-
method_option :account, :
|
117
|
-
:
|
118
|
-
:
|
119
|
-
method_option :verbose, :
|
120
|
-
:
|
121
|
-
method_option :config, :
|
122
|
-
:
|
99
|
+
method_option :ignore_bad_master, type: :boolean, aliases: %w(--ignore-bad-bridge),
|
100
|
+
desc: "Force a deploy even if the master is in a bad state"
|
101
|
+
method_option :migrate, type: :string, aliases: %w(-m),
|
102
|
+
lazy_default: true,
|
103
|
+
desc: "Run migrations via [MIGRATE]; use --no-migrate to avoid running migrations"
|
104
|
+
method_option :ref, type: :string, aliases: %w(-r --branch --tag),
|
105
|
+
required: true, default: '',
|
106
|
+
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."
|
107
|
+
method_option :force_ref, type: :string, aliases: %w(--ignore-default-branch -R),
|
108
|
+
lazy_default: true,
|
109
|
+
desc: "Force a deploy of the specified git ref even if a default is set in ey.yml."
|
110
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
111
|
+
required: true, default: false,
|
112
|
+
desc: "Environment in which to deploy this application"
|
113
|
+
method_option :app, type: :string, aliases: %w(-a),
|
114
|
+
required: true, default: '',
|
115
|
+
desc: "Name of the application to deploy"
|
116
|
+
method_option :account, type: :string, aliases: %w(-c),
|
117
|
+
required: true, default: '',
|
118
|
+
desc: "Name of the account in which the environment can be found"
|
119
|
+
method_option :verbose, type: :boolean, aliases: %w(-v),
|
120
|
+
desc: "Be verbose"
|
121
|
+
method_option :config, type: :hash, default: {}, aliases: %w(--extra-deploy-hook-options),
|
122
|
+
desc: "Hash made available in deploy hooks (in the 'config' hash), can also override some ey.yml settings."
|
123
123
|
def deploy
|
124
124
|
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
125
125
|
|
@@ -127,11 +127,11 @@ Go look at it, then add it to your repository!
|
|
127
127
|
deploy_config = EY::DeployConfig.new(options, env_config, repo, ui)
|
128
128
|
|
129
129
|
deployment = app_env.new_deployment({
|
130
|
-
:
|
131
|
-
:
|
132
|
-
:
|
133
|
-
:
|
134
|
-
:
|
130
|
+
ref: deploy_config.ref,
|
131
|
+
migrate: deploy_config.migrate,
|
132
|
+
migrate_command: deploy_config.migrate_command,
|
133
|
+
extra_config: deploy_config.extra_config,
|
134
|
+
serverside_version: serverside_version,
|
135
135
|
})
|
136
136
|
|
137
137
|
runner = serverside_runner(app_env, deploy_config.verbose, deployment.serverside_version, options[:ignore_bad_master])
|
@@ -204,15 +204,15 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
204
204
|
deployment as failed. Only run this when a deployment is known to be
|
205
205
|
wrongly unfinished/stuck and when further deployments are blocked.
|
206
206
|
DESC
|
207
|
-
method_option :environment, :
|
208
|
-
:
|
209
|
-
:
|
210
|
-
method_option :app, :
|
211
|
-
:
|
212
|
-
:
|
213
|
-
method_option :account, :
|
214
|
-
:
|
215
|
-
:
|
207
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
208
|
+
required: true, default: false,
|
209
|
+
desc: "Environment in which to deploy this application"
|
210
|
+
method_option :app, type: :string, aliases: %w(-a),
|
211
|
+
required: true, default: '',
|
212
|
+
desc: "Name of the application to deploy"
|
213
|
+
method_option :account, type: :string, aliases: %w(-c),
|
214
|
+
required: true, default: '',
|
215
|
+
desc: "Name of the account in which the environment can be found"
|
216
216
|
def timeout_deploy
|
217
217
|
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
218
218
|
deployment = app_env.last_deployment
|
@@ -235,15 +235,15 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
235
235
|
Show the current status of most recent deployment of the specified
|
236
236
|
application and environment.
|
237
237
|
DESC
|
238
|
-
method_option :environment, :
|
239
|
-
:
|
240
|
-
:
|
241
|
-
method_option :app, :
|
242
|
-
:
|
243
|
-
:
|
244
|
-
method_option :account, :
|
245
|
-
:
|
246
|
-
:
|
238
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
239
|
+
required: true, default: '',
|
240
|
+
desc: "Environment where the application is deployed"
|
241
|
+
method_option :app, type: :string, aliases: %w(-a),
|
242
|
+
required: true, default: '',
|
243
|
+
desc: "Name of the application"
|
244
|
+
method_option :account, type: :string, aliases: %w(-c),
|
245
|
+
required: true, default: '',
|
246
|
+
desc: "Name of the account in which the application can be found"
|
247
247
|
def status
|
248
248
|
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
249
249
|
deployment = app_env.last_deployment
|
@@ -260,19 +260,19 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
260
260
|
display all environments, including those for this app.
|
261
261
|
DESC
|
262
262
|
|
263
|
-
method_option :all, :
|
264
|
-
:
|
265
|
-
method_option :simple, :
|
266
|
-
:
|
267
|
-
method_option :app, :
|
268
|
-
:
|
269
|
-
:
|
270
|
-
method_option :account, :
|
271
|
-
:
|
272
|
-
:
|
273
|
-
method_option :environment, :
|
274
|
-
:
|
275
|
-
:
|
263
|
+
method_option :all, type: :boolean, aliases: %(-A),
|
264
|
+
desc: "Show all environments (ignores --app, --account, and --environment arguments)"
|
265
|
+
method_option :simple, type: :boolean, aliases: %(-s),
|
266
|
+
desc: "Display one environment per line with no extra output"
|
267
|
+
method_option :app, type: :string, aliases: %w(-a),
|
268
|
+
required: true, default: '',
|
269
|
+
desc: "Show environments for this application"
|
270
|
+
method_option :account, type: :string, aliases: %w(-c),
|
271
|
+
required: true, default: '',
|
272
|
+
desc: "Show environments in this account"
|
273
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
274
|
+
required: true, default: '',
|
275
|
+
desc: "Show environments matching environment name"
|
276
276
|
def environments
|
277
277
|
if options[:all] && options[:simple]
|
278
278
|
ui.print_simple_envs api.environments
|
@@ -286,10 +286,10 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
286
286
|
end
|
287
287
|
|
288
288
|
resolver = api.resolve_app_environments({
|
289
|
-
:
|
290
|
-
:
|
291
|
-
:
|
292
|
-
:
|
289
|
+
account_name: options[:account],
|
290
|
+
app_name: options[:app],
|
291
|
+
environment_name: options[:environment],
|
292
|
+
remotes: remotes,
|
293
293
|
})
|
294
294
|
|
295
295
|
resolver.no_matches do |errors|
|
@@ -322,18 +322,32 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
322
322
|
or -uS (--user --host) to output bash loop friendly "user@hostname"
|
323
323
|
DESC
|
324
324
|
|
325
|
-
method_option :simple, :
|
326
|
-
:
|
327
|
-
method_option :host, :
|
328
|
-
:
|
329
|
-
method_option :user, :
|
330
|
-
:
|
331
|
-
method_option :account, :
|
332
|
-
:
|
333
|
-
:
|
334
|
-
method_option :environment, :
|
335
|
-
:
|
336
|
-
:
|
325
|
+
method_option :simple, type: :boolean, aliases: %(-s),
|
326
|
+
desc: "Display all information in a simplified format without extra text or column alignment"
|
327
|
+
method_option :host, type: :boolean, aliases: %(-S),
|
328
|
+
desc: "Display only hostnames, one per newline (use options -uS (--user --host) for user@hostname)"
|
329
|
+
method_option :user, type: :boolean, aliases: %w(-u),
|
330
|
+
desc: "Include the ssh username in front of the hostname for easy SSH scripting"
|
331
|
+
method_option :account, type: :string, aliases: %w(-c),
|
332
|
+
required: true, default: '',
|
333
|
+
desc: "Find environment in this account"
|
334
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
335
|
+
required: true, default: '',
|
336
|
+
desc: "Show servers in environment matching environment name"
|
337
|
+
method_option :all, type: :boolean, aliases: %(-A),
|
338
|
+
desc: "Show all servers (for compatibility only, this is the default for this command)"
|
339
|
+
method_option :app_master, type: :boolean,
|
340
|
+
desc: "Show only app master server"
|
341
|
+
method_option :app_servers, type: :boolean, aliases: %w(--app),
|
342
|
+
desc: "Show only application servers"
|
343
|
+
method_option :db_servers, type: :boolean, aliases: %w(--db),
|
344
|
+
desc: "Show only database servers"
|
345
|
+
method_option :db_master, type: :boolean,
|
346
|
+
desc: "Show only the master database server"
|
347
|
+
method_option :db_slaves, type: :boolean,
|
348
|
+
desc: "Show only the slave database servers"
|
349
|
+
method_option :utilities, type: :array, lazy_default: true, aliases: %w(--util),
|
350
|
+
desc: "Show only utility servers or only utility servers with the given names"
|
337
351
|
def servers
|
338
352
|
if options[:environment] == '' && options[:account] == ''
|
339
353
|
repo.fail_on_no_remotes!
|
@@ -345,7 +359,8 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
345
359
|
end
|
346
360
|
|
347
361
|
username = options[:user] && environment.username
|
348
|
-
|
362
|
+
|
363
|
+
servers = filter_servers(environment, options, default: {all: true})
|
349
364
|
|
350
365
|
if options[:host]
|
351
366
|
ui.print_hostnames(servers, username)
|
@@ -367,12 +382,12 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
367
382
|
successfully completed.
|
368
383
|
DESC
|
369
384
|
|
370
|
-
method_option :environment, :
|
371
|
-
:
|
372
|
-
:
|
373
|
-
method_option :account, :
|
374
|
-
:
|
375
|
-
:
|
385
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
386
|
+
required: true, default: '',
|
387
|
+
desc: "Environment to rebuild"
|
388
|
+
method_option :account, type: :string, aliases: %w(-c),
|
389
|
+
required: true, default: '',
|
390
|
+
desc: "Name of the account in which the environment can be found"
|
376
391
|
def rebuild
|
377
392
|
environment = fetch_environment(options[:environment], options[:account])
|
378
393
|
ui.info "Updating instances on #{environment.hierarchy_name}"
|
@@ -386,19 +401,19 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
386
401
|
remote server(s) to restart application servers.
|
387
402
|
DESC
|
388
403
|
|
389
|
-
method_option :environment, :
|
390
|
-
:
|
391
|
-
:
|
392
|
-
method_option :app, :
|
393
|
-
:
|
394
|
-
:
|
395
|
-
method_option :account, :
|
396
|
-
:
|
397
|
-
:
|
398
|
-
method_option :verbose, :
|
399
|
-
:
|
400
|
-
method_option :config, :
|
401
|
-
:
|
404
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
405
|
+
required: true, default: '',
|
406
|
+
desc: "Environment in which to roll back the application"
|
407
|
+
method_option :app, type: :string, aliases: %w(-a),
|
408
|
+
required: true, default: '',
|
409
|
+
desc: "Name of the application to roll back"
|
410
|
+
method_option :account, type: :string, aliases: %w(-c),
|
411
|
+
required: true, default: '',
|
412
|
+
desc: "Name of the account in which the environment can be found"
|
413
|
+
method_option :verbose, type: :boolean, aliases: %w(-v),
|
414
|
+
desc: "Be verbose"
|
415
|
+
method_option :config, type: :hash, default: {}, aliases: %w(--extra-deploy-hook-options),
|
416
|
+
desc: "Hash made available in deploy hooks (in the 'config' hash), can also override some ey.yml settings."
|
402
417
|
def rollback
|
403
418
|
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
404
419
|
env_config = config.environment_config(app_env.environment_name)
|
@@ -421,7 +436,7 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
421
436
|
desc "ssh [COMMAND] [--all] [--environment ENVIRONMENT]", "Open an ssh session to the master app server, or run a command."
|
422
437
|
long_desc <<-DESC
|
423
438
|
If a command is supplied, it will be run, otherwise a session will be
|
424
|
-
opened. The
|
439
|
+
opened. The bridge server (app master) is used for environments with multiple instances.
|
425
440
|
|
426
441
|
Option --all requires a command to be supplied and runs it on all servers or
|
427
442
|
pass --each to connect to each server one after another.
|
@@ -431,36 +446,37 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
431
446
|
|
432
447
|
$ #{banner_base} ssh "rm -f /some/file" -e my-environment --all
|
433
448
|
DESC
|
434
|
-
method_option :environment, :
|
435
|
-
:
|
436
|
-
:
|
437
|
-
method_option :account, :
|
438
|
-
:
|
439
|
-
:
|
440
|
-
method_option :all, :
|
441
|
-
:
|
442
|
-
method_option :app_servers, :
|
443
|
-
:
|
444
|
-
method_option :db_servers, :
|
445
|
-
:
|
446
|
-
method_option :db_master, :
|
447
|
-
:
|
448
|
-
method_option :db_slaves, :
|
449
|
-
:
|
450
|
-
method_option :utilities, :
|
451
|
-
:
|
452
|
-
method_option :shell, :
|
453
|
-
:
|
454
|
-
method_option :pty, :
|
455
|
-
:
|
456
|
-
method_option :bind_address, :
|
457
|
-
:
|
458
|
-
method_option :each, :
|
459
|
-
:
|
449
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
450
|
+
required: true, default: '',
|
451
|
+
desc: "Environment to ssh into"
|
452
|
+
method_option :account, type: :string, aliases: %w(-c),
|
453
|
+
required: true, default: '',
|
454
|
+
desc: "Name of the account in which the environment can be found"
|
455
|
+
method_option :all, type: :boolean, aliases: %(-A),
|
456
|
+
desc: "Run command on all servers"
|
457
|
+
method_option :app_servers, type: :boolean,
|
458
|
+
desc: "Run command on all application servers"
|
459
|
+
method_option :db_servers, type: :boolean,
|
460
|
+
desc: "Run command on the database servers"
|
461
|
+
method_option :db_master, type: :boolean,
|
462
|
+
desc: "Run command on the master database server"
|
463
|
+
method_option :db_slaves, type: :boolean,
|
464
|
+
desc: "Run command on the slave database servers"
|
465
|
+
method_option :utilities, type: :array, lazy_default: true,
|
466
|
+
desc: "Run command on the utility servers with the given names. If no names are given, run on all utility servers."
|
467
|
+
method_option :shell, type: :string, default: 'bash', aliases: %w(-s),
|
468
|
+
desc: "Run command in a shell other than bash. Use --no-shell to run the command without a shell."
|
469
|
+
method_option :pty, type: :boolean, default: false, aliases: %w(-t),
|
470
|
+
desc: "If a command is given, run in a pty. Required for interactive commands like sudo."
|
471
|
+
method_option :bind_address, type: :string, aliases: %w(-L),
|
472
|
+
desc: "When a command is not given, pass -L to the ssh command."
|
473
|
+
method_option :each, type: :boolean, default: false,
|
474
|
+
desc: "If no command is given, connect to multiple servers each one after another, instead of exiting with an error."
|
460
475
|
|
461
476
|
def ssh(cmd=nil)
|
462
477
|
environment = fetch_environment(options[:environment], options[:account])
|
463
|
-
instances =
|
478
|
+
instances = filter_servers(environment, options, default: {app_master: true})
|
479
|
+
user = environment.username
|
464
480
|
ssh_opts = []
|
465
481
|
|
466
482
|
if cmd
|
@@ -488,7 +504,8 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
488
504
|
|
489
505
|
trap(:INT) { abort "Aborting..." }
|
490
506
|
|
491
|
-
exits =
|
507
|
+
exits = []
|
508
|
+
instances.each do |instance|
|
492
509
|
host = instance.public_hostname
|
493
510
|
name = instance.name ? "#{instance.role} (#{instance.name})" : instance.role
|
494
511
|
ui.info "\nConnecting to #{name} #{host}..."
|
@@ -496,37 +513,122 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
496
513
|
ui.info "Ctrl + C to abort"
|
497
514
|
sleep 1.3
|
498
515
|
end
|
499
|
-
|
500
|
-
|
516
|
+
sshcmd = Escape.shell_command((ssh_cmd + ["#{user}@#{host}"] + [cmd]).compact)
|
517
|
+
ui.debug "$ #{sshcmd}"
|
518
|
+
system sshcmd
|
519
|
+
exits << $?.exitstatus
|
501
520
|
end
|
502
521
|
|
503
522
|
exit exits.detect {|status| status != 0 } || 0
|
504
523
|
end
|
505
524
|
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
525
|
+
desc "scp [FROM_PATH] [TO_PATH] [--all] [--environment ENVIRONMENT]", "scp a file to/from multiple servers in an environment"
|
526
|
+
long_desc <<-DESC
|
527
|
+
Use the system `scp` command to copy files to some or all of the servers.
|
528
|
+
|
529
|
+
If `HOST:` is found in the FROM_PATH or TO_PATH, the server name will be
|
530
|
+
substituted in place of `HOST:` when scp is run. This allows you to scp in
|
531
|
+
either direction by putting `HOST:` in the FROM_PATH or TO_PATH, as follows:
|
532
|
+
|
533
|
+
$ #{banner_base} scp example.json HOST:/data/app_name/current/config/ -e env --app-servers
|
534
|
+
|
535
|
+
$ #{banner_base} scp HOST:/data/app_name/current/config/example.json ./ -e env --app-servers
|
536
|
+
|
537
|
+
If `HOST:` is not specified, TO_PATH will be used as the remote path.
|
538
|
+
Be sure to escape shell words so they don't expand locally (e.g. '~').
|
539
|
+
|
540
|
+
Note: this command is a bit picky about its ordering. FROM_PATH TO_PATH
|
541
|
+
must follow immediately after `ey scp` with no flags in between.
|
542
|
+
DESC
|
543
|
+
method_option :environment, :type => :string, :aliases => %w(-e),
|
544
|
+
:required => true, :default => '',
|
545
|
+
:desc => "Name of the destination environment"
|
546
|
+
method_option :account, :type => :string, :aliases => %w(-c),
|
547
|
+
:required => true, :default => '',
|
548
|
+
:desc => "Name of the account in which the environment can be found"
|
549
|
+
method_option :all, :type => :boolean, :aliases => %(-A),
|
550
|
+
:desc => "scp to all servers"
|
551
|
+
method_option :app_servers, :type => :boolean,
|
552
|
+
:desc => "scp to all application servers"
|
553
|
+
method_option :db_servers, :type => :boolean,
|
554
|
+
:desc => "scp to database servers"
|
555
|
+
method_option :db_master, :type => :boolean,
|
556
|
+
:desc => "scp to the master database server"
|
557
|
+
method_option :db_slaves, :type => :boolean,
|
558
|
+
:desc => "scp to the slave database servers"
|
559
|
+
method_option :utilities, :type => :array, :lazy_default => true,
|
560
|
+
:desc => "scp to all utility servers or only those with the given names"
|
561
|
+
|
562
|
+
def scp(from_path, to_path)
|
563
|
+
environment = fetch_environment(options[:environment], options[:account])
|
564
|
+
instances = filter_servers(environment, options, default: {app_master: true})
|
565
|
+
user = environment.username
|
566
|
+
|
567
|
+
ui.info "Copying '#{from_path}' to '#{to_path}' on #{instances.count} server#{instances.count == 1 ? '' : 's'} serially..."
|
568
|
+
|
569
|
+
# default to `scp FROM_PATH HOST:TO_PATH`
|
570
|
+
unless [from_path, to_path].detect { |path| path =~ /HOST:/ }
|
571
|
+
to_path = "HOST:#{to_path}"
|
515
572
|
end
|
516
573
|
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
574
|
+
exits = []
|
575
|
+
instances.each do |instance|
|
576
|
+
host = instance.public_hostname
|
577
|
+
authority = "#{user}@#{host}:"
|
578
|
+
|
579
|
+
name = instance.name ? "#{instance.role} (#{instance.name})" : instance.role
|
580
|
+
ui.info "# #{name} #{host}"
|
581
|
+
|
582
|
+
from = from_path.sub(/^HOST:/, authority)
|
583
|
+
to = to_path.sub(/^HOST:/, authority)
|
584
|
+
|
585
|
+
cmd = Escape.shell_command(["scp", from, to])
|
586
|
+
ui.debug "$ #{cmd}"
|
587
|
+
system cmd
|
588
|
+
exits << $?.exitstatus
|
589
|
+
end
|
590
|
+
|
591
|
+
exit exits.detect {|status| status != 0 } || 0
|
592
|
+
end
|
593
|
+
|
594
|
+
no_tasks do
|
595
|
+
OPT_TO_ROLES = {
|
596
|
+
all: %w[all],
|
597
|
+
app_master: %w[solo app_master],
|
598
|
+
app_servers: %w[solo app app_master],
|
599
|
+
db_servers: %w[solo db_master db_slave],
|
600
|
+
db_master: %w[solo db_master],
|
601
|
+
db_slaves: %w[db_slave],
|
602
|
+
utilities: %w[util],
|
603
|
+
}
|
604
|
+
|
605
|
+
def filter_servers(environment, cli_opts, filter_opts)
|
606
|
+
if (cli_opts.keys.map(&:to_sym) & OPT_TO_ROLES.keys).any?
|
607
|
+
options = cli_opts.dup
|
608
|
+
else
|
609
|
+
options = filter_opts[:default].dup
|
610
|
+
end
|
611
|
+
|
612
|
+
options.keep_if {|k,v| OPT_TO_ROLES.has_key?(k.to_sym) }
|
613
|
+
|
614
|
+
if options[:all]
|
615
|
+
instances = environment.instances
|
524
616
|
else
|
525
|
-
|
617
|
+
roles = {}
|
618
|
+
options.each do |cli_opt,cli_val|
|
619
|
+
if cli_val && OPT_TO_ROLES.has_key?(cli_opt.to_sym)
|
620
|
+
OPT_TO_ROLES[cli_opt.to_sym].each do |role|
|
621
|
+
roles[role] = cli_val # val is true or an array of strings
|
622
|
+
end
|
623
|
+
end
|
624
|
+
end
|
625
|
+
instances = environment.select_instances(roles)
|
626
|
+
end
|
627
|
+
|
628
|
+
if instances.empty?
|
629
|
+
raise NoInstancesError.new(environment.name)
|
526
630
|
end
|
527
631
|
|
528
|
-
instances = environment.instances.select {|instance| filter[instance] }
|
529
|
-
raise NoInstancesError.new(environment.name) if instances.empty?
|
530
632
|
return instances
|
531
633
|
end
|
532
634
|
end
|
@@ -537,12 +639,12 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
537
639
|
recipes were uploaded to the environment & run, their logs will also be
|
538
640
|
displayed beneath the main configuration logs.
|
539
641
|
DESC
|
540
|
-
method_option :environment, :
|
541
|
-
:
|
542
|
-
:
|
543
|
-
method_option :account, :
|
544
|
-
:
|
545
|
-
:
|
642
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
643
|
+
required: true, default: '',
|
644
|
+
desc: "Environment with the interesting logs"
|
645
|
+
method_option :account, type: :string, aliases: %w(-c),
|
646
|
+
required: true, default: '',
|
647
|
+
desc: "Name of the account in which the environment can be found"
|
546
648
|
def logs
|
547
649
|
environment = fetch_environment(options[:environment], options[:account])
|
548
650
|
environment.logs.each do |log|
|
@@ -618,15 +720,15 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
|
|
618
720
|
end
|
619
721
|
|
620
722
|
desc "launch [--app APP] [--environment ENVIRONMENT] [--account ACCOUNT]", "Open application in browser."
|
621
|
-
method_option :environment, :
|
622
|
-
:
|
623
|
-
:
|
624
|
-
method_option :app, :
|
625
|
-
:
|
626
|
-
:
|
627
|
-
method_option :account, :
|
628
|
-
:
|
629
|
-
:
|
723
|
+
method_option :environment, type: :string, aliases: %w(-e),
|
724
|
+
required: true, default: '',
|
725
|
+
desc: "Environment where the application is deployed"
|
726
|
+
method_option :app, type: :string, aliases: %w(-a),
|
727
|
+
required: true, default: '',
|
728
|
+
desc: "Name of the application"
|
729
|
+
method_option :account, type: :string, aliases: %w(-c),
|
730
|
+
required: true, default: '',
|
731
|
+
desc: "Name of the account in which the application can be found"
|
630
732
|
def launch
|
631
733
|
app_env = fetch_app_environment(options[:app], options[:environment], options[:account])
|
632
734
|
Launchy.open(app_env.uri)
|