engineyard-serverside 1.5.35.pre.2 → 1.6.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/lib/engineyard-serverside.rb +3 -1
  2. data/lib/engineyard-serverside/cli.rb +73 -38
  3. data/lib/engineyard-serverside/configuration.rb +38 -12
  4. data/lib/engineyard-serverside/deploy.rb +63 -51
  5. data/lib/engineyard-serverside/deploy_hook.rb +21 -18
  6. data/lib/engineyard-serverside/deprecation.rb +9 -17
  7. data/lib/engineyard-serverside/lockfile_parser.rb +1 -1
  8. data/lib/engineyard-serverside/rails_asset_support.rb +5 -5
  9. data/lib/engineyard-serverside/server.rb +8 -11
  10. data/lib/engineyard-serverside/shell.rb +101 -0
  11. data/lib/engineyard-serverside/shell/formatter.rb +70 -0
  12. data/lib/engineyard-serverside/shell/helpers.rb +29 -0
  13. data/lib/engineyard-serverside/strategies/git.rb +12 -15
  14. data/lib/engineyard-serverside/task.rb +28 -5
  15. data/lib/engineyard-serverside/version.rb +1 -1
  16. data/lib/vendor/open4/lib/open4.rb +432 -0
  17. data/spec/basic_deploy_spec.rb +9 -9
  18. data/spec/bundler_deploy_spec.rb +1 -1
  19. data/spec/custom_deploy_spec.rb +45 -4
  20. data/spec/deploy_hook_spec.rb +77 -78
  21. data/spec/deprecation_spec.rb +4 -26
  22. data/spec/git_strategy_spec.rb +6 -2
  23. data/spec/nodejs_deploy_spec.rb +2 -2
  24. data/spec/services_deploy_spec.rb +11 -10
  25. data/spec/shell_spec.rb +48 -0
  26. data/spec/spec_helper.rb +48 -25
  27. data/spec/sqlite3_deploy_spec.rb +1 -2
  28. data/spec/support/integration.rb +1 -13
  29. metadata +57 -97
  30. data/lib/engineyard-serverside/logged_output.rb +0 -91
  31. data/lib/vendor/systemu/LICENSE +0 -3
  32. data/lib/vendor/systemu/lib/systemu.rb +0 -363
  33. data/lib/vendor/systemu/systemu.gemspec +0 -45
  34. data/spec/fixtures/gitrepo/bar +0 -0
  35. data/spec/logged_output_spec.rb +0 -55
@@ -8,7 +8,7 @@ else
8
8
  end
9
9
 
10
10
  $LOAD_PATH.unshift File.expand_path('vendor/thor/lib', File.dirname(__FILE__))
11
- $LOAD_PATH.unshift File.expand_path('vendor/systemu/lib', File.dirname(__FILE__))
11
+ $LOAD_PATH.unshift File.expand_path('vendor/open4/lib', File.dirname(__FILE__))
12
12
  $LOAD_PATH.unshift File.expand_path('vendor/escape/lib', File.dirname(__FILE__))
13
13
  $LOAD_PATH.unshift File.expand_path('vendor/json_pure/lib', File.dirname(__FILE__))
14
14
 
@@ -26,6 +26,8 @@ require 'engineyard-serverside/cli'
26
26
  require 'engineyard-serverside/configuration'
27
27
  require 'engineyard-serverside/deprecation'
28
28
  require 'engineyard-serverside/future'
29
+ require 'engineyard-serverside/shell'
30
+
29
31
 
30
32
  module EY
31
33
  module Serverside
@@ -1,5 +1,8 @@
1
1
  require 'thor'
2
2
  require 'pathname'
3
+ require 'engineyard-serverside/deploy'
4
+ require 'engineyard-serverside/shell'
5
+ require 'engineyard-serverside/server'
3
6
 
4
7
  module EY
5
8
  module Serverside
@@ -22,6 +25,14 @@ module EY
22
25
  :desc => "Application to deploy",
23
26
  :aliases => ["-a"]
24
27
 
28
+ method_option :environment_name,:type => :string,
29
+ :required => true,
30
+ :desc => "Environment name"
31
+
32
+ method_option :account_name, :type => :string,
33
+ :required => true,
34
+ :desc => "Account name"
35
+
25
36
  method_option :framework_env, :type => :string,
26
37
  :desc => "Ruby web framework environment",
27
38
  :aliases => ["-e"]
@@ -44,21 +55,13 @@ module EY
44
55
  :desc => "Instance names, keyed on hostname. e.g. instance1:name1 instance2:name2"
45
56
 
46
57
  method_option :verbose, :type => :boolean,
47
- :default => false,
48
58
  :desc => "Verbose output",
49
59
  :aliases => ["-v"]
50
60
 
51
61
  desc "deploy", "Deploy code from /data/<app>"
52
62
  def deploy(default_task=:deploy)
53
- config = EY::Serverside::Deploy::Configuration.new(options)
54
- load_servers(config)
55
-
56
- EY::Serverside::LoggedOutput.verbose = options[:verbose]
57
- EY::Serverside::LoggedOutput.logfile = File.join(ENV['HOME'], "#{options[:app]}-deploy.log")
58
-
59
- invoke :propagate
60
-
61
- EY::Serverside::Deploy.new(config).send(default_task)
63
+ config, shell = init_and_propagate(options, 'deploy')
64
+ EY::Serverside::Deploy.new(config, shell).send(default_task)
62
65
  end
63
66
 
64
67
  method_option :app, :type => :string,
@@ -66,6 +69,14 @@ module EY
66
69
  :desc => "Which application's hooks to run",
67
70
  :aliases => ["-a"]
68
71
 
72
+ method_option :environment_name, :type => :string,
73
+ :required => true,
74
+ :desc => "Environment name"
75
+
76
+ method_option :account_name, :type => :string,
77
+ :required => true,
78
+ :desc => "Account name"
79
+
69
80
  method_option :release_path, :type => :string,
70
81
  :desc => "Value for #release_path in hooks (mostly for internal coordination)",
71
82
  :aliases => ["-r"]
@@ -84,9 +95,14 @@ module EY
84
95
  method_option :current_name, :type => :string,
85
96
  :desc => "Value for #current_name in hooks"
86
97
 
98
+ method_option :verbose, :type => :boolean,
99
+ :desc => "Verbose output",
100
+ :aliases => ["-v"]
101
+
87
102
  desc "hook [NAME]", "Run a particular deploy hook"
88
103
  def hook(hook_name)
89
- EY::Serverside::DeployHook.new(options).run(hook_name)
104
+ config, shell = init(options, "hook-#{hook_name}")
105
+ EY::Serverside::DeployHook.new(config, shell).run(hook_name)
90
106
  end
91
107
 
92
108
 
@@ -95,6 +111,14 @@ module EY
95
111
  :desc => "Application to deploy",
96
112
  :aliases => ["-a"]
97
113
 
114
+ method_option :environment_name,:type => :string,
115
+ :required => true,
116
+ :desc => "Environment name"
117
+
118
+ method_option :account_name, :type => :string,
119
+ :required => true,
120
+ :desc => "Account name"
121
+
98
122
  method_option :framework_env, :type => :string,
99
123
  :required => true,
100
124
  :desc => "Ruby web framework environment",
@@ -115,13 +139,10 @@ module EY
115
139
  :desc => "Instance names, keyed on hostname. e.g. instance1:name1 instance2:name2"
116
140
 
117
141
  method_option :verbose, :type => :boolean,
118
- :default => false,
119
142
  :desc => "Verbose output",
120
143
  :aliases => ["-v"]
121
144
  desc "integrate", "Integrate other instances into this cluster"
122
145
  def integrate
123
- EY::Serverside::LoggedOutput.verbose = options[:verbose]
124
- EY::Serverside::LoggedOutput.logfile = File.join(ENV['HOME'], "#{options[:app]}-integrate.log")
125
146
 
126
147
  app_dir = Pathname.new "/data/#{options[:app]}"
127
148
  current_app_dir = app_dir + "current"
@@ -133,23 +154,19 @@ module EY
133
154
  # we have to deploy the same SHA there as here
134
155
  integrate_options[:branch] = (current_app_dir + 'REVISION').read.strip
135
156
 
136
- config = EY::Serverside::Deploy::Configuration.new(integrate_options)
137
-
138
- load_servers(config)
139
-
140
- invoke :propagate
157
+ config, shell = init_and_propagate(integrate_options, 'integrate')
141
158
 
142
159
  EY::Serverside::Server.all.each do |server|
143
- server.sync_directory app_dir
160
+ server.sync_directory(app_dir) { |cmd| shell.logged_system(cmd) }
144
161
  # we're just about to recreate this, so it has to be gone
145
162
  # first. otherwise, non-idempotent deploy hooks could screw
146
163
  # things up, and since we don't control deploy hooks, we must
147
164
  # assume the worst.
148
- server.run("rm -rf #{current_app_dir}")
165
+ run_on_server(server,"rm -rf #{current_app_dir}")
149
166
  end
150
167
 
151
168
  # deploy local-ref to other instances into /data/$app/local-current
152
- EY::Serverside::Deploy.new(config).cached_deploy
169
+ EY::Serverside::Deploy.new(config, shell).cached_deploy
153
170
  end
154
171
 
155
172
  method_option :app, :type => :string,
@@ -157,6 +174,14 @@ module EY
157
174
  :desc => "Application to deploy",
158
175
  :aliases => ["-a"]
159
176
 
177
+ method_option :environment_name,:type => :string,
178
+ :required => true,
179
+ :desc => "Environment name"
180
+
181
+ method_option :account_name, :type => :string,
182
+ :required => true,
183
+ :desc => "Account name"
184
+
160
185
  method_option :stack, :type => :string,
161
186
  :desc => "Web stack (so we can restart it correctly)"
162
187
 
@@ -172,20 +197,13 @@ module EY
172
197
  :desc => "Instance names, keyed on hostname. e.g. instance1:name1 instance2:name2"
173
198
 
174
199
  method_option :verbose, :type => :boolean,
175
- :default => false,
176
200
  :desc => "Verbose output",
177
201
  :aliases => ["-v"]
178
202
  desc "restart", "Restart app servers, conditionally enabling maintenance page"
179
203
  def restart
180
- EY::Serverside::LoggedOutput.verbose = options[:verbose]
181
- EY::Serverside::LoggedOutput.logfile = File.join(ENV['HOME'], "#{options[:app]}-restart.log")
204
+ config, shell = init_and_propagate(options, 'restart')
182
205
 
183
- config = EY::Serverside::Deploy::Configuration.new(options)
184
- load_servers(config)
185
-
186
- invoke :propagate
187
-
188
- EY::Serverside::Deploy.new(config).restart_with_maintenance_page
206
+ EY::Serverside::Deploy.new(config, shell).restart_with_maintenance_page
189
207
  end
190
208
 
191
209
  desc "install_bundler [VERSION]", "Make sure VERSION of bundler is installed (in system ruby)"
@@ -203,8 +221,10 @@ module EY
203
221
  end
204
222
  end
205
223
 
206
- desc "propagate", "Propagate the engineyard-serverside gem to the other instances in the cluster. This will install exactly version #{EY::Serverside::VERSION}."
207
- def propagate
224
+ private
225
+
226
+ # Put the same engineyard-serverside on all the servers (Used to be public but is unused as an actual CLI command now)
227
+ def propagate(shell)
208
228
  config = EY::Serverside::Deploy::Configuration.new
209
229
  gem_filename = "engineyard-serverside-#{EY::Serverside::VERSION}.gem"
210
230
  local_gem_file = File.join(Gem.dir, 'cache', gem_filename)
@@ -219,23 +239,38 @@ module EY
219
239
  # 0.5.11, and mistakenly thinking 0.5.1 is there
220
240
  has_gem_cmd = "#{gem_binary} list engineyard-serverside | grep \"engineyard-serverside\" | egrep -q '#{egrep_escaped_version}[,)]'"
221
241
 
222
- if !server.run(has_gem_cmd) # doesn't have this exact version
223
- puts "~> Installing engineyard-serverside on #{server.hostname}"
242
+ if !run_on_server(server,has_gem_cmd) # doesn't have this exact version
243
+ shell.status "Installing engineyard-serverside on #{server.hostname}"
224
244
 
225
- system(Escape.shell_command([
245
+ shell.logged_system(Escape.shell_command([
226
246
  'scp', '-i', "#{ENV['HOME']}/.ssh/internal",
227
247
  "-o", "StrictHostKeyChecking=no",
228
248
  local_gem_file,
229
249
  "#{config.user}@#{server.hostname}:#{remote_gem_file}",
230
250
  ]))
231
- server.run("sudo #{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'")
251
+ run_on_server(server,"sudo #{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'")
232
252
  end
233
253
  end
234
254
 
235
255
  EY::Serverside::Future.success?(futures)
236
256
  end
237
257
 
238
- private
258
+ def init_and_propagate(*args)
259
+ config, shell = init(*args)
260
+ load_servers(config)
261
+ propagate(shell)
262
+ [config, shell]
263
+ end
264
+
265
+ def init(options, action)
266
+ config = EY::Serverside::Deploy::Configuration.new(options)
267
+ shell = EY::Serverside::Shell.new(:verbose => config.verbose, :log_path => File.join(ENV['HOME'], "#{config.app}-#{action}.log"))
268
+ [config, shell]
269
+ end
270
+
271
+ def run_on_server(server, command)
272
+ server.run(command) { |cmd| shell.logged_system(cmd) }
273
+ end
239
274
 
240
275
  def load_servers(config)
241
276
  EY::Serverside::Server.load_all_from_array(assemble_instance_hashes(config))
@@ -10,41 +10,50 @@ module EY
10
10
  "bundle_without" => "test development",
11
11
  })
12
12
 
13
- attr_reader :configuration
14
- alias :c :configuration
15
-
16
13
  attr_writer :release_path
17
14
 
18
15
  def initialize(options={})
19
16
  opts = options.dup
20
17
  @release_path = opts[:release_path]
21
18
  config = JSON.parse(opts.delete("config") || "{}")
22
- @configuration = DEFAULT_CONFIG.merge(config).merge(opts)
19
+ @configs = [config, opts] # low to high priority
20
+ end
21
+
22
+ def configuration
23
+ @configuration ||= @configs.inject(DEFAULT_CONFIG) {|low,high| low.merge(high)}
23
24
  end
25
+ alias :c :configuration # FIXME: awful, but someone is probably using it :(
24
26
 
25
27
  # Delegate to the configuration objects
26
28
  def method_missing(meth, *args, &blk)
27
- c.key?(meth.to_s) ? c[meth.to_s] : super
29
+ configuration.key?(meth.to_s) ? c[meth.to_s] : super
28
30
  end
29
31
 
30
32
  def respond_to?(meth, include_private=false)
31
- c.key?(meth.to_s) ? true : super
33
+ configuration.key?(meth.to_s) ? true : super
34
+ end
35
+
36
+ def ey_yml_data=(data)
37
+ environments = data['environments']
38
+ if environments && (env_data = environments[environment_name])
39
+ @configuration = nil # reset cached configuration hash
40
+ @configs.unshift(env_data) # insert just above default configuration
41
+ true
42
+ else
43
+ false
44
+ end
32
45
  end
33
46
 
34
47
  def [](key)
35
48
  if respond_to?(key.to_sym)
36
49
  send(key.to_sym)
37
50
  else
38
- c[key]
51
+ configuration[key]
39
52
  end
40
53
  end
41
54
 
42
55
  def has_key?(key)
43
- if respond_to?(key.to_sym)
44
- true
45
- else
46
- c.has_key?(key)
47
- end
56
+ respond_to?(key.to_sym) || configuration.has_key?(key)
48
57
  end
49
58
 
50
59
  def to_json
@@ -55,9 +64,22 @@ module EY
55
64
  EY::Serverside.node
56
65
  end
57
66
 
67
+ def verbose
68
+ configuration['verbose']
69
+ end
70
+
58
71
  def app
59
72
  configuration['app'].to_s
60
73
  end
74
+ alias app_name app
75
+
76
+ def environment_name
77
+ configuration['environment_name'].to_s
78
+ end
79
+
80
+ def account_name
81
+ configuration['account_name'].to_s
82
+ end
61
83
 
62
84
  def revision
63
85
  IO.read(File.join(latest_release, 'REVISION'))
@@ -95,6 +117,10 @@ module EY
95
117
  node['instance_role']
96
118
  end
97
119
 
120
+ def current_roles
121
+ configuration['current_roles'] || []
122
+ end
123
+
98
124
  def current_role
99
125
  current_roles.first
100
126
  end
@@ -7,22 +7,22 @@ require 'engineyard-serverside/rails_asset_support'
7
7
  module EY
8
8
  module Serverside
9
9
  class DeployBase < Task
10
- include LoggedOutput
11
10
  include ::EY::Serverside::RailsAssetSupport
12
11
 
13
12
  # default task
14
13
  def deploy
15
- debug "Starting deploy at #{Time.now.asctime}"
14
+ shell.status "Starting deploy at #{shell.start_time.asctime}"
16
15
  update_repository_cache
17
16
  cached_deploy
18
17
  end
19
18
 
20
19
  def cached_deploy
21
- debug "Deploying app from cached copy at #{Time.now.asctime}"
20
+ shell.status "Deploying app from cached copy at #{Time.now.asctime}"
22
21
  require_custom_tasks
22
+ load_ey_yml
23
23
  push_code
24
24
 
25
- info "~> Starting full deploy"
25
+ shell.status "Starting full deploy"
26
26
  copy_repository_cache
27
27
  check_repository
28
28
 
@@ -47,9 +47,9 @@ module EY
47
47
  disable_maintenance_page
48
48
 
49
49
  cleanup_old_releases
50
- debug "Finished deploy at #{Time.now.asctime}"
50
+ shell.status "Finished deploy at #{Time.now.asctime}"
51
51
  rescue Exception
52
- debug "Finished failing to deploy at #{Time.now.asctime}"
52
+ shell.status "Finished failing to deploy at #{Time.now.asctime}"
53
53
  puts_deploy_failure
54
54
  raise
55
55
  end
@@ -73,9 +73,9 @@ module EY
73
73
 
74
74
  def check_repository
75
75
  if gemfile?
76
- info "~> Gemfile found."
76
+ shell.status "Gemfile found."
77
77
  if lockfile
78
- info "~> Gemfile.lock found."
78
+ shell.status "Gemfile.lock found."
79
79
  unless lockfile.any_database_adapter?
80
80
  warning <<-WARN
81
81
  Gemfile.lock does not contain a recognized database adapter.
@@ -97,7 +97,7 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
97
97
  WARN
98
98
  end
99
99
  else
100
- info "~> No Gemfile. Deploying without bundler support."
100
+ shell.status "No Gemfile. Deploying without bundler support."
101
101
  end
102
102
  end
103
103
 
@@ -163,9 +163,9 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
163
163
 
164
164
  # task
165
165
  def push_code
166
- info "~> Pushing code to all servers"
166
+ shell.status "Pushing code to all servers"
167
167
  futures = EY::Serverside::Future.call(EY::Serverside::Server.all) do |server|
168
- server.sync_directory(config.repository_cache)
168
+ server.sync_directory(config.repository_cache) { |cmd| shell.logged_system(cmd) }
169
169
  end
170
170
  EY::Serverside::Future.success?(futures)
171
171
  end
@@ -173,7 +173,7 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
173
173
  # task
174
174
  def restart
175
175
  @restart_failed = true
176
- info "~> Restarting app servers"
176
+ shell.status "Restarting app servers"
177
177
  roles :app_master, :app, :solo do
178
178
  run(restart_command)
179
179
  end
@@ -191,12 +191,8 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
191
191
 
192
192
  # If we don't have a local version of the ssh wrapper script yet,
193
193
  # create it on all the servers that will need it.
194
- # TODO - This logic likely fails when people change deploy keys.
195
194
  def ssh_executable
196
- roles :app_master, :app, :solo, :util do
197
- run(generate_ssh_wrapper)
198
- end
199
- ssh_wrapper_path
195
+ @path ||= generate_ssh_wrapper
200
196
  end
201
197
 
202
198
  # We specify 'IdentitiesOnly' to avoid failures on systems with > 5 private keys available.
@@ -205,12 +201,17 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
205
201
  # Learned this at http://lists.mindrot.org/pipermail/openssh-unix-dev/2009-February/027271.html
206
202
  # (Thanks Jim L.)
207
203
  def generate_ssh_wrapper
204
+ path = ssh_wrapper_path
208
205
  identity_file = "~/.ssh/#{c.app}-deploy-key"
209
- %{ echo "#{wrapper_for(identity_file)}" > #{ssh_wrapper_path} && chmod 0700 #{ssh_wrapper_path} }
210
- end
211
-
212
- def wrapper_for(identity)
213
- "#!/bin/sh\nunset SSH_AUTH_SOCK; ssh -o CheckHostIP=no -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o LogLevel=DEBUG -o IdentityFile=#{identity} -o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null $*"
206
+ run <<-SCRIPT
207
+ [[ -x #{path} ]] || cat > #{path} <<'SSH'
208
+ #!/bin/sh
209
+ unset SSH_AUTH_SOCK
210
+ ssh -o 'CheckHostIP no' -o 'StrictHostKeyChecking no' -o 'PasswordAuthentication no' -o 'LogLevel DEBUG' -o 'IdentityFile #{identity_file}' -o 'IdentitiesOnly yes' -o 'UserKnownHostsFile /dev/null' $*
211
+ SSH
212
+ chmod 0700 #{path}
213
+ SCRIPT
214
+ path
214
215
  end
215
216
 
216
217
  def ssh_wrapper_path
@@ -238,7 +239,7 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
238
239
  def clean_release_directory(dir, count = 3)
239
240
  @cleanup_failed = true
240
241
  ordinal = count.succ.to_s
241
- info "~> Cleaning release directory: #{dir}"
242
+ shell.status "Cleaning release directory: #{dir}"
242
243
  sudo "ls -r #{dir} | tail -n +#{ordinal} | xargs -I@ rm -rf #{dir}/@"
243
244
  @cleanup_failed = false
244
245
  end
@@ -250,15 +251,15 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
250
251
  c.release_path = c.previous_release(rolled_back_release)
251
252
 
252
253
  revision = File.read(File.join(c.release_path, 'REVISION')).strip
253
- info "~> Rolling back to previous release: #{short_log_message(revision)}"
254
+ shell.status "Rolling back to previous release: #{short_log_message(revision)}"
254
255
 
255
256
  run_with_callbacks(:symlink)
256
257
  sudo "rm -rf #{rolled_back_release}"
257
258
  bundle
258
- info "~> Restarting with previous release."
259
+ shell.status "Restarting with previous release."
259
260
  with_maintenance_page { run_with_callbacks(:restart) }
260
261
  else
261
- info "~> Already at oldest release, nothing to roll back to."
262
+ shell.status "Already at oldest release, nothing to roll back to."
262
263
  exit(1)
263
264
  end
264
265
  end
@@ -269,17 +270,17 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
269
270
  @migrations_reached = true
270
271
  roles :app_master, :solo do
271
272
  cmd = "cd #{c.release_path} && PATH=#{c.binstubs_path}:$PATH #{c.framework_envs} #{c.migration_command}"
272
- info "~> Migrating: #{cmd}"
273
+ shell.status "Migrating: #{cmd}"
273
274
  run(cmd)
274
275
  end
275
276
  end
276
277
 
277
278
  # task
278
279
  def copy_repository_cache
279
- info "~> Copying to #{c.release_path}"
280
+ shell.status "Copying to #{c.release_path}"
280
281
  run("mkdir -p #{c.release_path} #{c.failed_release_dir} && rsync -aq #{c.exclusions} #{c.repository_cache}/ #{c.release_path}")
281
282
 
282
- info "~> Ensuring proper ownership."
283
+ shell.status "Ensuring proper ownership."
283
284
  sudo("chown -R #{c.user}:#{c.group} #{c.deploy_to}")
284
285
  end
285
286
 
@@ -295,8 +296,12 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
295
296
  "/usr/local/ey_resin/ruby/bin/ey-services-setup #{config.app}"
296
297
  end
297
298
 
299
+ def node_package_manager_command_check
300
+ "which npm"
301
+ end
302
+
298
303
  def setup_services
299
- info "~> Setting up external services."
304
+ shell.status "Setting up external services."
300
305
  previously_configured_services = parse_configured_services
301
306
  begin
302
307
  sudo(services_command_check)
@@ -332,24 +337,24 @@ YML
332
337
  WRAP
333
338
  ["Symlink database.yml", "ln -nfs #{c.shared_path}/config/database.sqlite3.yml #{c.release_path}/config/database.yml"],
334
339
  ].each do |what, cmd|
335
- info "~> #{what}"
340
+ shell.status "#{what}"
336
341
  run(cmd)
337
342
  end
338
343
 
339
344
  owner = [c.user, c.group].join(':')
340
- info "~> Setting ownership to #{owner}"
345
+ shell.status "Setting ownership to #{owner}"
341
346
  sudo "chown -R #{owner} #{c.release_path}"
342
347
  end
343
348
  end
344
349
 
345
350
  def symlink_configs(release_to_link=c.release_path)
346
- info "~> Preparing shared resources for release."
351
+ shell.status "Preparing shared resources for release."
347
352
  symlink_tasks(release_to_link).each do |what, cmd|
348
- info "~> #{what}"
353
+ shell.substatus what
349
354
  run(cmd)
350
355
  end
351
356
  owner = [c.user, c.group].join(':')
352
- info "~> Setting ownership to #{owner}"
357
+ shell.status "Setting ownership to #{owner}"
353
358
  sudo "chown -R #{owner} #{release_to_link}"
354
359
  end
355
360
 
@@ -372,7 +377,7 @@ WRAP
372
377
 
373
378
  # task
374
379
  def symlink(release_to_link=c.release_path)
375
- info "~> Symlinking code."
380
+ shell.status "Symlinking code."
376
381
  run "rm -f #{c.current_path} && ln -nfs #{release_to_link} #{c.current_path} && chown -R #{c.user}:#{c.group} #{c.current_path}"
377
382
  @symlink_changed = true
378
383
  rescue Exception
@@ -382,7 +387,7 @@ WRAP
382
387
  end
383
388
 
384
389
  def callback(what)
385
- @callbacks_reached = true
390
+ @callbacks_reached ||= true
386
391
  if File.exist?("#{c.release_path}/deploy/#{what}.rb")
387
392
  run Escape.shell_command(base_callback_command_for(what)) do |server, cmd|
388
393
  per_instance_args = [
@@ -406,11 +411,14 @@ WRAP
406
411
  end
407
412
 
408
413
  def base_callback_command_for(what)
409
- [serverside_bin, 'hook', what.to_s,
410
- '--app', config.app,
411
- '--release-path', config.release_path.to_s,
412
- '--framework-env', c.environment.to_s,
413
- ].compact
414
+ cmd = [serverside_bin, 'hook', what.to_s]
415
+ cmd << '--app' << config.app
416
+ cmd << '--environment-name' << config.environment_name
417
+ cmd << '--account-name' << config.account_name
418
+ cmd << '--release-path' << config.release_path.to_s
419
+ cmd << '--framework-env' << config.environment.to_s
420
+ cmd << '--verbose' if config.verbose
421
+ cmd
414
422
  end
415
423
 
416
424
  def serverside_bin
@@ -420,9 +428,9 @@ WRAP
420
428
 
421
429
  def puts_deploy_failure
422
430
  if @cleanup_failed
423
- info "~> [Relax] Your site is running new code, but clean up of old deploys failed."
431
+ shell.status "[Relax] Your site is running new code, but clean up of old deploys failed."
424
432
  elsif @maintenance_up
425
- info "~> [Attention] Maintenance page still up, consider the following before removing:"
433
+ shell.status "[Attention] Maintenance page still up, consider the following before removing:"
426
434
  info " * Deploy hooks ran. This might cause problems for reverting to old code." if @callbacks_reached
427
435
  info " * Migrations ran. This might cause problems for reverting to old code." if @migrations_reached
428
436
  if @symlink_changed
@@ -432,9 +440,9 @@ WRAP
432
440
  end
433
441
  info " * Application servers failed to restart." if @restart_failed
434
442
  info ""
435
- info "~> Need help? File a ticket for support."
443
+ shell.status "Need help? File a ticket for support."
436
444
  else
437
- info "~> [Relax] Your site is still running old code and nothing destructive has occurred."
445
+ shell.status "[Relax] Your site is still running old code and nothing destructive has occurred."
438
446
  end
439
447
  end
440
448
 
@@ -447,7 +455,7 @@ WRAP
447
455
  def with_failed_release_cleanup
448
456
  yield
449
457
  rescue Exception
450
- info "~> Release #{c.release_path} failed, saving release to #{c.failed_release_dir}."
458
+ shell.status "Release #{c.release_path} failed, saving release to #{c.failed_release_dir}."
451
459
  sudo "mv #{c.release_path} #{c.failed_release_dir}"
452
460
  raise
453
461
  end
@@ -480,7 +488,7 @@ WRAP
480
488
 
481
489
  def check_ruby_bundler
482
490
  if gemfile?
483
- info "~> Bundling gems..."
491
+ shell.status "Bundling gems..."
484
492
 
485
493
  clean_bundle_on_system_version_change
486
494
 
@@ -511,14 +519,18 @@ WRAP
511
519
 
512
520
  def check_node_npm
513
521
  if File.exist?("#{c.release_path}/package.json")
514
- info "~> package.json detected, installing npm packages"
515
- run "cd #{c.release_path} && npm install"
522
+ unless run(node_package_manager_command_check)
523
+ abort "*** [Error] package.json detected, but npm was not installed"
524
+ else
525
+ shell.status "package.json detected, installing npm packages"
526
+ run "cd #{c.release_path} && npm install"
527
+ end
516
528
  end
517
529
  end
518
530
  end # DeployBase
519
531
 
520
532
  class Deploy < DeployBase
521
- def self.new(config)
533
+ def self.new(config, shell=nil)
522
534
  # include the correct fetch strategy
523
535
  include EY::Serverside::Strategies.const_get(config.strategy)::Helpers
524
536
  super