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