engineyard 2.3.3 → 3.0.0
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.
- 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)
|