engineyard-serverside 1.5.28.pre.timestamps4 → 1.5.28
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 +0 -2
- data/lib/engineyard-serverside/cli.rb +27 -36
- data/lib/engineyard-serverside/configuration.rb +0 -4
- data/lib/engineyard-serverside/deploy.rb +34 -33
- data/lib/engineyard-serverside/deploy_hook.rb +2 -2
- data/lib/engineyard-serverside/deprecation.rb +17 -7
- data/lib/engineyard-serverside/logged_output.rb +90 -0
- data/lib/engineyard-serverside/rails_asset_support.rb +5 -5
- data/lib/engineyard-serverside/server.rb +12 -9
- data/lib/engineyard-serverside/strategies/git.rb +15 -12
- data/lib/engineyard-serverside/task.rb +4 -8
- data/lib/engineyard-serverside/version.rb +1 -1
- data/lib/vendor/open4/lib/open4.rb +80 -51
- data/spec/basic_deploy_spec.rb +9 -9
- data/spec/bundler_deploy_spec.rb +1 -1
- data/spec/custom_deploy_spec.rb +3 -3
- 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 -9
- data/spec/spec_helper.rb +27 -35
- data/spec/sqlite3_deploy_spec.rb +1 -0
- data/spec/support/integration.rb +13 -1
- metadata +24 -29
- data/lib/engineyard-serverside/shell.rb +0 -150
- data/spec/fixtures/gitrepo/bar +0 -0
- data/spec/shell_spec.rb +0 -46
|
@@ -51,12 +51,14 @@ module EY
|
|
|
51
51
|
desc "deploy", "Deploy code from /data/<app>"
|
|
52
52
|
def deploy(default_task=:deploy)
|
|
53
53
|
config = EY::Serverside::Deploy::Configuration.new(options)
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
EY::Serverside::Server.load_all_from_array(assemble_instance_hashes(config))
|
|
55
|
+
|
|
56
|
+
EY::Serverside::LoggedOutput.verbose = options[:verbose]
|
|
57
|
+
EY::Serverside::LoggedOutput.logfile = File.join(ENV['HOME'], "#{options[:app]}-deploy.log")
|
|
56
58
|
|
|
57
|
-
propagate
|
|
59
|
+
invoke :propagate
|
|
58
60
|
|
|
59
|
-
EY::Serverside::Deploy.new(config
|
|
61
|
+
EY::Serverside::Deploy.new(config).send(default_task)
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
method_option :app, :type => :string,
|
|
@@ -118,6 +120,9 @@ module EY
|
|
|
118
120
|
:aliases => ["-v"]
|
|
119
121
|
desc "integrate", "Integrate other instances into this cluster"
|
|
120
122
|
def integrate
|
|
123
|
+
EY::Serverside::LoggedOutput.verbose = options[:verbose]
|
|
124
|
+
EY::Serverside::LoggedOutput.logfile = File.join(ENV['HOME'], "#{options[:app]}-integrate.log")
|
|
125
|
+
|
|
121
126
|
app_dir = Pathname.new "/data/#{options[:app]}"
|
|
122
127
|
current_app_dir = app_dir + "current"
|
|
123
128
|
|
|
@@ -129,23 +134,22 @@ module EY
|
|
|
129
134
|
integrate_options[:branch] = (current_app_dir + 'REVISION').read.strip
|
|
130
135
|
|
|
131
136
|
config = EY::Serverside::Deploy::Configuration.new(integrate_options)
|
|
132
|
-
shell = init_shell(config.verbose, "#{config.app}-integrate")
|
|
133
137
|
|
|
134
|
-
|
|
138
|
+
EY::Serverside::Server.load_all_from_array(assemble_instance_hashes(config))
|
|
135
139
|
|
|
136
|
-
propagate
|
|
140
|
+
invoke :propagate
|
|
137
141
|
|
|
138
142
|
EY::Serverside::Server.all.each do |server|
|
|
139
|
-
server.sync_directory
|
|
143
|
+
server.sync_directory app_dir
|
|
140
144
|
# we're just about to recreate this, so it has to be gone
|
|
141
145
|
# first. otherwise, non-idempotent deploy hooks could screw
|
|
142
146
|
# things up, and since we don't control deploy hooks, we must
|
|
143
147
|
# assume the worst.
|
|
144
|
-
|
|
148
|
+
server.run("rm -rf #{current_app_dir}")
|
|
145
149
|
end
|
|
146
150
|
|
|
147
151
|
# deploy local-ref to other instances into /data/$app/local-current
|
|
148
|
-
EY::Serverside::Deploy.new(config
|
|
152
|
+
EY::Serverside::Deploy.new(config).cached_deploy
|
|
149
153
|
end
|
|
150
154
|
|
|
151
155
|
method_option :app, :type => :string,
|
|
@@ -173,13 +177,15 @@ module EY
|
|
|
173
177
|
:aliases => ["-v"]
|
|
174
178
|
desc "restart", "Restart app servers, conditionally enabling maintenance page"
|
|
175
179
|
def restart
|
|
180
|
+
EY::Serverside::LoggedOutput.verbose = options[:verbose]
|
|
181
|
+
EY::Serverside::LoggedOutput.logfile = File.join(ENV['HOME'], "#{options[:app]}-restart.log")
|
|
182
|
+
|
|
176
183
|
config = EY::Serverside::Deploy::Configuration.new(options)
|
|
177
|
-
|
|
178
|
-
load_servers(config)
|
|
184
|
+
EY::Serverside::Server.load_all_from_array(assemble_instance_hashes(config))
|
|
179
185
|
|
|
180
|
-
propagate
|
|
186
|
+
invoke :propagate
|
|
181
187
|
|
|
182
|
-
EY::Serverside::Deploy.new(config
|
|
188
|
+
EY::Serverside::Deploy.new(config).restart_with_maintenance_page
|
|
183
189
|
end
|
|
184
190
|
|
|
185
191
|
desc "install_bundler [VERSION]", "Make sure VERSION of bundler is installed (in system ruby)"
|
|
@@ -197,10 +203,8 @@ module EY
|
|
|
197
203
|
end
|
|
198
204
|
end
|
|
199
205
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
# Put the same engineyard-serverside on all the servers (Used to be public but is unused as an actual CLI command now)
|
|
203
|
-
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
|
|
204
208
|
config = EY::Serverside::Deploy::Configuration.new
|
|
205
209
|
gem_filename = "engineyard-serverside-#{EY::Serverside::VERSION}.gem"
|
|
206
210
|
local_gem_file = File.join(Gem.dir, 'cache', gem_filename)
|
|
@@ -215,36 +219,23 @@ module EY
|
|
|
215
219
|
# 0.5.11, and mistakenly thinking 0.5.1 is there
|
|
216
220
|
has_gem_cmd = "#{gem_binary} list engineyard-serverside | grep \"engineyard-serverside\" | egrep -q '#{egrep_escaped_version}[,)]'"
|
|
217
221
|
|
|
218
|
-
if !
|
|
219
|
-
|
|
222
|
+
if !server.run(has_gem_cmd) # doesn't have this exact version
|
|
223
|
+
puts "~> Installing engineyard-serverside on #{server.hostname}"
|
|
220
224
|
|
|
221
|
-
|
|
225
|
+
system(Escape.shell_command([
|
|
222
226
|
'scp', '-i', "#{ENV['HOME']}/.ssh/internal",
|
|
223
227
|
"-o", "StrictHostKeyChecking=no",
|
|
224
228
|
local_gem_file,
|
|
225
229
|
"#{config.user}@#{server.hostname}:#{remote_gem_file}",
|
|
226
230
|
]))
|
|
227
|
-
|
|
231
|
+
server.run("sudo #{gem_binary} install --no-rdoc --no-ri '#{remote_gem_file}'")
|
|
228
232
|
end
|
|
229
233
|
end
|
|
230
234
|
|
|
231
235
|
EY::Serverside::Future.success?(futures)
|
|
232
236
|
end
|
|
233
237
|
|
|
234
|
-
|
|
235
|
-
EY::Serverside::Shell.new(
|
|
236
|
-
:verbose => verbose,
|
|
237
|
-
:log_path => File.join(ENV['HOME'], "#{log_basename}.log")
|
|
238
|
-
)
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
def load_servers(config)
|
|
242
|
-
EY::Serverside::Server.load_all_from_array(assemble_instance_hashes(config))
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
def run_on_server(server, command)
|
|
246
|
-
server.run(command) { |cmd| shell.logged_system(cmd) }
|
|
247
|
-
end
|
|
238
|
+
private
|
|
248
239
|
|
|
249
240
|
def assemble_instance_hashes(config)
|
|
250
241
|
options[:instances].collect { |hostname|
|
|
@@ -7,21 +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
23
|
push_code
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
info "~> Starting full deploy"
|
|
25
26
|
copy_repository_cache
|
|
26
27
|
check_repository
|
|
27
28
|
|
|
@@ -46,9 +47,9 @@ module EY
|
|
|
46
47
|
disable_maintenance_page
|
|
47
48
|
|
|
48
49
|
cleanup_old_releases
|
|
49
|
-
|
|
50
|
+
debug "Finished deploy at #{Time.now.asctime}"
|
|
50
51
|
rescue Exception
|
|
51
|
-
|
|
52
|
+
debug "Finished failing to deploy at #{Time.now.asctime}"
|
|
52
53
|
puts_deploy_failure
|
|
53
54
|
raise
|
|
54
55
|
end
|
|
@@ -72,9 +73,9 @@ module EY
|
|
|
72
73
|
|
|
73
74
|
def check_repository
|
|
74
75
|
if gemfile?
|
|
75
|
-
|
|
76
|
+
info "~> Gemfile found."
|
|
76
77
|
if lockfile
|
|
77
|
-
|
|
78
|
+
info "~> Gemfile.lock found."
|
|
78
79
|
unless lockfile.any_database_adapter?
|
|
79
80
|
warning <<-WARN
|
|
80
81
|
Gemfile.lock does not contain a recognized database adapter.
|
|
@@ -96,7 +97,7 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
96
97
|
WARN
|
|
97
98
|
end
|
|
98
99
|
else
|
|
99
|
-
|
|
100
|
+
info "~> No Gemfile. Deploying without bundler support."
|
|
100
101
|
end
|
|
101
102
|
end
|
|
102
103
|
|
|
@@ -162,9 +163,9 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
162
163
|
|
|
163
164
|
# task
|
|
164
165
|
def push_code
|
|
165
|
-
|
|
166
|
+
info "~> Pushing code to all servers"
|
|
166
167
|
futures = EY::Serverside::Future.call(EY::Serverside::Server.all) do |server|
|
|
167
|
-
server.sync_directory(config.repository_cache)
|
|
168
|
+
server.sync_directory(config.repository_cache)
|
|
168
169
|
end
|
|
169
170
|
EY::Serverside::Future.success?(futures)
|
|
170
171
|
end
|
|
@@ -172,7 +173,7 @@ To fix this problem, commit your Gemfile.lock to your repository and redeploy.
|
|
|
172
173
|
# task
|
|
173
174
|
def restart
|
|
174
175
|
@restart_failed = true
|
|
175
|
-
|
|
176
|
+
info "~> Restarting app servers"
|
|
176
177
|
roles :app_master, :app, :solo do
|
|
177
178
|
run(restart_command)
|
|
178
179
|
end
|
|
@@ -242,7 +243,7 @@ WRAP
|
|
|
242
243
|
def clean_release_directory(dir, count = 3)
|
|
243
244
|
@cleanup_failed = true
|
|
244
245
|
ordinal = count.succ.to_s
|
|
245
|
-
|
|
246
|
+
info "~> Cleaning release directory: #{dir}"
|
|
246
247
|
sudo "ls -r #{dir} | tail -n +#{ordinal} | xargs -I@ rm -rf #{dir}/@"
|
|
247
248
|
@cleanup_failed = false
|
|
248
249
|
end
|
|
@@ -254,15 +255,15 @@ WRAP
|
|
|
254
255
|
c.release_path = c.previous_release(rolled_back_release)
|
|
255
256
|
|
|
256
257
|
revision = File.read(File.join(c.release_path, 'REVISION')).strip
|
|
257
|
-
|
|
258
|
+
info "~> Rolling back to previous release: #{short_log_message(revision)}"
|
|
258
259
|
|
|
259
260
|
run_with_callbacks(:symlink)
|
|
260
261
|
sudo "rm -rf #{rolled_back_release}"
|
|
261
262
|
bundle
|
|
262
|
-
|
|
263
|
+
info "~> Restarting with previous release."
|
|
263
264
|
with_maintenance_page { run_with_callbacks(:restart) }
|
|
264
265
|
else
|
|
265
|
-
|
|
266
|
+
info "~> Already at oldest release, nothing to roll back to."
|
|
266
267
|
exit(1)
|
|
267
268
|
end
|
|
268
269
|
end
|
|
@@ -273,17 +274,17 @@ WRAP
|
|
|
273
274
|
@migrations_reached = true
|
|
274
275
|
roles :app_master, :solo do
|
|
275
276
|
cmd = "cd #{c.release_path} && PATH=#{c.binstubs_path}:$PATH #{c.framework_envs} #{c.migration_command}"
|
|
276
|
-
|
|
277
|
+
info "~> Migrating: #{cmd}"
|
|
277
278
|
run(cmd)
|
|
278
279
|
end
|
|
279
280
|
end
|
|
280
281
|
|
|
281
282
|
# task
|
|
282
283
|
def copy_repository_cache
|
|
283
|
-
|
|
284
|
+
info "~> Copying to #{c.release_path}"
|
|
284
285
|
run("mkdir -p #{c.release_path} #{c.failed_release_dir} && rsync -aq #{c.exclusions} #{c.repository_cache}/ #{c.release_path}")
|
|
285
286
|
|
|
286
|
-
|
|
287
|
+
info "~> Ensuring proper ownership."
|
|
287
288
|
sudo("chown -R #{c.user}:#{c.group} #{c.deploy_to}")
|
|
288
289
|
end
|
|
289
290
|
|
|
@@ -304,7 +305,7 @@ WRAP
|
|
|
304
305
|
end
|
|
305
306
|
|
|
306
307
|
def setup_services
|
|
307
|
-
|
|
308
|
+
info "~> Setting up external services."
|
|
308
309
|
previously_configured_services = parse_configured_services
|
|
309
310
|
begin
|
|
310
311
|
sudo(services_command_check)
|
|
@@ -340,24 +341,24 @@ YML
|
|
|
340
341
|
WRAP
|
|
341
342
|
["Symlink database.yml", "ln -nfs #{c.shared_path}/config/database.sqlite3.yml #{c.release_path}/config/database.yml"],
|
|
342
343
|
].each do |what, cmd|
|
|
343
|
-
|
|
344
|
+
info "~> #{what}"
|
|
344
345
|
run(cmd)
|
|
345
346
|
end
|
|
346
347
|
|
|
347
348
|
owner = [c.user, c.group].join(':')
|
|
348
|
-
|
|
349
|
+
info "~> Setting ownership to #{owner}"
|
|
349
350
|
sudo "chown -R #{owner} #{c.release_path}"
|
|
350
351
|
end
|
|
351
352
|
end
|
|
352
353
|
|
|
353
354
|
def symlink_configs(release_to_link=c.release_path)
|
|
354
|
-
|
|
355
|
+
info "~> Preparing shared resources for release."
|
|
355
356
|
symlink_tasks(release_to_link).each do |what, cmd|
|
|
356
|
-
|
|
357
|
+
info "~> #{what}"
|
|
357
358
|
run(cmd)
|
|
358
359
|
end
|
|
359
360
|
owner = [c.user, c.group].join(':')
|
|
360
|
-
|
|
361
|
+
info "~> Setting ownership to #{owner}"
|
|
361
362
|
sudo "chown -R #{owner} #{release_to_link}"
|
|
362
363
|
end
|
|
363
364
|
|
|
@@ -380,7 +381,7 @@ WRAP
|
|
|
380
381
|
|
|
381
382
|
# task
|
|
382
383
|
def symlink(release_to_link=c.release_path)
|
|
383
|
-
|
|
384
|
+
info "~> Symlinking code."
|
|
384
385
|
run "rm -f #{c.current_path} && ln -nfs #{release_to_link} #{c.current_path} && chown -R #{c.user}:#{c.group} #{c.current_path}"
|
|
385
386
|
@symlink_changed = true
|
|
386
387
|
rescue Exception
|
|
@@ -428,9 +429,9 @@ WRAP
|
|
|
428
429
|
|
|
429
430
|
def puts_deploy_failure
|
|
430
431
|
if @cleanup_failed
|
|
431
|
-
|
|
432
|
+
info "~> [Relax] Your site is running new code, but clean up of old deploys failed."
|
|
432
433
|
elsif @maintenance_up
|
|
433
|
-
|
|
434
|
+
info "~> [Attention] Maintenance page still up, consider the following before removing:"
|
|
434
435
|
info " * Deploy hooks ran. This might cause problems for reverting to old code." if @callbacks_reached
|
|
435
436
|
info " * Migrations ran. This might cause problems for reverting to old code." if @migrations_reached
|
|
436
437
|
if @symlink_changed
|
|
@@ -440,9 +441,9 @@ WRAP
|
|
|
440
441
|
end
|
|
441
442
|
info " * Application servers failed to restart." if @restart_failed
|
|
442
443
|
info ""
|
|
443
|
-
|
|
444
|
+
info "~> Need help? File a ticket for support."
|
|
444
445
|
else
|
|
445
|
-
|
|
446
|
+
info "~> [Relax] Your site is still running old code and nothing destructive has occurred."
|
|
446
447
|
end
|
|
447
448
|
end
|
|
448
449
|
|
|
@@ -455,7 +456,7 @@ WRAP
|
|
|
455
456
|
def with_failed_release_cleanup
|
|
456
457
|
yield
|
|
457
458
|
rescue Exception
|
|
458
|
-
|
|
459
|
+
info "~> Release #{c.release_path} failed, saving release to #{c.failed_release_dir}."
|
|
459
460
|
sudo "mv #{c.release_path} #{c.failed_release_dir}"
|
|
460
461
|
raise
|
|
461
462
|
end
|
|
@@ -488,7 +489,7 @@ WRAP
|
|
|
488
489
|
|
|
489
490
|
def check_ruby_bundler
|
|
490
491
|
if gemfile?
|
|
491
|
-
|
|
492
|
+
info "~> Bundling gems..."
|
|
492
493
|
|
|
493
494
|
clean_bundle_on_system_version_change
|
|
494
495
|
|
|
@@ -522,7 +523,7 @@ WRAP
|
|
|
522
523
|
unless run(node_package_manager_command_check)
|
|
523
524
|
abort "*** [Error] package.json detected, but npm was not installed"
|
|
524
525
|
else
|
|
525
|
-
|
|
526
|
+
info "~> package.json detected, installing npm packages"
|
|
526
527
|
run "cd #{c.release_path} && npm install"
|
|
527
528
|
end
|
|
528
529
|
end
|
|
@@ -530,7 +531,7 @@ WRAP
|
|
|
530
531
|
end # DeployBase
|
|
531
532
|
|
|
532
533
|
class Deploy < DeployBase
|
|
533
|
-
def self.new(config
|
|
534
|
+
def self.new(config)
|
|
534
535
|
# include the correct fetch strategy
|
|
535
536
|
include EY::Serverside::Strategies.const_get(config.strategy)::Helpers
|
|
536
537
|
super
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module EY
|
|
2
2
|
module Serverside
|
|
3
3
|
class DeployHook < Task
|
|
4
|
-
def initialize(options
|
|
5
|
-
super(EY::Serverside::Deploy::Configuration.new(options)
|
|
4
|
+
def initialize(options)
|
|
5
|
+
super(EY::Serverside::Deploy::Configuration.new(options))
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def callback_context
|
|
@@ -3,14 +3,24 @@ module EY
|
|
|
3
3
|
def self.deprecation_warning(msg)
|
|
4
4
|
$stderr.puts "DEPRECATION WARNING: #{msg}"
|
|
5
5
|
end
|
|
6
|
+
end
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
end
|
|
8
|
+
def self.const_missing(const)
|
|
9
|
+
if EY::Serverside.const_defined?(const)
|
|
10
|
+
EY::Serverside.deprecation_warning("EY::#{const} has been deprecated. use EY::Serverside::#{const} instead")
|
|
11
|
+
EY::Serverside.class_eval(const.to_s)
|
|
12
|
+
else
|
|
13
|
+
super
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
def self.node
|
|
18
|
+
EY::Serverside.deprecation_warning("EY.node has been deprecated. use EY::Serverside.node instead")
|
|
19
|
+
EY::Serverside.node
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.dna_json
|
|
23
|
+
EY::Serverside.deprecation_warning("EY.dna_json has been deprecated. use EY::Serverside.dna_json instead")
|
|
24
|
+
EY::Serverside.dna_json
|
|
25
|
+
end
|
|
16
26
|
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require 'open4'
|
|
2
|
+
|
|
3
|
+
module EY
|
|
4
|
+
module Serverside
|
|
5
|
+
module LoggedOutput
|
|
6
|
+
|
|
7
|
+
class Tee
|
|
8
|
+
def initialize(*streams)
|
|
9
|
+
@streams = streams.flatten
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def <<(output)
|
|
13
|
+
@streams.each do |s|
|
|
14
|
+
s << output
|
|
15
|
+
s.flush
|
|
16
|
+
end
|
|
17
|
+
self
|
|
18
|
+
end
|
|
19
|
+
end # Tee
|
|
20
|
+
|
|
21
|
+
@@logfile = File.join(ENV['HOME'], 'ey.log')
|
|
22
|
+
def self.logfile=(filename)
|
|
23
|
+
File.unlink filename if File.exist?(filename) # start fresh
|
|
24
|
+
@@logfile = filename
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.logfile
|
|
28
|
+
@@logfile
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
@@verbose = false
|
|
32
|
+
def self.verbose=(v)
|
|
33
|
+
@@verbose = !!v
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.verbose?
|
|
37
|
+
@@verbose
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def verbose?
|
|
41
|
+
EY::Serverside::LoggedOutput.verbose?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def warning(msg)
|
|
45
|
+
info "WARNING: #{msg}\n".gsub(/^/,'!> ')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def info(msg)
|
|
49
|
+
with_logfile do |log|
|
|
50
|
+
Tee.new($stdout, log) << ("#{with_timestamp(msg)}\n")
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def debug(msg)
|
|
55
|
+
with_logfile do |log|
|
|
56
|
+
log << "#{with_timestamp(msg)}\n"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def logged_system(cmd)
|
|
61
|
+
with_logfile do |log|
|
|
62
|
+
out = verbose? ? Tee.new($stdout, log) : log
|
|
63
|
+
err = Tee.new($stderr, log) # we always want to see errors
|
|
64
|
+
|
|
65
|
+
out << with_timestamp(":: running #{cmd}\n")
|
|
66
|
+
|
|
67
|
+
# :quiet means don't raise an error on nonzero exit status
|
|
68
|
+
status = Open4.spawn cmd, 0 => '', 1 => out, 2 => err, :quiet => true
|
|
69
|
+
status.exitstatus == 0
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
def with_logfile
|
|
75
|
+
File.open(logfile, 'a') {|f| yield f }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def logfile
|
|
79
|
+
EY::Serverside::LoggedOutput.logfile
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def with_timestamp(msg)
|
|
83
|
+
return msg unless respond_to?(:starting_time)
|
|
84
|
+
time_passed = Time.now.to_i - starting_time.to_i
|
|
85
|
+
timestamp = "+%2dm %02ds " % time_passed.divmod(60)
|
|
86
|
+
msg.gsub(/^/, timestamp)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|