engineyard 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- N2Y4ZmE1ZGQ5MDEzMWJiZDhlZWI0NmJjNGM5MGUyYjE2YjRlNTVjNw==
4
+ MWMzMTAwYWJkYWMyYjcxNjFhZjc0OThjZDM5M2E1MTJkMzIwNTg4Yg==
5
5
  data.tar.gz: !binary |-
6
- NTA2OWMyYmY4MTUwZjU1MTI4MDkwMDY4MTk1ZTNhNGQ4YWUxNTM3NA==
6
+ NGM3OWVjYTI2ZWJmOGM5MzI3MjdiMjc3NDMzMTRiMmM3YTA4ZDFiNg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MTc2NTMzNWI1ODNiYzRkYzQ4MWJiOTMzMzY4NTAyMjdkMGQ0ZTc3MGYxM2Nh
10
- MzRjYWQ1ODFlZTY4Y2VkN2M2M2EzYjBmNzJiNzNiMjJjM2JlMzFiYmNjNTM5
11
- OGM3ODZiNTQxZjIwZjM2NTRkNjc4ODcxN2U1OTBhNmIxZjQ4MzQ=
9
+ ZGI4ZWRlNWE3NWIzZWE0MTc4ODBlMDcxNjllZTk3M2Y3NTE3ZmE3MDNjMzVk
10
+ ODgyOTc1ZjUzMjI2OGRhYTNmZmM4OGU3YzQzMGQxZmFiNGQ4ZTg5MWI4NzJi
11
+ NGY1M2Q1MWM4ODRhZWUyY2RkZjI2MzhjOTlhYTQzNzBjODgwMmM=
12
12
  data.tar.gz: !binary |-
13
- ODQ0OTY5NDQwZTVjMzc4N2ZmOGU1Y2E0YTMzMmJlYjgwOGUxZGQyZDc1MGUx
14
- ZWNiNjQ3NWE3NzIyMGYzNmNmNWU0ZThmNDMxZWZmYWRiNGFiZDBiNzQ3ZGFm
15
- NGE5NjA1OTliMDNiNDA1ZDVjZGZlODIxMGM3ODllNGU0ZjU1ZTI=
13
+ OTY4OWZhOGZjZDdhYjY4NDc5OWE4ZjA5OTJhMjg4ZDFhNjVjMDFmMzM1ZjRj
14
+ ODJhMjNiYWY3MzBhZGMyNWI2MzFmNDkyNTliZmY1MzVhNWM5OGE2NjIzY2U1
15
+ YzU5OTU5Y2RjMjk4MDBlYTI5ZGM3ZDRmZDQxZmRjZGFiN2I4YmI=
data/README.md CHANGED
@@ -18,38 +18,56 @@ you for your Engine Yard email and password.
18
18
  ### Configuration
19
19
 
20
20
  The `ey.yml` file allows options to be saved for each environment to which an
21
- application is deployed. Here's an example ey.yml file in `ROOT/config/ey.yml`:
21
+ application is deployed.
22
+
23
+ A typical Rails application will have a `config/ey.yml` like this:
24
+
25
+ ---
26
+ # This is all you need for a typical rails application.
27
+ defaults:
28
+ migrate: true
29
+ migration_command: rake db:migrate
30
+ precompile_assets: true
31
+
32
+ The following `ey.yml` file shows other things that can be customized.
33
+ A typical application will not need most of these options.
22
34
 
23
- $ cat config/ey.yml
24
35
  ---
25
36
  # 'defaults' applies to all environments running this application.
37
+ # Only set these options if needed. The defaults are correct for most applications.
26
38
  defaults:
27
- bundle_without: test development mygroup # exclude groups on bundle install (leave blank to remove --without)
28
- bundle_options: --local # add extra options to the bundle install command line (does not override bundle_without)
29
- copy_exclude: # don't rsync the following dirs
30
- - .git
39
+ bundler: detect # By default, bundler is detected via Gemfile. Options: true: always run bundler; false: never run bundler
40
+ composer: detect # By default, composer is detected via composer.lock. Options: true: always run composer; false: never run composer
41
+ npm: detect # By default, npm is detected via package.json. Options: true: always run npm; false: never run npm
42
+ bundle_without: GROUP1 GROUP2 # exclude groups on bundle install (default: test development)
43
+ bundle_options: --OPTION # extra bundle install options (--local, --quiet, etc; does not override bundle_without)
44
+ copy_exclude: # don't rsync the following dirs (some people like to skip .git)
45
+ - SOME_LARGE_DIR
31
46
  maintenance_on_restart: false # show maintenance page during app restart (default: false except for glassfish and mongrel)
32
- maintenance_on_migrate: false # show maintenance page during migrations (default: true)
47
+ maintenance_on_migrate: true # show maintenance page during migrations (default: true)
33
48
  precompile_assets: true # enables rails assets precompilation (default: inferred using app/assets and config/application.rb)
34
49
  precomplie_assets_task: assets:precompile # override the assets:precompile rake task
35
- precompile_unchanged_assets: true # precompiles assets even if no changes would be detected (does not check for changes at all).
36
- asset_dependencies: app/assets # a list of relative paths to search for asset changes during each deploy.
37
- assets_strategy: shifting # choose an alternet asset management strategy (shifting, cleaning, private, shared)
38
- asset_roles: :all # specify on which roles to compile assets (default: [:app, :app_master, :solo] - must be an Array)
39
- asset_roles: # (Array input for multiple roles) - Use hook deploy/before_compile_assets.rb for finer grained control.
40
- - :app
41
- - :app_master
42
- - :util
50
+ precompile_unchanged_assets: false # if true, does not check git for changes before precompiling assets.
51
+ asset_dependencies: # a list of relative paths to search for asset changes during each deploy.
52
+ - app/assets # default
53
+ - lib/assets # default
54
+ - vendor/assets # default
55
+ - Gemfile.lock # default
56
+ - config/routes.rb # default
57
+ - config/application.rb # default
58
+ - config/requirejs.yml # custom option (be sure to include defaults if you specify this option)
59
+ asset_strategy: shifting # choose an alternet asset management strategy. See rails_assets/strategy.rb for more info.
60
+ asset_roles: :all # specify on which roles to compile assets (default: [:app, :app_master, :solo])
43
61
  ignore_database_adapter_warning: true # hide database adapter warning if you don't use MySQL or PostgreSQL (default: false)
44
62
 
45
63
  # Environment specific options apply only to a single environment and override settings in defaults.
46
64
  environments:
47
65
  env_production:
48
66
  precompile_unchanged_assets: true # precompiles assets even if no changes would be detected (does not check for changes at all).
49
- assets_strategy: shifting # choose an alternet asset management strategy (shifting, cleaning, private, shared)
67
+ asset_strategy: shifting # choose an alternet asset management strategy (shifting, cleaning, private, shared)
50
68
  asset_roles: :all # specify on which roles to compile assets (default: [:app, :app_master, :solo] - must be an Array)
51
69
  env_staging
52
- assets_strategy: private # Use an asset management that always refreshes, so staging enviroments don't get conflicts
70
+ asset_strategy: private # Use an asset management that always refreshes, so staging enviroments don't get conflicts
53
71
 
54
72
  These options in `ey.yml` will only work if the file is committed to your
55
73
  application repository. Make sure to commit this file. Different branches
@@ -59,6 +77,19 @@ found in the deploying commit will be used for the current deploy.
59
77
 
60
78
  ### Commands
61
79
 
80
+ #### ey init
81
+
82
+ Initialize a repository for deployment on Engine Yard Cloud.
83
+
84
+ This command writes or updates an ey.yml file which explains options available
85
+ for customizing the deployment process.
86
+
87
+ `ey init` can be run in existing applications to update the ey.yml file
88
+ without losing existing settings.
89
+
90
+ NOTE: Please verify all settings and changes after running ey init for
91
+ the first time.
92
+
62
93
  #### ey deploy
63
94
 
64
95
  This command must be run within the current directory containing the app to be
@@ -78,7 +109,7 @@ Options:
78
109
  -c, [--account=ACCOUNT] # Name of the account in which the environment can be found
79
110
  -a, [--app=APP] # Name of the application to deploy
80
111
  -e, [--environment=ENVIRONMENT] # Environment in which to deploy this application
81
- -m, [--migrate=MIGRATE] # Run migrations via [MIGRATE], defaults to 'rake db:migrate'; use --no-migrate to avoid running migrations
112
+ -m, [--migrate=MIGRATE] # Run migrations via [MIGRATE]; use --no-migrate to avoid running migrations
82
113
  -v, [--verbose] # Be verbose
83
114
  [--ignore-default-branch] # Force a deploy of the specified branch even if a default is set
84
115
  [--ignore-bad-master] # Force a deploy even if the master is in a bad state
@@ -129,6 +160,32 @@ Options:
129
160
  -s, [--simple] # Print each environment name on its own on a new line
130
161
  -a, [--all] # Show all environments, not just ones associated with this application.
131
162
 
163
+ #### ey servers
164
+
165
+ List all servers on an environment.
166
+
167
+ Options:
168
+
169
+ -c, [--account=ACCOUNT] # Name of the account in which the environment can be found
170
+ -e, [--environment=ENVIRONMENT] # Show only servers in the named environment
171
+ -u, [--user] # Print the user@ in front of the server hostname to make ssh connections simpler
172
+ -s, [--simple] # Print each server on a new line with hostname, role, and name separated by tabs
173
+ -S, [--host] # Print each server on a new line with hostname only. Use -Su for 'user@host'
174
+
175
+ Example output:
176
+
177
+ $ ey servers -s
178
+ ec2-10-0-0-0.us-west-2.compute.amazonaws.com i-aabbccdd app_master
179
+ ec2-10-0-0-1.us-west-2.compute.amazonaws.com i-bbccddee app
180
+ ec2-10-0-0-2.us-west-2.compute.amazonaws.com i-ccddeeff db_master
181
+ ec2-10-0-0-3.us-west-2.compute.amazonaws.com i-ddeeffaa util resque
182
+
183
+ $ ey servers -Su
184
+ deploy@ec2-10-0-0-0.us-west-2.compute.amazonaws.com
185
+ deploy@ec2-10-0-0-1.us-west-2.compute.amazonaws.com
186
+ deploy@ec2-10-0-0-2.us-west-2.compute.amazonaws.com
187
+ deploy@ec2-10-0-0-3.us-west-2.compute.amazonaws.com
188
+
132
189
 
133
190
  #### ey logs
134
191
 
@@ -1,9 +1,9 @@
1
- require 'engineyard-cloud-client'
2
-
3
1
  module EY
4
- require 'engineyard/version'
5
- require 'engineyard/error'
6
- require 'engineyard/config'
7
-
8
2
  autoload :Repo, 'engineyard/repo'
3
+ autoload :Templates, 'engineyard/templates'
9
4
  end
5
+
6
+ require 'engineyard-cloud-client'
7
+ require 'engineyard/version'
8
+ require 'engineyard/error'
9
+ require 'engineyard/config'
@@ -4,6 +4,7 @@ require 'engineyard/thor'
4
4
  require 'engineyard/deploy_config'
5
5
  require 'engineyard/serverside_runner'
6
6
  require 'launchy'
7
+ require 'fileutils'
7
8
 
8
9
  module EY
9
10
  class CLI < EY::Thor
@@ -36,10 +37,52 @@ module EY
36
37
  raise
37
38
  end
38
39
 
39
- class_option :api_token, :type => :string, :desc => "Use API-TOKEN to authenticate this command"
40
+ class_option :api_token, :type => :string, :desc => "Use API_TOKEN to authenticate this command"
40
41
  class_option :serverside_version, :type => :string, :desc => "Please use with care! Override deploy system version (same as ENV variable ENGINEYARD_SERVERSIDE_VERSION)"
41
42
  class_option :quiet, :aliases => %w[-q], :type => :boolean, :desc => "Quieter CLI output."
42
43
 
44
+ desc "init",
45
+ "Initialize the current directory with an ey.yml configuration file."
46
+ long_desc <<-DESC
47
+ Initialize the current directory with an ey.yml configuration file.
48
+
49
+ Please read the generated file and make adjustments.
50
+ Many applications will need only the default behavior.
51
+ For reference, many available options are explained in the generated file.
52
+
53
+ IMPORTANT: THE GENERATED FILE '#{EY::Config.pathname_for_write}'
54
+ MUST BE COMMITTED TO YOUR REPOSITORY OR OPTIONS WILL NOT BE LOADED.
55
+ DESC
56
+ method_option :path, :type => :string, :aliases => %w(-p),
57
+ :desc => "Path for ey.yml (supported paths: #{EY::Config::CONFIG_FILES.join(', ')})"
58
+ def init
59
+ unless EY::Repo.exist?
60
+ raise EY::Error, "Working directory is not a repository. Aborting."
61
+ end
62
+
63
+ path = Pathname.new(options['path'] || EY::Config.pathname_for_write)
64
+
65
+ existing = {}
66
+ if path.exist?
67
+ ui.warn "Reinitializing existing file: #{path}"
68
+ existing = EY::Config.load_config
69
+ end
70
+
71
+ template = EY::Templates::EyYml.new(existing)
72
+ template.write(path)
73
+
74
+ ui.info <<-GIT
75
+
76
+ Configuration generated: #{path}
77
+ Go look at it, then add it to your repository!
78
+
79
+ \tgit add #{path}
80
+ \tgit commit -m "Add generated #{path} from ey init"
81
+
82
+ GIT
83
+ end
84
+
85
+
43
86
  desc "deploy [--environment ENVIRONMENT] [--ref GIT-REF]",
44
87
  "Deploy specified branch, tag, or sha to specified environment."
45
88
  long_desc <<-DESC
@@ -57,7 +100,7 @@ module EY
57
100
  :desc => "Force a deploy even if the master is in a bad state"
58
101
  method_option :migrate, :type => :string, :aliases => %w(-m),
59
102
  :lazy_default => true,
60
- :desc => "Run migrations via [MIGRATE], defaults to '#{EY::DeployConfig::Migrate::DEFAULT}'; use --no-migrate to avoid running migrations"
103
+ :desc => "Run migrations via [MIGRATE]; use --no-migrate to avoid running migrations"
61
104
  method_option :ref, :type => :string, :aliases => %w(-r --branch --tag),
62
105
  :required => true, :default => '',
63
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."
@@ -272,6 +315,47 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
272
315
  end
273
316
  map "envs" => :environments
274
317
 
318
+ desc "servers", "List servers for an environment."
319
+ long_desc <<-DESC
320
+ Display a list of all servers on an environment.
321
+ Specify -s (--simple) to make parsing the output easier
322
+ or -uS (--user --host) to output bash loop friendly "user@hostname"
323
+ DESC
324
+
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
+ def servers
338
+ if options[:environment] == '' && options[:account] == ''
339
+ repo.fail_on_no_remotes!
340
+ end
341
+
342
+ environment = nil
343
+ ui.mute_if(options[:simple] || options[:host]) do
344
+ environment = fetch_environment(options[:environment], options[:account])
345
+ end
346
+
347
+ username = options[:user] && environment.username
348
+ servers = environment.instances
349
+
350
+ if options[:host]
351
+ ui.print_hostnames(servers, username)
352
+ elsif options[:simple]
353
+ ui.print_simple_servers(servers, username)
354
+ else
355
+ ui.print_servers(servers, environment.hierarchy_name, username)
356
+ end
357
+ end
358
+
275
359
  desc "rebuild [--environment ENVIRONMENT]", "Rebuild specified environment."
276
360
  long_desc <<-DESC
277
361
  Engine Yard's main configuration run occurs on all servers. Mainly used to fix
@@ -338,7 +422,9 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
338
422
  long_desc <<-DESC
339
423
  If a command is supplied, it will be run, otherwise a session will be
340
424
  opened. The application master is used for environments with clusters.
341
- Option --all requires a command to be supplied and runs it on all servers.
425
+
426
+ Option --all requires a command to be supplied and runs it on all servers or
427
+ pass --each to connect to each server one after another.
342
428
 
343
429
  Note: this command is a bit picky about its ordering. To run a command with arguments on
344
430
  all servers, like "rm -f /some/file", you need to order it like so:
@@ -365,22 +451,56 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
365
451
  :desc => "Run command on the utility servers with the given names. If no names are given, run on all utility servers."
366
452
  method_option :shell, :type => :string, :default => 'bash', :aliases => %w(-s),
367
453
  :desc => "Run command in a shell other than bash. Use --no-shell to run the command without a shell."
454
+ method_option :pty, :type => :boolean, :default => false, :aliases => %w(-t),
455
+ :desc => "If a command is given, run in a pty. Required for interactive commands like sudo."
456
+ method_option :bind_address, :type => :string, :aliases => %w(-L),
457
+ :desc => "When a command is not given, pass -L to the ssh command."
458
+ method_option :each, :type => :boolean, :default => false,
459
+ :desc => "If no command is given, connect to multiple servers each one after another, instead of exiting with an error."
368
460
 
369
461
  def ssh(cmd=nil)
370
462
  environment = fetch_environment(options[:environment], options[:account])
371
- hosts = ssh_hosts(options, environment)
463
+ instances = ssh_hosts(options, environment)
464
+ ssh_opts = []
465
+
466
+ if cmd
467
+ if options[:shell]
468
+ cmd = Escape.shell_command([options[:shell],'-lc',cmd])
469
+ end
372
470
 
373
- raise NoCommandError.new if cmd.nil? and hosts.size != 1
471
+ if options[:pty]
472
+ ssh_opts = ["-t"]
473
+ elsif cmd =~ /sudo/
474
+ ui.warn "sudo commands often need a tty to run correctly. Use -t option to spawn a tty."
475
+ end
476
+ else
477
+ if instances.size != 1 && options[:each] == false
478
+ raise NoCommandError.new
479
+ end
374
480
 
375
- if options[:shell] && cmd
376
- cmd = Escape.shell_command([options[:shell],'-lc',cmd])
481
+ if options[:bind_address]
482
+ ssh_opts = ["-L", options[:bind_address]]
483
+ end
377
484
  end
378
485
 
379
- exits = hosts.map do |host|
380
- system Escape.shell_command(['ssh', "#{environment.username}@#{host}", cmd].compact)
486
+ ssh_cmd = ["ssh"]
487
+ ssh_cmd += ssh_opts
488
+
489
+ trap(:INT) { abort "Aborting..." }
490
+
491
+ exits = instances.map do |instance|
492
+ host = instance.public_hostname
493
+ name = instance.name ? "#{instance.role} (#{instance.name})" : instance.role
494
+ ui.info "\nConnecting to #{name} #{host}..."
495
+ unless cmd
496
+ ui.info "Ctrl + C to abort"
497
+ sleep 1.3
498
+ end
499
+ system Escape.shell_command((ssh_cmd + ["#{environment.username}@#{host}"] + [cmd]).compact)
381
500
  $?.exitstatus
382
501
  end
383
- exit exits.detect {|status| !status.zero?} || 0
502
+
503
+ exit exits.detect {|status| status != 0 } || 0
384
504
  end
385
505
 
386
506
  no_tasks do
@@ -407,7 +527,7 @@ WARNING: Interrupting again may prevent Engine Yard Cloud from recording this
407
527
 
408
528
  instances = environment.instances.select {|instance| filter[instance] }
409
529
  raise NoInstancesError.new(environment.name) if instances.empty?
410
- return instances.map { |instance| instance.public_hostname }
530
+ return instances
411
531
  end
412
532
  end
413
533
 
@@ -128,6 +128,48 @@ module EY
128
128
  return ''
129
129
  end
130
130
 
131
+ def mute_if(bool, &block)
132
+ bool ? mute(&block) : yield
133
+ end
134
+
135
+ def server_tuples(servers, username=nil)
136
+ user = username && "#{username}@"
137
+
138
+ servers.map do |server|
139
+ host = "#{user}#{server.hostname}"
140
+ [host, server.amazon_id, server.role, server.name]
141
+ end
142
+ end
143
+ private :server_tuples
144
+
145
+ def print_hostnames(servers, username=nil)
146
+ server_tuples(servers, username).each do |server_tuple|
147
+ puts server_tuple.first
148
+ end
149
+ end
150
+
151
+ def print_simple_servers(servers, username=nil)
152
+ server_tuples(servers, username).each do |server_tuple|
153
+ puts server_tuple.join("\t")
154
+ end
155
+ end
156
+
157
+ def print_servers(servers, name, username=nil)
158
+ tuples = server_tuples(servers, username)
159
+ count = tuples.size
160
+ puts "# #{count} server#{count == 1 ? '' : 's'} on #{name}"
161
+
162
+ host_width = tuples.map {|s| s[0].length }.max
163
+ host_format = "%-#{host_width}s" # "%-10s" left align
164
+
165
+ role_width = tuples.map {|s| s[2].length }.max
166
+ role_format = "%-#{role_width}s" # "%-10s" left align
167
+
168
+ tuples.each do |server_tuple|
169
+ puts "#{host_format}\t%s\t#{role_format}\t%s" % server_tuple
170
+ end
171
+ end
172
+
131
173
  def print_simple_envs(envs)
132
174
  puts envs.map{|env| env.name }.uniq.sort
133
175
  end
@@ -5,19 +5,37 @@ require 'engineyard/error'
5
5
 
6
6
  module EY
7
7
  class Config
8
+ # This order is important.
8
9
  CONFIG_FILES = ["config/ey.yml", "ey.yml"].map {|path| Pathname.new(path)}.freeze
10
+ TEMPLATE_PATHNAME = Pathname.new(__FILE__).dirname.join('templates','ey.yml').freeze
9
11
 
10
- attr_reader :path
12
+ def self.pathname_for_write
13
+ pathname || CONFIG_FILES.find{|pathname| pathname.dirname.exist? }
14
+ end
11
15
 
12
- def initialize(file = nil)
13
- @path = file ? Pathname.new(file) : CONFIG_FILES.find{|pathname| pathname.exist? }
14
- @config = @path ? YAML.load_file(@path.to_s) : {}
15
- @config ||= {} # load_file returns `false' when the file is empty
16
+ def self.pathname
17
+ CONFIG_FILES.find{|pathname| pathname.exist? }
18
+ end
19
+
20
+ def self.template_pathname
21
+ TEMPLATE_PATHNAME
22
+ end
16
23
 
17
- unless Hash === @config
18
- raise "ey.yml load error: Expected a Hash but a #{@config.class.name} was returned."
24
+ def self.load_config(path = pathname)
25
+ config = YAML.load_file(path.to_s) if path && path.exist?
26
+ config ||= {} # load_file returns `false' when the file is empty
27
+
28
+ unless Hash === config
29
+ raise "ey.yml load error: Expected a Hash but a #{config.class.name} was returned."
19
30
  end
31
+ config
32
+ end
20
33
 
34
+ attr_reader :path
35
+
36
+ def initialize(file = nil)
37
+ @path = file ? Pathname.new(file) : self.class.pathname
38
+ @config = self.class.load_config(@path)
21
39
  @config["environments"] ||= {}
22
40
  end
23
41
 
@@ -79,76 +97,6 @@ module EY
79
97
  EnvironmentConfig.new(environments[environment_name], environment_name, self)
80
98
  end
81
99
 
82
- def set_environment_option(environment_name, key, value)
83
- environments[environment_name] ||= {}
84
- environments[environment_name][key] = value
85
- write_ey_yaml
86
- end
87
-
88
- def write_ey_yaml
89
- ensure_path
90
- comments = ey_yml_comments
91
- @path.open('w') do |f|
92
- f.puts comments
93
- f.puts YAML.dump(@config)
94
- end
95
- end
96
-
97
- def set_default_option(key, value)
98
- defaults[key] = value
99
- write_ey_yaml
100
- end
101
-
102
- EY_YML_HINTS = <<-HINTS
103
- # ey.yml supports many deploy configuration options when committed in an
104
- # application's repository.
105
- #
106
- # Valid locations: REPO_ROOT/ey.yml or REPO_ROOT/config/ey.yml.
107
- #
108
- # Examples options (defaults apply to all environments for this application):
109
- #
110
- # defaults:
111
- # migrate: true # Default --migrate choice for ey deploy
112
- # migration_command: 'rake migrate' # Default migrate command to run when migrations are enabled
113
- # branch: default_deploy_branch # Branch/ref to be deployed by default during ey deploy
114
- # bundle_without: development test # The string to pass to bundle install --without ''
115
- # maintenance_on_migrate: true # Enable maintenance page during migrate action (use with caution) (default: true)
116
- # maintenance_on_restart: false # Enable maintanence page during every deploy (default: false for unicorn & passenger)
117
- # ignore_database_adapter_warning: false # Hide the warning shown when the Gemfile does not contain a recognized database adapter (mongodb for example)
118
- # your_own_custom_key: 'any attribute you put in ey.yml is available in deploy hooks'
119
- # environments:
120
- # YOUR_ENVIRONMENT_NAME: # All options pertain only to the named environment
121
- # any_option: 'override any of the options above with specific options for certain environments'
122
- # migrate: false
123
- #
124
- # Further information available here:
125
- # https://support.cloud.engineyard.com/entries/20996661-customize-your-deployment-on-engine-yard-cloud
126
- #
127
- # NOTE: Please commit this file into your git repository.
128
- #
129
- HINTS
130
-
131
- def ey_yml_comments
132
- if @path.exist?
133
- existing = @path.readlines.grep(/^#/).map {|line| line.strip }.join("\n")
134
- else
135
- EY_YML_HINTS
136
- end
137
- end
138
-
139
- def ensure_path
140
- return if @path && @path.exist?
141
- unless EY::Repo.exist?
142
- raise "Not in application directory. Unable to save configuration."
143
- end
144
- if Pathname.new('config').exist?
145
- @path = Pathname.new('config/ey.yml')
146
- else
147
- @path = Pathname.new('ey.yml')
148
- end
149
- @path
150
- end
151
-
152
100
  class EnvironmentConfig
153
101
  attr_reader :name
154
102
 
@@ -162,28 +110,16 @@ module EY
162
110
  @parent.path
163
111
  end
164
112
 
165
- def fetch(key, default = nil, &block)
166
- @config.fetch(key.to_s) do
167
- @parent.fetch_from_defaults(key.to_s, default, &block)
113
+ def ensure_exists
114
+ unless path && path.exist?
115
+ raise EY::Error, "Please initialize this application with the following command:\n\tey init"
168
116
  end
169
117
  end
170
118
 
171
- def set(key, val)
172
- if @config.empty? || !@config.has_key?(key.to_s)
173
- @parent.set_default_option(key, val)
174
- else
175
- @config[key.to_s] = val
176
- @parent.set_environment_option(@name, key, val)
119
+ def fetch(key, default = nil, &block)
120
+ @config.fetch(key.to_s) do
121
+ @parent.fetch_from_defaults(key.to_s, default, &block)
177
122
  end
178
- val
179
- end
180
-
181
- def merge(other)
182
- to_clean_hash.merge(other)
183
- end
184
-
185
- def to_clean_hash
186
- @config.reject { |k,v| %w[branch migrate migration_command verbose].include?(k) }
187
123
  end
188
124
 
189
125
  def branch
@@ -191,22 +127,20 @@ module EY
191
127
  end
192
128
 
193
129
  def migrate
194
- fetch('migrate')
195
- end
196
-
197
- def migrate=(mig)
198
- set('migrate', mig)
130
+ ensure_exists
131
+ fetch('migrate') do
132
+ raise EY::Error, "'migrate' not found in #{path}. Reinitialize with:\n\tey init"
133
+ end
199
134
  end
200
135
 
201
136
  def migration_command
202
- fetch('migration_command', nil)
137
+ ensure_exists
138
+ fetch('migration_command') do
139
+ raise EY::Error, "'migration_command' not found in #{path}. Reinitialize with:\n\tey init"
140
+ end
203
141
  end
204
142
 
205
- def migration_command=(cmd)
206
- set('migration_command', cmd)
207
- end
208
143
  alias migrate_command migration_command
209
- alias migrate_command= migration_command=
210
144
 
211
145
  def verbose
212
146
  fetch('verbose', false)