engineyard-serverside 1.6.5 → 1.7.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/engineyard-serverside.rb +2 -0
- data/lib/engineyard-serverside/cli.rb +83 -48
- data/lib/engineyard-serverside/configuration.rb +85 -18
- data/lib/engineyard-serverside/deploy.rb +105 -91
- data/lib/engineyard-serverside/deploy_hook.rb +22 -20
- data/lib/engineyard-serverside/deprecation.rb +9 -17
- data/lib/engineyard-serverside/future.rb +10 -4
- data/lib/engineyard-serverside/futures/celluloid.rb +3 -13
- data/lib/engineyard-serverside/futures/dataflow.rb +8 -13
- data/lib/engineyard-serverside/lockfile_parser.rb +1 -1
- data/lib/engineyard-serverside/rails_asset_support.rb +26 -10
- data/lib/engineyard-serverside/server.rb +17 -12
- data/lib/engineyard-serverside/shell.rb +98 -0
- data/lib/engineyard-serverside/shell/formatter.rb +71 -0
- data/lib/engineyard-serverside/shell/helpers.rb +29 -0
- data/lib/engineyard-serverside/strategies/git.rb +33 -63
- data/lib/engineyard-serverside/task.rb +34 -13
- data/lib/engineyard-serverside/version.rb +1 -1
- data/spec/basic_deploy_spec.rb +15 -50
- data/spec/bundler_deploy_spec.rb +3 -44
- data/spec/configuration_spec.rb +72 -0
- data/spec/custom_deploy_spec.rb +3 -4
- data/spec/deploy_hook_spec.rb +210 -162
- data/spec/deprecation_spec.rb +4 -26
- data/spec/ey_yml_customized_deploy_spec.rb +68 -0
- data/spec/fixtures/repos/assets_disabled/Gemfile +6 -0
- data/spec/fixtures/repos/assets_disabled/Gemfile.lock +90 -0
- data/spec/fixtures/repos/assets_disabled/README +1 -0
- data/spec/fixtures/repos/assets_disabled/Rakefile +5 -0
- data/spec/fixtures/repos/assets_disabled/config/application.rb +5 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Gemfile +6 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Gemfile.lock +90 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/README +1 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/Rakefile +5 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/config/application.rb +5 -0
- data/spec/fixtures/repos/assets_disabled_in_ey_yml/config/ey.yml +4 -0
- data/spec/fixtures/repos/assets_enabled/Gemfile +6 -0
- data/spec/fixtures/repos/assets_enabled/Gemfile.lock +90 -0
- data/spec/fixtures/repos/assets_enabled/README +1 -0
- data/spec/fixtures/repos/assets_enabled/Rakefile +5 -0
- data/spec/fixtures/repos/assets_enabled/config/application.rb +5 -0
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/README +1 -0
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/Rakefile +5 -0
- data/spec/fixtures/repos/assets_enabled_in_ey_yml/config/ey.yml +4 -0
- data/spec/fixtures/repos/assets_in_hook/Gemfile +6 -0
- data/spec/fixtures/repos/assets_in_hook/Gemfile.lock +90 -0
- data/spec/fixtures/repos/assets_in_hook/README +2 -0
- data/spec/fixtures/repos/assets_in_hook/Rakefile +5 -0
- data/spec/fixtures/repos/assets_in_hook/config/application.rb +5 -0
- data/spec/fixtures/repos/assets_in_hook/deploy/before_migrate.rb +1 -0
- data/spec/fixtures/repos/default/Gemfile +5 -0
- data/spec/fixtures/repos/default/Gemfile.lock +14 -0
- data/spec/fixtures/repos/default/README +5 -0
- data/spec/fixtures/repos/ey_yml/Gemfile +4 -0
- data/spec/fixtures/repos/ey_yml/Gemfile.lock +12 -0
- data/spec/fixtures/repos/ey_yml/README +1 -0
- data/spec/fixtures/repos/ey_yml/config/ey.yml +12 -0
- data/spec/fixtures/repos/ey_yml/deploy/before_migrate.rb +6 -0
- data/spec/fixtures/repos/ey_yml_alt/Gemfile +4 -0
- data/spec/fixtures/repos/ey_yml_alt/Gemfile.lock +12 -0
- data/spec/fixtures/repos/ey_yml_alt/README +1 -0
- data/spec/fixtures/repos/ey_yml_alt/deploy/before_migrate.rb +6 -0
- data/spec/fixtures/repos/ey_yml_alt/ey.yml +12 -0
- data/spec/fixtures/repos/hook_fails/README +1 -0
- data/spec/fixtures/repos/hook_fails/deploy/before_migrate.rb +1 -0
- data/spec/fixtures/repos/hooks/README +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_bundle.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_compile_assets.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_migrate.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_restart.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/after_symlink.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_bundle.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_compile_assets.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_migrate.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_restart.rb +1 -0
- data/spec/fixtures/repos/hooks/deploy/before_symlink.rb +1 -0
- data/spec/fixtures/repos/no_ey_config/Gemfile +4 -0
- data/spec/fixtures/repos/no_ey_config/Gemfile.lock +12 -0
- data/spec/fixtures/repos/no_ey_config/README +1 -0
- data/spec/fixtures/repos/no_gemfile_lock/Gemfile +5 -0
- data/spec/fixtures/repos/no_gemfile_lock/README +1 -0
- data/spec/fixtures/repos/nodejs/README +1 -0
- data/spec/fixtures/repos/nodejs/package.json +7 -0
- data/spec/fixtures/repos/not_bundled/README +1 -0
- data/spec/fixtures/{gemfiles/1.0.21-rails-31-with-sqlite → repos/sqlite3/Gemfile} +0 -0
- data/spec/fixtures/{lockfiles/1.0.21-rails-31-with-sqlite → repos/sqlite3/Gemfile.lock} +0 -0
- data/spec/fixtures/repos/sqlite3/README +1 -0
- data/spec/git_strategy_spec.rb +11 -2
- data/spec/lockfile_parser_spec.rb +8 -3
- data/spec/nodejs_deploy_spec.rb +1 -26
- data/spec/rails31_deploy_spec.rb +23 -31
- data/spec/services_deploy_spec.rb +41 -100
- data/spec/shell_spec.rb +50 -0
- data/spec/spec_helper.rb +80 -66
- data/spec/sqlite3_deploy_spec.rb +10 -16
- data/spec/support/integration.rb +45 -139
- metadata +233 -78
- data/lib/engineyard-serverside/logged_output.rb +0 -91
- data/spec/logged_output_spec.rb +0 -55
|
@@ -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 =
|
|
54
|
-
|
|
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
|
-
|
|
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,26 +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 =
|
|
137
|
-
|
|
138
|
-
# We have to rsync the entire app dir, so we need all the permissions to be correct!
|
|
139
|
-
system "sudo sh -l -c 'find #{app_dir} -not -user #{config.user} -or -not -group #{config.group} -exec chown #{config.user}:#{config.group} {} +'"
|
|
140
|
-
|
|
141
|
-
load_servers(config)
|
|
142
|
-
|
|
143
|
-
invoke :propagate
|
|
157
|
+
config, shell = init_and_propagate(integrate_options, 'integrate')
|
|
144
158
|
|
|
145
159
|
EY::Serverside::Server.all.each do |server|
|
|
146
|
-
server.
|
|
160
|
+
shell.logged_system server.sync_directory_command(app_dir)
|
|
147
161
|
# we're just about to recreate this, so it has to be gone
|
|
148
162
|
# first. otherwise, non-idempotent deploy hooks could screw
|
|
149
163
|
# things up, and since we don't control deploy hooks, we must
|
|
150
164
|
# assume the worst.
|
|
151
|
-
server
|
|
165
|
+
run_on_server(server,"rm -rf #{current_app_dir}")
|
|
152
166
|
end
|
|
153
167
|
|
|
154
168
|
# deploy local-ref to other instances into /data/$app/local-current
|
|
155
|
-
EY::Serverside::Deploy.new(config).cached_deploy
|
|
169
|
+
EY::Serverside::Deploy.new(config, shell).cached_deploy
|
|
156
170
|
end
|
|
157
171
|
|
|
158
172
|
method_option :app, :type => :string,
|
|
@@ -160,6 +174,14 @@ module EY
|
|
|
160
174
|
:desc => "Application to deploy",
|
|
161
175
|
:aliases => ["-a"]
|
|
162
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
|
+
|
|
163
185
|
method_option :stack, :type => :string,
|
|
164
186
|
:desc => "Web stack (so we can restart it correctly)"
|
|
165
187
|
|
|
@@ -175,20 +197,13 @@ module EY
|
|
|
175
197
|
:desc => "Instance names, keyed on hostname. e.g. instance1:name1 instance2:name2"
|
|
176
198
|
|
|
177
199
|
method_option :verbose, :type => :boolean,
|
|
178
|
-
:default => false,
|
|
179
200
|
:desc => "Verbose output",
|
|
180
201
|
:aliases => ["-v"]
|
|
181
202
|
desc "restart", "Restart app servers, conditionally enabling maintenance page"
|
|
182
203
|
def restart
|
|
183
|
-
|
|
184
|
-
EY::Serverside::LoggedOutput.logfile = File.join(ENV['HOME'], "#{options[:app]}-restart.log")
|
|
204
|
+
config, shell = init_and_propagate(options, 'restart')
|
|
185
205
|
|
|
186
|
-
|
|
187
|
-
load_servers(config)
|
|
188
|
-
|
|
189
|
-
invoke :propagate
|
|
190
|
-
|
|
191
|
-
EY::Serverside::Deploy.new(config).restart_with_maintenance_page
|
|
206
|
+
EY::Serverside::Deploy.new(config, shell).restart_with_maintenance_page
|
|
192
207
|
end
|
|
193
208
|
|
|
194
209
|
desc "install_bundler [VERSION]", "Make sure VERSION of bundler is installed (in system ruby)"
|
|
@@ -206,8 +221,10 @@ module EY
|
|
|
206
221
|
end
|
|
207
222
|
end
|
|
208
223
|
|
|
209
|
-
|
|
210
|
-
|
|
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)
|
|
211
228
|
config = EY::Serverside::Deploy::Configuration.new
|
|
212
229
|
gem_filename = "engineyard-serverside-#{EY::Serverside::VERSION}.gem"
|
|
213
230
|
local_gem_file = File.join(Gem.dir, 'cache', gem_filename)
|
|
@@ -216,29 +233,47 @@ module EY
|
|
|
216
233
|
|
|
217
234
|
servers = EY::Serverside::Server.all.find_all { |server| !server.local? }
|
|
218
235
|
|
|
219
|
-
|
|
236
|
+
commands = servers.each do |server|
|
|
220
237
|
egrep_escaped_version = EY::Serverside::VERSION.gsub(/\./, '\.')
|
|
221
238
|
# the [,)] is to stop us from looking for e.g. 0.5.1, seeing
|
|
222
239
|
# 0.5.11, and mistakenly thinking 0.5.1 is there
|
|
223
240
|
has_gem_cmd = "#{gem_binary} list engineyard-serverside | grep \"engineyard-serverside\" | egrep -q '#{egrep_escaped_version}[,)]'"
|
|
224
241
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
242
|
+
proc do
|
|
243
|
+
if !run_on_server(server,has_gem_cmd).success? # doesn't have this exact version
|
|
244
|
+
shell.status "Installing engineyard-serverside on #{server.hostname}"
|
|
245
|
+
|
|
246
|
+
shell.logged_system(Escape.shell_command([
|
|
247
|
+
'scp', '-i', "#{ENV['HOME']}/.ssh/internal",
|
|
248
|
+
"-o", "StrictHostKeyChecking=no",
|
|
249
|
+
local_gem_file,
|
|
250
|
+
"#{config.user}@#{server.hostname}:#{remote_gem_file}",
|
|
251
|
+
]))
|
|
252
|
+
run_on_server(server,"sudo #{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'")
|
|
253
|
+
end
|
|
235
254
|
end
|
|
236
255
|
end
|
|
237
256
|
|
|
257
|
+
futures = EY::Serverside::Future.call(commands)
|
|
238
258
|
EY::Serverside::Future.success?(futures)
|
|
239
259
|
end
|
|
240
260
|
|
|
241
|
-
|
|
261
|
+
def init_and_propagate(*args)
|
|
262
|
+
config, shell = init(*args)
|
|
263
|
+
load_servers(config)
|
|
264
|
+
propagate(shell)
|
|
265
|
+
[config, shell]
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def init(options, action)
|
|
269
|
+
config = EY::Serverside::Deploy::Configuration.new(options)
|
|
270
|
+
shell = EY::Serverside::Shell.new(:verbose => config.verbose, :log_path => File.join(ENV['HOME'], "#{config.app}-#{action}.log"))
|
|
271
|
+
[config, shell]
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def run_on_server(server, command)
|
|
275
|
+
shell.logged_system(server.command_on_server('sh -l -c', command))
|
|
276
|
+
end
|
|
242
277
|
|
|
243
278
|
def load_servers(config)
|
|
244
279
|
EY::Serverside::Server.load_all_from_array(assemble_instance_hashes(config))
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'json'
|
|
2
2
|
require 'thor'
|
|
3
|
+
require 'pp'
|
|
3
4
|
|
|
4
5
|
module EY
|
|
5
6
|
module Serverside
|
|
@@ -10,41 +11,54 @@ module EY
|
|
|
10
11
|
"bundle_without" => "test development",
|
|
11
12
|
})
|
|
12
13
|
|
|
13
|
-
attr_reader :configuration
|
|
14
|
-
alias :c :configuration
|
|
15
|
-
|
|
16
14
|
attr_writer :release_path
|
|
17
15
|
|
|
18
16
|
def initialize(options={})
|
|
19
|
-
opts = options.
|
|
20
|
-
@release_path = opts[
|
|
17
|
+
opts = options.inject({}) { |h,(k,v)| h[k.to_s] = v; h }
|
|
18
|
+
@release_path = opts['release_path']
|
|
21
19
|
config = JSON.parse(opts.delete("config") || "{}")
|
|
22
|
-
@
|
|
20
|
+
@configs = [config, opts] # low to high priority
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def configuration
|
|
24
|
+
@configuration ||= @configs.inject(DEFAULT_CONFIG) {|low,high| low.merge(high)}
|
|
23
25
|
end
|
|
26
|
+
alias :c :configuration # FIXME: awful, but someone is probably using it :(
|
|
24
27
|
|
|
25
28
|
# Delegate to the configuration objects
|
|
26
29
|
def method_missing(meth, *args, &blk)
|
|
27
|
-
|
|
30
|
+
configuration.key?(meth.to_s) ? configuration[meth.to_s] : super
|
|
28
31
|
end
|
|
29
32
|
|
|
30
33
|
def respond_to?(meth, include_private=false)
|
|
31
|
-
|
|
34
|
+
configuration.key?(meth.to_s) ? true : super
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def load_ey_yml_data(data, shell)
|
|
38
|
+
environments = data['environments']
|
|
39
|
+
if environments && (env_data = environments[environment_name])
|
|
40
|
+
shell.substatus "ey.yml configuration loaded for environment #{environment_name.inspect}."
|
|
41
|
+
shell.debug "#{environment_name}: #{env_data.pretty_inspect}"
|
|
42
|
+
@configuration = nil # reset cached configuration hash
|
|
43
|
+
@configs.unshift(env_data) # insert just above default configuration
|
|
44
|
+
true
|
|
45
|
+
else
|
|
46
|
+
shell.info "No matching ey.yml configuration found for environment #{environment_name.inspect}."
|
|
47
|
+
shell.debug "ey.yml:\n#{data.pretty_inspect}"
|
|
48
|
+
false
|
|
49
|
+
end
|
|
32
50
|
end
|
|
33
51
|
|
|
34
52
|
def [](key)
|
|
35
53
|
if respond_to?(key.to_sym)
|
|
36
54
|
send(key.to_sym)
|
|
37
55
|
else
|
|
38
|
-
|
|
56
|
+
configuration[key]
|
|
39
57
|
end
|
|
40
58
|
end
|
|
41
59
|
|
|
42
60
|
def has_key?(key)
|
|
43
|
-
|
|
44
|
-
true
|
|
45
|
-
else
|
|
46
|
-
c.has_key?(key)
|
|
47
|
-
end
|
|
61
|
+
respond_to?(key.to_sym) || configuration.has_key?(key)
|
|
48
62
|
end
|
|
49
63
|
|
|
50
64
|
def to_json
|
|
@@ -55,9 +69,30 @@ module EY
|
|
|
55
69
|
EY::Serverside.node
|
|
56
70
|
end
|
|
57
71
|
|
|
72
|
+
def verbose
|
|
73
|
+
configuration['verbose']
|
|
74
|
+
end
|
|
75
|
+
|
|
58
76
|
def app
|
|
59
77
|
configuration['app'].to_s
|
|
60
78
|
end
|
|
79
|
+
alias app_name app
|
|
80
|
+
|
|
81
|
+
def environment_name
|
|
82
|
+
configuration['environment_name'].to_s
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def account_name
|
|
86
|
+
configuration['account_name'].to_s
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def ssh_identity_file
|
|
90
|
+
"~/.ssh/#{c.app}-deploy-key"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def strategy_class
|
|
94
|
+
EY::Serverside::Strategies.const_get(strategy)
|
|
95
|
+
end
|
|
61
96
|
|
|
62
97
|
def revision
|
|
63
98
|
IO.read(File.join(latest_release, 'REVISION'))
|
|
@@ -95,6 +130,10 @@ module EY
|
|
|
95
130
|
node['instance_role']
|
|
96
131
|
end
|
|
97
132
|
|
|
133
|
+
def current_roles
|
|
134
|
+
configuration['current_roles'] || []
|
|
135
|
+
end
|
|
136
|
+
|
|
98
137
|
def current_role
|
|
99
138
|
current_roles.first
|
|
100
139
|
end
|
|
@@ -116,10 +155,6 @@ module EY
|
|
|
116
155
|
all_releases[index-1]
|
|
117
156
|
end
|
|
118
157
|
|
|
119
|
-
def oldest_release
|
|
120
|
-
all_releases.first
|
|
121
|
-
end
|
|
122
|
-
|
|
123
158
|
def all_releases
|
|
124
159
|
Dir.glob("#{release_dir}/*").sort
|
|
125
160
|
end
|
|
@@ -184,10 +219,42 @@ module EY
|
|
|
184
219
|
@release_path ||= File.join(release_dir, Time.now.utc.strftime("%Y%m%d%H%M%S"))
|
|
185
220
|
end
|
|
186
221
|
|
|
222
|
+
def precompile_assets?
|
|
223
|
+
configuration['precompile_assets'] == true
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def skip_precompile_assets?
|
|
227
|
+
configuration['precompile_assets'] == false
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def required_downtime_stack?
|
|
231
|
+
%w[ nginx_mongrel glassfish ].include? stack
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def enable_maintenance_page_on_restart?
|
|
235
|
+
configuration.fetch('maintenance_on_restart', required_downtime_stack?)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def enable_maintenance_page_on_migrate?
|
|
239
|
+
configuration.fetch('maintenance_on_migrate', true)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def enable_maintenance_page?
|
|
243
|
+
enable_maintenance_page_on_restart? || (migrate? && enable_maintenance_page_on_migrate?)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def maintenance_page_enabled_path
|
|
247
|
+
File.join(shared_path, "system", "maintenance.html")
|
|
248
|
+
end
|
|
249
|
+
|
|
187
250
|
def exclusions
|
|
188
251
|
copy_exclude.map { |e| %|--exclude="#{e}"| }.join(' ')
|
|
189
252
|
end
|
|
190
253
|
|
|
254
|
+
def ignore_database_adapter_warning?
|
|
255
|
+
configuration.fetch('ignore_database_adapter_warning', false)
|
|
256
|
+
end
|
|
257
|
+
|
|
191
258
|
end
|
|
192
259
|
end
|
|
193
260
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
25
|
+
shell.status "Starting full deploy"
|
|
26
26
|
copy_repository_cache
|
|
27
27
|
check_repository
|
|
28
28
|
|
|
@@ -47,13 +47,25 @@ module EY
|
|
|
47
47
|
disable_maintenance_page
|
|
48
48
|
|
|
49
49
|
cleanup_old_releases
|
|
50
|
-
|
|
50
|
+
shell.status "Finished deploy at #{Time.now.asctime}"
|
|
51
51
|
rescue Exception
|
|
52
|
-
|
|
52
|
+
shell.status "Finished failing to deploy at #{Time.now.asctime}"
|
|
53
53
|
puts_deploy_failure
|
|
54
54
|
raise
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
def update_repository_cache
|
|
58
|
+
strategy.update_repository_cache
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def create_revision_file_command
|
|
62
|
+
strategy.create_revision_file_command(config.release_path)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def short_log_message(revision)
|
|
66
|
+
strategy.short_log_message(revision)
|
|
67
|
+
end
|
|
68
|
+
|
|
57
69
|
def parse_configured_services
|
|
58
70
|
result = YAML.load_file "#{c.shared_path}/config/ey_services_config_deploy.yml"
|
|
59
71
|
return {} unless result.is_a?(Hash)
|
|
@@ -66,18 +78,18 @@ module EY
|
|
|
66
78
|
if gemfile? && lockfile
|
|
67
79
|
configured_services = parse_configured_services
|
|
68
80
|
if !configured_services.empty? && !lockfile.has_ey_config?
|
|
69
|
-
warning "Gemfile.lock does not contain ey_config. Add it to get EY::Config access to: #{configured_services.keys.join(', ')}."
|
|
81
|
+
shell.warning "Gemfile.lock does not contain ey_config. Add it to get EY::Config access to: #{configured_services.keys.join(', ')}."
|
|
70
82
|
end
|
|
71
83
|
end
|
|
72
84
|
end
|
|
73
85
|
|
|
74
86
|
def check_repository
|
|
75
87
|
if gemfile?
|
|
76
|
-
|
|
88
|
+
shell.status "Gemfile found."
|
|
77
89
|
if lockfile
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
warning <<-WARN
|
|
90
|
+
shell.status "Gemfile.lock found."
|
|
91
|
+
if !config.ignore_database_adapter_warning? && !lockfile.any_database_adapter?
|
|
92
|
+
shell.warning <<-WARN
|
|
81
93
|
Gemfile.lock does not contain a recognized database adapter.
|
|
82
94
|
A database-adapter gem such as mysql2, mysql, or do_mysql was expected.
|
|
83
95
|
This can prevent applications that use MySQL or PostreSQL from booting.
|
|
@@ -87,7 +99,7 @@ Applications that don't use MySQL or PostgreSQL can safely ignore this warning.
|
|
|
87
99
|
WARN
|
|
88
100
|
end
|
|
89
101
|
else
|
|
90
|
-
warning <<-WARN
|
|
102
|
+
shell.warning <<-WARN
|
|
91
103
|
Gemfile.lock is missing!
|
|
92
104
|
You can get different versions of gems in production than what you tested with.
|
|
93
105
|
You can get different versions of gems on every deployment even if your Gemfile hasn't changed.
|
|
@@ -97,15 +109,13 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
97
109
|
WARN
|
|
98
110
|
end
|
|
99
111
|
else
|
|
100
|
-
|
|
112
|
+
shell.status "No Gemfile. Deploying without bundler support."
|
|
101
113
|
end
|
|
102
114
|
end
|
|
103
115
|
|
|
104
116
|
def restart_with_maintenance_page
|
|
105
117
|
require_custom_tasks
|
|
106
|
-
|
|
107
|
-
restart
|
|
108
|
-
disable_maintenance_page
|
|
118
|
+
with_maintenance_page { restart }
|
|
109
119
|
end
|
|
110
120
|
|
|
111
121
|
def enable_maintenance_page
|
|
@@ -119,10 +129,7 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
119
129
|
end
|
|
120
130
|
|
|
121
131
|
# this one is guaranteed to exist
|
|
122
|
-
maintenance_page_candidates <<
|
|
123
|
-
"default_maintenance_page.html",
|
|
124
|
-
File.dirname(__FILE__)
|
|
125
|
-
)
|
|
132
|
+
maintenance_page_candidates << File.expand_path("default_maintenance_page.html", File.dirname(__FILE__))
|
|
126
133
|
|
|
127
134
|
# put in the maintenance page
|
|
128
135
|
maintenance_file = maintenance_page_candidates.detect do |file|
|
|
@@ -131,27 +138,21 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
131
138
|
|
|
132
139
|
@maintenance_up = true
|
|
133
140
|
roles :app_master, :app, :solo do
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
run Escape.shell_command(['mkdir', '-p', maint_page_dir])
|
|
137
|
-
run Escape.shell_command(['cp', maintenance_file, visible_maint_page])
|
|
141
|
+
run Escape.shell_command(['mkdir', '-p', File.dirname(c.maintenance_page_enabled_path)])
|
|
142
|
+
run Escape.shell_command(['cp', maintenance_file, c.maintenance_page_enabled_path])
|
|
138
143
|
end
|
|
139
144
|
end
|
|
140
145
|
|
|
141
146
|
def conditionally_enable_maintenance_page
|
|
142
|
-
if c.
|
|
147
|
+
if c.enable_maintenance_page?
|
|
143
148
|
enable_maintenance_page
|
|
144
149
|
end
|
|
145
150
|
end
|
|
146
151
|
|
|
147
|
-
def required_downtime_stack?
|
|
148
|
-
%w[ nginx_mongrel glassfish ].include? c.stack
|
|
149
|
-
end
|
|
150
|
-
|
|
151
152
|
def disable_maintenance_page
|
|
152
153
|
@maintenance_up = false
|
|
153
154
|
roles :app_master, :app, :solo do
|
|
154
|
-
run "rm -f #{
|
|
155
|
+
run "rm -f #{c.maintenance_page_enabled_path}"
|
|
155
156
|
end
|
|
156
157
|
end
|
|
157
158
|
|
|
@@ -163,17 +164,19 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
163
164
|
|
|
164
165
|
# task
|
|
165
166
|
def push_code
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
server.
|
|
167
|
+
shell.status "Pushing code to all servers"
|
|
168
|
+
commands = EY::Serverside::Server.all.reject { |server| server.local? }.map do |server|
|
|
169
|
+
cmd = server.sync_directory_command(config.repository_cache)
|
|
170
|
+
proc { shell.logged_system(cmd) }
|
|
169
171
|
end
|
|
172
|
+
futures = EY::Serverside::Future.call(commands)
|
|
170
173
|
EY::Serverside::Future.success?(futures)
|
|
171
174
|
end
|
|
172
175
|
|
|
173
176
|
# task
|
|
174
177
|
def restart
|
|
175
178
|
@restart_failed = true
|
|
176
|
-
|
|
179
|
+
shell.status "Restarting app servers"
|
|
177
180
|
roles :app_master, :app, :solo do
|
|
178
181
|
run(restart_command)
|
|
179
182
|
end
|
|
@@ -189,14 +192,14 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
189
192
|
%Q[export GIT_SSH="#{ssh_executable}" && export LANG="en_US.UTF-8" && unset RUBYOPT BUNDLE_PATH BUNDLE_FROZEN BUNDLE_WITHOUT BUNDLE_BIN BUNDLE_GEMFILE]
|
|
190
193
|
end
|
|
191
194
|
|
|
192
|
-
#
|
|
193
|
-
# create it on all the servers that will need it.
|
|
194
|
-
# TODO - This logic likely fails when people change deploy keys.
|
|
195
|
+
# create ssh wrapper on all servers
|
|
195
196
|
def ssh_executable
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
@ssh_executable ||= begin
|
|
198
|
+
roles :app_master, :app, :solo, :util do
|
|
199
|
+
run(generate_ssh_wrapper)
|
|
200
|
+
end
|
|
201
|
+
ssh_wrapper_path
|
|
202
|
+
end
|
|
200
203
|
end
|
|
201
204
|
|
|
202
205
|
# We specify 'IdentitiesOnly' to avoid failures on systems with > 5 private keys available.
|
|
@@ -206,15 +209,15 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
206
209
|
# (Thanks Jim L.)
|
|
207
210
|
def generate_ssh_wrapper
|
|
208
211
|
path = ssh_wrapper_path
|
|
209
|
-
|
|
210
|
-
|
|
212
|
+
<<-SCRIPT
|
|
213
|
+
mkdir -p #{File.dirname(path)}
|
|
211
214
|
[[ -x #{path} ]] || cat > #{path} <<'SSH'
|
|
212
215
|
#!/bin/sh
|
|
213
216
|
unset SSH_AUTH_SOCK
|
|
214
|
-
ssh -o CheckHostIP=no -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o LogLevel=INFO -o IdentityFile=#{
|
|
217
|
+
ssh -o CheckHostIP=no -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o LogLevel=INFO -o IdentityFile=#{c.ssh_identity_file} -o IdentitiesOnly=yes $*
|
|
215
218
|
SSH
|
|
216
219
|
chmod 0700 #{path}
|
|
217
|
-
|
|
220
|
+
SCRIPT
|
|
218
221
|
end
|
|
219
222
|
|
|
220
223
|
def ssh_wrapper_path
|
|
@@ -242,7 +245,7 @@ WRAP
|
|
|
242
245
|
def clean_release_directory(dir, count = 3)
|
|
243
246
|
@cleanup_failed = true
|
|
244
247
|
ordinal = count.succ.to_s
|
|
245
|
-
|
|
248
|
+
shell.status "Cleaning release directory: #{dir}"
|
|
246
249
|
sudo "ls -r #{dir} | tail -n +#{ordinal} | xargs -I@ rm -rf #{dir}/@"
|
|
247
250
|
@cleanup_failed = false
|
|
248
251
|
end
|
|
@@ -254,15 +257,15 @@ WRAP
|
|
|
254
257
|
c.release_path = c.previous_release(rolled_back_release)
|
|
255
258
|
|
|
256
259
|
revision = File.read(File.join(c.release_path, 'REVISION')).strip
|
|
257
|
-
|
|
260
|
+
shell.status "Rolling back to previous release: #{short_log_message(revision)}"
|
|
258
261
|
|
|
259
262
|
run_with_callbacks(:symlink)
|
|
260
263
|
sudo "rm -rf #{rolled_back_release}"
|
|
261
264
|
bundle
|
|
262
|
-
|
|
265
|
+
shell.status "Restarting with previous release."
|
|
263
266
|
with_maintenance_page { run_with_callbacks(:restart) }
|
|
264
267
|
else
|
|
265
|
-
|
|
268
|
+
shell.status "Already at oldest release, nothing to roll back to."
|
|
266
269
|
exit(1)
|
|
267
270
|
end
|
|
268
271
|
end
|
|
@@ -273,17 +276,17 @@ WRAP
|
|
|
273
276
|
@migrations_reached = true
|
|
274
277
|
roles :app_master, :solo do
|
|
275
278
|
cmd = "cd #{c.release_path} && PATH=#{c.binstubs_path}:$PATH #{c.framework_envs} #{c.migration_command}"
|
|
276
|
-
|
|
279
|
+
shell.status "Migrating: #{cmd}"
|
|
277
280
|
run(cmd)
|
|
278
281
|
end
|
|
279
282
|
end
|
|
280
283
|
|
|
281
284
|
# task
|
|
282
285
|
def copy_repository_cache
|
|
283
|
-
|
|
286
|
+
shell.status "Copying to #{c.release_path}"
|
|
284
287
|
run("mkdir -p #{c.release_path} #{c.failed_release_dir} && rsync -aq #{c.exclusions} #{c.repository_cache}/ #{c.release_path}")
|
|
285
288
|
|
|
286
|
-
|
|
289
|
+
shell.status "Ensuring proper ownership."
|
|
287
290
|
sudo("chown -R #{c.user}:#{c.group} #{c.deploy_to}")
|
|
288
291
|
end
|
|
289
292
|
|
|
@@ -300,18 +303,18 @@ WRAP
|
|
|
300
303
|
end
|
|
301
304
|
|
|
302
305
|
def setup_services
|
|
303
|
-
|
|
306
|
+
shell.status "Setting up external services."
|
|
304
307
|
previously_configured_services = parse_configured_services
|
|
305
308
|
begin
|
|
306
309
|
sudo(services_command_check)
|
|
307
310
|
rescue StandardError => e
|
|
308
|
-
info "Could not setup services. Upgrade your environment to get services configuration."
|
|
311
|
+
shell.info "Could not setup services. Upgrade your environment to get services configuration."
|
|
309
312
|
return
|
|
310
313
|
end
|
|
311
314
|
sudo(services_setup_command)
|
|
312
315
|
rescue StandardError => e
|
|
313
316
|
unless previously_configured_services.empty?
|
|
314
|
-
warning <<-WARNING
|
|
317
|
+
shell.warning <<-WARNING
|
|
315
318
|
External services configuration not updated. Using previous version.
|
|
316
319
|
Deploy again if your services configuration appears incomplete or out of date.
|
|
317
320
|
#{e}
|
|
@@ -336,24 +339,24 @@ YML
|
|
|
336
339
|
WRAP
|
|
337
340
|
["Symlink database.yml", "ln -nfs #{c.shared_path}/config/database.sqlite3.yml #{c.release_path}/config/database.yml"],
|
|
338
341
|
].each do |what, cmd|
|
|
339
|
-
|
|
342
|
+
shell.status "#{what}"
|
|
340
343
|
run(cmd)
|
|
341
344
|
end
|
|
342
345
|
|
|
343
346
|
owner = [c.user, c.group].join(':')
|
|
344
|
-
|
|
347
|
+
shell.status "Setting ownership to #{owner}"
|
|
345
348
|
sudo "chown -R #{owner} #{c.release_path}"
|
|
346
349
|
end
|
|
347
350
|
end
|
|
348
351
|
|
|
349
352
|
def symlink_configs(release_to_link=c.release_path)
|
|
350
|
-
|
|
353
|
+
shell.status "Preparing shared resources for release."
|
|
351
354
|
symlink_tasks(release_to_link).each do |what, cmd|
|
|
352
|
-
|
|
355
|
+
shell.substatus what
|
|
353
356
|
run(cmd)
|
|
354
357
|
end
|
|
355
358
|
owner = [c.user, c.group].join(':')
|
|
356
|
-
|
|
359
|
+
shell.status "Setting ownership to #{owner}"
|
|
357
360
|
sudo "chown -R #{owner} #{release_to_link}"
|
|
358
361
|
end
|
|
359
362
|
|
|
@@ -376,7 +379,7 @@ WRAP
|
|
|
376
379
|
|
|
377
380
|
# task
|
|
378
381
|
def symlink(release_to_link=c.release_path)
|
|
379
|
-
|
|
382
|
+
shell.status "Symlinking code."
|
|
380
383
|
run "rm -f #{c.current_path} && ln -nfs #{release_to_link} #{c.current_path} && chown -R #{c.user}:#{c.group} #{c.current_path}"
|
|
381
384
|
@symlink_changed = true
|
|
382
385
|
rescue Exception
|
|
@@ -388,12 +391,12 @@ WRAP
|
|
|
388
391
|
def callback(what)
|
|
389
392
|
@callbacks_reached ||= true
|
|
390
393
|
if File.exist?("#{c.release_path}/deploy/#{what}.rb")
|
|
394
|
+
shell.status "Running deploy hook: deploy/#{what}.rb"
|
|
391
395
|
run Escape.shell_command(base_callback_command_for(what)) do |server, cmd|
|
|
392
|
-
per_instance_args = [
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
per_instance_args << '--current-name' << server.name.to_s if server.name
|
|
396
|
+
per_instance_args = []
|
|
397
|
+
per_instance_args << '--current-roles' << server.roles.join(' ')
|
|
398
|
+
per_instance_args << '--current-name' << server.name.to_s if server.name
|
|
399
|
+
per_instance_args << '--config' << c.to_json
|
|
397
400
|
cmd << " " << Escape.shell_command(per_instance_args)
|
|
398
401
|
end
|
|
399
402
|
end
|
|
@@ -401,8 +404,20 @@ WRAP
|
|
|
401
404
|
|
|
402
405
|
protected
|
|
403
406
|
|
|
404
|
-
|
|
405
|
-
|
|
407
|
+
# Use [] to access attributes instead of calling methods so
|
|
408
|
+
# that we get nils instead of NoMethodError.
|
|
409
|
+
#
|
|
410
|
+
# Rollback doesn't know about the repository location (nor
|
|
411
|
+
# should it need to), but it would like to use #short_log_message.
|
|
412
|
+
def strategy
|
|
413
|
+
ENV['GIT_SSH'] = ssh_executable
|
|
414
|
+
@strategy ||= config.strategy_class.new(
|
|
415
|
+
shell,
|
|
416
|
+
:repository_cache => config[:repository_cache],
|
|
417
|
+
:app => config[:app],
|
|
418
|
+
:repo => config[:repo],
|
|
419
|
+
:ref => config[:branch]
|
|
420
|
+
)
|
|
406
421
|
end
|
|
407
422
|
|
|
408
423
|
def gemfile?
|
|
@@ -410,11 +425,14 @@ WRAP
|
|
|
410
425
|
end
|
|
411
426
|
|
|
412
427
|
def base_callback_command_for(what)
|
|
413
|
-
[serverside_bin, 'hook', what.to_s
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
428
|
+
cmd = [serverside_bin, 'hook', what.to_s]
|
|
429
|
+
cmd << '--app' << config.app
|
|
430
|
+
cmd << '--environment-name' << config.environment_name
|
|
431
|
+
cmd << '--account-name' << config.account_name
|
|
432
|
+
cmd << '--release-path' << config.release_path.to_s
|
|
433
|
+
cmd << '--framework-env' << config.environment.to_s
|
|
434
|
+
cmd << '--verbose' if config.verbose
|
|
435
|
+
cmd
|
|
418
436
|
end
|
|
419
437
|
|
|
420
438
|
def serverside_bin
|
|
@@ -424,21 +442,22 @@ WRAP
|
|
|
424
442
|
|
|
425
443
|
def puts_deploy_failure
|
|
426
444
|
if @cleanup_failed
|
|
427
|
-
|
|
445
|
+
shell.notice "[Relax] Your site is running new code, but clean up of old deploys failed."
|
|
428
446
|
elsif @maintenance_up
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
447
|
+
message = "[Attention] Maintenance page still up, consider the following before removing:\n"
|
|
448
|
+
message << " * Deploy hooks ran. This might cause problems for reverting to old code.\n" if @callbacks_reached
|
|
449
|
+
message << " * Migrations ran. This might cause problems for reverting to old code.\n" if @migrations_reached
|
|
432
450
|
if @symlink_changed
|
|
433
|
-
|
|
451
|
+
message << " * Your new code is symlinked as current.\n"
|
|
434
452
|
else
|
|
435
|
-
|
|
453
|
+
message << " * Your old code is still symlinked as current.\n"
|
|
436
454
|
end
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
455
|
+
message << " * Application servers failed to restart.\n" if @restart_failed
|
|
456
|
+
message << "\n"
|
|
457
|
+
message << "Need help? File a ticket for support.\n"
|
|
458
|
+
shell.notice message
|
|
440
459
|
else
|
|
441
|
-
|
|
460
|
+
shell.notice "[Relax] Your site is still running old code and nothing destructive has occurred."
|
|
442
461
|
end
|
|
443
462
|
end
|
|
444
463
|
|
|
@@ -451,7 +470,7 @@ WRAP
|
|
|
451
470
|
def with_failed_release_cleanup
|
|
452
471
|
yield
|
|
453
472
|
rescue Exception
|
|
454
|
-
|
|
473
|
+
shell.status "Release #{c.release_path} failed, saving release to #{c.failed_release_dir}."
|
|
455
474
|
sudo "mv #{c.release_path} #{c.failed_release_dir}"
|
|
456
475
|
raise
|
|
457
476
|
end
|
|
@@ -484,7 +503,7 @@ WRAP
|
|
|
484
503
|
|
|
485
504
|
def check_ruby_bundler
|
|
486
505
|
if gemfile?
|
|
487
|
-
|
|
506
|
+
shell.status "Bundling gems..."
|
|
488
507
|
|
|
489
508
|
clean_bundle_on_system_version_change
|
|
490
509
|
|
|
@@ -515,18 +534,13 @@ WRAP
|
|
|
515
534
|
|
|
516
535
|
def check_node_npm
|
|
517
536
|
if File.exist?("#{c.release_path}/package.json")
|
|
518
|
-
info "~> package.json detected, installing npm packages"
|
|
537
|
+
shell.info "~> package.json detected, installing npm packages"
|
|
519
538
|
run "cd #{c.release_path} && npm install"
|
|
520
539
|
end
|
|
521
540
|
end
|
|
522
541
|
end # DeployBase
|
|
523
542
|
|
|
524
543
|
class Deploy < DeployBase
|
|
525
|
-
def self.new(config)
|
|
526
|
-
# include the correct fetch strategy
|
|
527
|
-
include EY::Serverside::Strategies.const_get(config.strategy)::Helpers
|
|
528
|
-
super
|
|
529
|
-
end
|
|
530
544
|
end
|
|
531
545
|
end
|
|
532
546
|
end
|