cloud-mu 3.1.2 → 3.2.0
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.
- checksums.yaml +4 -4
- data/Dockerfile +15 -3
- data/ansible/roles/mu-windows/README.md +33 -0
- data/ansible/roles/mu-windows/defaults/main.yml +2 -0
- data/ansible/roles/mu-windows/files/LaunchConfig.json +9 -0
- data/ansible/roles/mu-windows/files/config.xml +76 -0
- data/ansible/roles/mu-windows/handlers/main.yml +2 -0
- data/ansible/roles/mu-windows/meta/main.yml +53 -0
- data/ansible/roles/mu-windows/tasks/main.yml +36 -0
- data/ansible/roles/mu-windows/tests/inventory +2 -0
- data/ansible/roles/mu-windows/tests/test.yml +5 -0
- data/ansible/roles/mu-windows/vars/main.yml +2 -0
- data/bin/mu-adopt +10 -13
- data/bin/mu-azure-tests +57 -0
- data/bin/mu-cleanup +2 -4
- data/bin/mu-configure +52 -0
- data/bin/mu-deploy +3 -3
- data/bin/mu-findstray-tests +25 -0
- data/bin/mu-gen-docs +2 -4
- data/bin/mu-load-config.rb +2 -3
- data/bin/mu-node-manage +15 -16
- data/bin/mu-run-tests +135 -37
- data/cloud-mu.gemspec +22 -20
- data/cookbooks/mu-activedirectory/resources/domain.rb +4 -4
- data/cookbooks/mu-activedirectory/resources/domain_controller.rb +4 -4
- data/cookbooks/mu-tools/libraries/helper.rb +3 -2
- data/cookbooks/mu-tools/libraries/monkey.rb +35 -0
- data/cookbooks/mu-tools/recipes/apply_security.rb +14 -14
- data/cookbooks/mu-tools/recipes/aws_api.rb +9 -0
- data/cookbooks/mu-tools/recipes/eks.rb +2 -2
- data/cookbooks/mu-tools/recipes/google_api.rb +2 -2
- data/cookbooks/mu-tools/recipes/selinux.rb +2 -1
- data/cookbooks/mu-tools/recipes/windows-client.rb +163 -164
- data/cookbooks/mu-tools/resources/disk.rb +1 -1
- data/cookbooks/mu-tools/resources/windows_users.rb +44 -43
- data/extras/clean-stock-amis +25 -19
- data/extras/generate-stock-images +1 -0
- data/extras/image-generators/AWS/win2k12.yaml +18 -13
- data/extras/image-generators/AWS/win2k16.yaml +18 -13
- data/extras/image-generators/AWS/win2k19.yaml +21 -0
- data/extras/image-generators/Google/centos6.yaml +1 -0
- data/extras/image-generators/Google/centos7.yaml +1 -1
- data/modules/mommacat.ru +6 -16
- data/modules/mu.rb +165 -111
- data/modules/mu/adoption.rb +401 -68
- data/modules/mu/cleanup.rb +199 -306
- data/modules/mu/cloud.rb +100 -1632
- data/modules/mu/cloud/database.rb +49 -0
- data/modules/mu/cloud/dnszone.rb +46 -0
- data/modules/mu/cloud/machine_images.rb +212 -0
- data/modules/mu/cloud/providers.rb +81 -0
- data/modules/mu/cloud/resource_base.rb +920 -0
- data/modules/mu/cloud/server.rb +40 -0
- data/modules/mu/cloud/server_pool.rb +1 -0
- data/modules/mu/cloud/ssh_sessions.rb +228 -0
- data/modules/mu/cloud/winrm_sessions.rb +237 -0
- data/modules/mu/cloud/wrappers.rb +165 -0
- data/modules/mu/config.rb +171 -1767
- data/modules/mu/config/alarm.rb +2 -6
- data/modules/mu/config/bucket.rb +4 -4
- data/modules/mu/config/cache_cluster.rb +1 -1
- data/modules/mu/config/collection.rb +4 -4
- data/modules/mu/config/container_cluster.rb +9 -4
- data/modules/mu/config/database.rb +83 -104
- data/modules/mu/config/database.yml +1 -2
- data/modules/mu/config/dnszone.rb +6 -6
- data/modules/mu/config/doc_helpers.rb +516 -0
- data/modules/mu/config/endpoint.rb +4 -4
- data/modules/mu/config/firewall_rule.rb +103 -4
- data/modules/mu/config/folder.rb +4 -4
- data/modules/mu/config/function.rb +3 -3
- data/modules/mu/config/group.rb +4 -4
- data/modules/mu/config/habitat.rb +4 -4
- data/modules/mu/config/loadbalancer.rb +60 -14
- data/modules/mu/config/log.rb +4 -4
- data/modules/mu/config/msg_queue.rb +4 -4
- data/modules/mu/config/nosqldb.rb +4 -4
- data/modules/mu/config/notifier.rb +3 -3
- data/modules/mu/config/ref.rb +365 -0
- data/modules/mu/config/role.rb +4 -4
- data/modules/mu/config/schema_helpers.rb +509 -0
- data/modules/mu/config/search_domain.rb +4 -4
- data/modules/mu/config/server.rb +97 -70
- data/modules/mu/config/server.yml +1 -0
- data/modules/mu/config/server_pool.rb +5 -9
- data/modules/mu/config/storage_pool.rb +1 -1
- data/modules/mu/config/tail.rb +200 -0
- data/modules/mu/config/user.rb +4 -4
- data/modules/mu/config/vpc.rb +70 -27
- data/modules/mu/config/vpc.yml +0 -1
- data/modules/mu/defaults/AWS.yaml +83 -60
- data/modules/mu/defaults/Azure.yaml +1 -0
- data/modules/mu/defaults/Google.yaml +3 -2
- data/modules/mu/deploy.rb +30 -26
- data/modules/mu/groomer.rb +17 -2
- data/modules/mu/groomers/ansible.rb +188 -41
- data/modules/mu/groomers/chef.rb +116 -55
- data/modules/mu/logger.rb +127 -148
- data/modules/mu/master.rb +389 -2
- data/modules/mu/master/chef.rb +3 -4
- data/modules/mu/master/ldap.rb +3 -3
- data/modules/mu/master/ssl.rb +12 -3
- data/modules/mu/mommacat.rb +217 -2612
- data/modules/mu/mommacat/daemon.rb +397 -0
- data/modules/mu/mommacat/naming.rb +473 -0
- data/modules/mu/mommacat/search.rb +495 -0
- data/modules/mu/mommacat/storage.rb +722 -0
- data/modules/mu/{clouds → providers}/README.md +1 -1
- data/modules/mu/{clouds → providers}/aws.rb +271 -112
- data/modules/mu/{clouds → providers}/aws/alarm.rb +5 -3
- data/modules/mu/{clouds → providers}/aws/bucket.rb +26 -22
- data/modules/mu/{clouds → providers}/aws/cache_cluster.rb +33 -67
- data/modules/mu/{clouds → providers}/aws/collection.rb +24 -23
- data/modules/mu/{clouds → providers}/aws/container_cluster.rb +681 -721
- data/modules/mu/providers/aws/database.rb +1744 -0
- data/modules/mu/{clouds → providers}/aws/dnszone.rb +64 -63
- data/modules/mu/{clouds → providers}/aws/endpoint.rb +22 -27
- data/modules/mu/{clouds → providers}/aws/firewall_rule.rb +214 -244
- data/modules/mu/{clouds → providers}/aws/folder.rb +7 -7
- data/modules/mu/{clouds → providers}/aws/function.rb +17 -22
- data/modules/mu/{clouds → providers}/aws/group.rb +23 -23
- data/modules/mu/{clouds → providers}/aws/habitat.rb +17 -14
- data/modules/mu/{clouds → providers}/aws/loadbalancer.rb +57 -48
- data/modules/mu/{clouds → providers}/aws/log.rb +15 -12
- data/modules/mu/{clouds → providers}/aws/msg_queue.rb +17 -16
- data/modules/mu/{clouds → providers}/aws/nosqldb.rb +18 -11
- data/modules/mu/{clouds → providers}/aws/notifier.rb +11 -6
- data/modules/mu/{clouds → providers}/aws/role.rb +112 -86
- data/modules/mu/{clouds → providers}/aws/search_domain.rb +39 -33
- data/modules/mu/{clouds → providers}/aws/server.rb +835 -1133
- data/modules/mu/{clouds → providers}/aws/server_pool.rb +56 -60
- data/modules/mu/{clouds → providers}/aws/storage_pool.rb +24 -42
- data/modules/mu/{clouds → providers}/aws/user.rb +21 -22
- data/modules/mu/{clouds → providers}/aws/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/aws/userdata/windows.erb +2 -1
- data/modules/mu/{clouds → providers}/aws/vpc.rb +523 -929
- data/modules/mu/providers/aws/vpc_subnet.rb +286 -0
- data/modules/mu/{clouds → providers}/azure.rb +29 -9
- data/modules/mu/{clouds → providers}/azure/container_cluster.rb +3 -8
- data/modules/mu/{clouds → providers}/azure/firewall_rule.rb +18 -11
- data/modules/mu/{clouds → providers}/azure/habitat.rb +8 -6
- data/modules/mu/{clouds → providers}/azure/loadbalancer.rb +5 -5
- data/modules/mu/{clouds → providers}/azure/role.rb +8 -10
- data/modules/mu/{clouds → providers}/azure/server.rb +95 -48
- data/modules/mu/{clouds → providers}/azure/user.rb +6 -8
- data/modules/mu/{clouds → providers}/azure/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/azure/vpc.rb +16 -21
- data/modules/mu/{clouds → providers}/cloudformation.rb +18 -7
- data/modules/mu/{clouds → providers}/cloudformation/alarm.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/cache_cluster.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/collection.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/database.rb +6 -17
- data/modules/mu/{clouds → providers}/cloudformation/dnszone.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/firewall_rule.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/loadbalancer.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/log.rb +3 -3
- data/modules/mu/{clouds → providers}/cloudformation/server.rb +7 -7
- data/modules/mu/{clouds → providers}/cloudformation/server_pool.rb +5 -5
- data/modules/mu/{clouds → providers}/cloudformation/vpc.rb +5 -7
- data/modules/mu/{clouds → providers}/docker.rb +0 -0
- data/modules/mu/{clouds → providers}/google.rb +67 -30
- data/modules/mu/{clouds → providers}/google/bucket.rb +13 -15
- data/modules/mu/{clouds → providers}/google/container_cluster.rb +84 -77
- data/modules/mu/{clouds → providers}/google/database.rb +10 -20
- data/modules/mu/{clouds → providers}/google/firewall_rule.rb +15 -14
- data/modules/mu/{clouds → providers}/google/folder.rb +20 -17
- data/modules/mu/{clouds → providers}/google/function.rb +139 -167
- data/modules/mu/{clouds → providers}/google/group.rb +29 -34
- data/modules/mu/{clouds → providers}/google/habitat.rb +21 -22
- data/modules/mu/{clouds → providers}/google/loadbalancer.rb +18 -20
- data/modules/mu/{clouds → providers}/google/role.rb +92 -58
- data/modules/mu/{clouds → providers}/google/server.rb +242 -155
- data/modules/mu/{clouds → providers}/google/server_pool.rb +25 -44
- data/modules/mu/{clouds → providers}/google/user.rb +95 -31
- data/modules/mu/{clouds → providers}/google/userdata/README.md +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/linux.erb +0 -0
- data/modules/mu/{clouds → providers}/google/userdata/windows.erb +0 -0
- data/modules/mu/{clouds → providers}/google/vpc.rb +103 -79
- data/modules/tests/bucket.yml +4 -0
- data/modules/tests/centos6.yaml +11 -0
- data/modules/tests/centos7.yaml +11 -0
- data/modules/tests/centos8.yaml +12 -0
- data/modules/tests/ecs.yaml +23 -0
- data/modules/tests/includes-and-params.yaml +2 -1
- data/modules/tests/rds.yaml +108 -0
- data/modules/tests/regrooms/aws-iam.yaml +201 -0
- data/modules/tests/regrooms/bucket.yml +19 -0
- data/modules/tests/regrooms/rds.yaml +123 -0
- data/modules/tests/server-with-scrub-muisms.yaml +1 -0
- data/modules/tests/super_simple_bok.yml +1 -3
- data/modules/tests/win2k12.yaml +17 -5
- data/modules/tests/win2k16.yaml +25 -0
- data/modules/tests/win2k19.yaml +25 -0
- data/requirements.txt +1 -0
- data/spec/mu/clouds/azure_spec.rb +2 -2
- metadata +232 -154
- data/extras/image-generators/AWS/windows.yaml +0 -18
- data/modules/mu/clouds/aws/database.rb +0 -1985
data/modules/mu/groomers/chef.rb
CHANGED
|
@@ -35,6 +35,12 @@ module MU
|
|
|
35
35
|
end
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
# Are the Chef libraries present and accounted for?
|
|
39
|
+
def self.available?(windows = false)
|
|
40
|
+
loadChefLib
|
|
41
|
+
@chefloaded
|
|
42
|
+
end
|
|
43
|
+
|
|
38
44
|
@chefloaded = false
|
|
39
45
|
@chefload_semaphore = Mutex.new
|
|
40
46
|
# Autoload is too brain-damaged to get Chef's subclasses/submodules, so
|
|
@@ -184,13 +190,13 @@ module MU
|
|
|
184
190
|
if !item.nil?
|
|
185
191
|
begin
|
|
186
192
|
loaded = ::ChefVault::Item.load(vault, item)
|
|
187
|
-
rescue ::ChefVault::Exceptions::KeysNotFound
|
|
193
|
+
rescue ::ChefVault::Exceptions::KeysNotFound
|
|
188
194
|
raise MuNoSuchSecret, "Can't load the Chef Vault #{vault}:#{item}. Does it exist? Chef user: #{MU.chef_user}"
|
|
189
195
|
end
|
|
190
196
|
else
|
|
191
197
|
# If we didn't ask for a particular item, list what we have.
|
|
192
198
|
begin
|
|
193
|
-
loaded = ::Chef::DataBag.load(vault).keys.select { |k
|
|
199
|
+
loaded = ::Chef::DataBag.load(vault).keys.select { |k| !k.match(/_keys$/) }
|
|
194
200
|
rescue Net::HTTPServerException
|
|
195
201
|
raise MuNoSuchSecret, "Failed to retrieve Vault #{vault}"
|
|
196
202
|
end
|
|
@@ -258,7 +264,6 @@ module MU
|
|
|
258
264
|
knifeAddToRunList(multiple: @config['run_list'])
|
|
259
265
|
end
|
|
260
266
|
|
|
261
|
-
pending_reboot_count = 0
|
|
262
267
|
chef_node = ::Chef::Node.load(@server.mu_name)
|
|
263
268
|
if !@config['application_attributes'].nil?
|
|
264
269
|
MU.log "Setting node:#{@server.mu_name} application_attributes", MU::DEBUG, details: @config['application_attributes']
|
|
@@ -300,7 +305,7 @@ module MU
|
|
|
300
305
|
cmd = "#{upgrade_cmd} chef-client --color || echo #{error_signal}"
|
|
301
306
|
end
|
|
302
307
|
Timeout::timeout(timeout) {
|
|
303
|
-
|
|
308
|
+
ssh.exec!(cmd) { |_ch, _stream, data|
|
|
304
309
|
extra_logfile = if Dir.exist?(@server.deploy.deploy_dir)
|
|
305
310
|
File.open(@server.deploy.deploy_dir+"/log", "a")
|
|
306
311
|
end
|
|
@@ -330,7 +335,7 @@ module MU
|
|
|
330
335
|
}
|
|
331
336
|
else
|
|
332
337
|
MU.log "Invoking Chef over WinRM on #{@server.mu_name}: #{purpose}"
|
|
333
|
-
winrm = @server.getWinRMSession(haveBootstrapped? ?
|
|
338
|
+
winrm = @server.getWinRMSession(haveBootstrapped? ? 2 : max_retries)
|
|
334
339
|
if @server.windows? and @server.windowsRebootPending?(winrm)
|
|
335
340
|
# Windows frequently gets stuck here
|
|
336
341
|
if retries > 5
|
|
@@ -363,7 +368,7 @@ module MU
|
|
|
363
368
|
}
|
|
364
369
|
|
|
365
370
|
if resp.exitcode == 1 and output_lines.join("\n").match(/Chef Client finished/)
|
|
366
|
-
MU.log
|
|
371
|
+
MU.log output_lines.last
|
|
367
372
|
elsif resp.exitcode != 0
|
|
368
373
|
raise MU::Cloud::BootstrapTempFail if resp.exitcode == 35 or output_lines.join("\n").match(/REBOOT_SCHEDULED| WARN: Reboot requested:|Rebooting server at a recipe's request|Chef::Exceptions::Reboot/)
|
|
369
374
|
raise MU::Groomer::RunError, output_lines.slice(output_lines.length-50, output_lines.length).join("")
|
|
@@ -380,7 +385,7 @@ module MU
|
|
|
380
385
|
sleep 30
|
|
381
386
|
end
|
|
382
387
|
retry
|
|
383
|
-
rescue
|
|
388
|
+
rescue SystemExit, Timeout::Error, MU::Cloud::BootstrapTempFail, Net::HTTPServerException, HTTPClient::ConnectTimeoutError, WinRM::WinRMError, Net::SSH::AuthenticationFailed, Net::SSH::Disconnect, Net::SSH::ConnectionTimeout, Net::SSH::Proxy::ConnectError, Net::SSH::Exception, Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::EPIPE, SocketError, IOError => e
|
|
384
389
|
begin
|
|
385
390
|
ssh.close if !ssh.nil?
|
|
386
391
|
rescue Net::SSH::Exception, IOError => e
|
|
@@ -390,6 +395,8 @@ module MU
|
|
|
390
395
|
MU.log "ssh session to #{@server.mu_name} was closed unexpectedly, waiting before trying again", MU::NOTICE
|
|
391
396
|
end
|
|
392
397
|
sleep 10
|
|
398
|
+
rescue StandardError => e
|
|
399
|
+
MU.log "Error I don't recognize closing ssh tunnel", MU::WARN, details: e.inspect
|
|
393
400
|
end
|
|
394
401
|
if e.instance_of?(MU::Groomer::RunError) and retries == 0 and max_retries > 1 and purpose != "Base Windows configuration"
|
|
395
402
|
MU.log "Got a run error, will attempt to install/update Chef Client on next attempt", MU::NOTICE
|
|
@@ -404,7 +411,7 @@ module MU
|
|
|
404
411
|
begin
|
|
405
412
|
preClean(true) # drop any Chef install that's not ours
|
|
406
413
|
@server.reboot # try gently rebooting the thing
|
|
407
|
-
rescue
|
|
414
|
+
rescue StandardError => e # it's ok to fail here (and to ignore failure)
|
|
408
415
|
MU.log "preclean err #{e.inspect}", MU::ERR
|
|
409
416
|
end
|
|
410
417
|
reboot_first_fail = false
|
|
@@ -414,9 +421,9 @@ module MU
|
|
|
414
421
|
if retries < max_retries
|
|
415
422
|
retries += 1
|
|
416
423
|
MU.log "#{@server.mu_name}: Chef run '#{purpose}' failed after #{Time.new - runstart} seconds, retrying (#{retries}/#{max_retries})", MU::WARN, details: e.message.dup
|
|
417
|
-
if purpose != "Base Windows configuration"
|
|
418
|
-
windows_try_ssh = !windows_try_ssh
|
|
419
|
-
end
|
|
424
|
+
# if purpose != "Base Windows configuration"
|
|
425
|
+
# windows_try_ssh = !windows_try_ssh
|
|
426
|
+
# end
|
|
420
427
|
if e.is_a?(WinRM::WinRMError)
|
|
421
428
|
if @server.windows? and retries >= 3 and retries % 3 == 0
|
|
422
429
|
# Mix in a hard reboot if WinRM isn't answering
|
|
@@ -429,7 +436,7 @@ module MU
|
|
|
429
436
|
@server.deploy.sendAdminSlack("Chef run '#{purpose}' failed on `#{@server.mu_name}` :crying_cat_face:", msg: e.message)
|
|
430
437
|
raise MU::Groomer::RunError, "#{@server.mu_name}: Chef run '#{purpose}' failed #{max_retries} times, last error was: #{e.message}"
|
|
431
438
|
end
|
|
432
|
-
rescue
|
|
439
|
+
rescue StandardError => e
|
|
433
440
|
@server.deploy.sendAdminSlack("Chef run '#{purpose}' failed on `#{@server.mu_name}` :crying_cat_face:", msg: e.inspect)
|
|
434
441
|
raise MU::Groomer::RunError, "Caught unexpected #{e.inspect} on #{@server.mu_name} in @groomer.run at #{e.backtrace[0]}"
|
|
435
442
|
|
|
@@ -443,8 +450,8 @@ module MU
|
|
|
443
450
|
def splunkVaultInit
|
|
444
451
|
self.class.loadChefLib
|
|
445
452
|
begin
|
|
446
|
-
|
|
447
|
-
rescue ::ChefVault::Exceptions::KeysNotFound
|
|
453
|
+
::ChefVault::Item.load("splunk", "admin_user")
|
|
454
|
+
rescue ::ChefVault::Exceptions::KeysNotFound
|
|
448
455
|
pw = Password.pronounceable(12..14)
|
|
449
456
|
creds = {
|
|
450
457
|
"username" => "admin",
|
|
@@ -550,7 +557,7 @@ module MU
|
|
|
550
557
|
winrm = @server.getWinRMSession(1, 30, winrm_retries: 2)
|
|
551
558
|
pp winrm.run(cmd)
|
|
552
559
|
return
|
|
553
|
-
rescue
|
|
560
|
+
rescue SystemExit, Timeout::Error, MU::Cloud::BootstrapTempFail, MU::MuError, Net::HTTPServerException, HTTPClient::ConnectTimeoutError, WinRM::WinRMError, Net::SSH::AuthenticationFailed, Net::SSH::Disconnect, Net::SSH::ConnectionTimeout, Net::SSH::Proxy::ConnectError, Net::SSH::Exception, Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::EPIPE, SocketError, IOError
|
|
554
561
|
MU.log "WinRM failure attempting Chef upgrade on #{@server.mu_name}, will fall back to ssh", MU::WARN
|
|
555
562
|
cmd = %Q{powershell.exe -inputformat none -noprofile "#{cmd}"}
|
|
556
563
|
end
|
|
@@ -558,7 +565,7 @@ module MU
|
|
|
558
565
|
|
|
559
566
|
MU.log "Attempting Chef upgrade via ssh on #{@server.mu_name}", MU::NOTICE, details: cmd
|
|
560
567
|
ssh = @server.getSSHSession(1)
|
|
561
|
-
|
|
568
|
+
ssh.exec!(cmd) { |_ch, _stream, data|
|
|
562
569
|
puts data
|
|
563
570
|
}
|
|
564
571
|
end
|
|
@@ -580,7 +587,7 @@ module MU
|
|
|
580
587
|
@config['cleaned_chef'] = true
|
|
581
588
|
end
|
|
582
589
|
|
|
583
|
-
|
|
590
|
+
_nat_ssh_key, _nat_ssh_user, _nat_ssh_host, canonical_addr, ssh_user, ssh_key_name = @server.getSSHConfig
|
|
584
591
|
|
|
585
592
|
MU.log "Bootstrapping #{@server.mu_name} (#{canonical_addr}) with knife"
|
|
586
593
|
|
|
@@ -593,11 +600,12 @@ module MU
|
|
|
593
600
|
json_attribs['skipinitialupdates'] = @config['skipinitialupdates']
|
|
594
601
|
end
|
|
595
602
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
603
|
+
# XXX this seems to break Knife Bootstrap
|
|
604
|
+
# vault_access = if !@config['vault_access'].nil?
|
|
605
|
+
# @config['vault_access']
|
|
606
|
+
# else
|
|
607
|
+
# []
|
|
608
|
+
# end
|
|
601
609
|
|
|
602
610
|
@server.windows? ? max_retries = 25 : max_retries = 10
|
|
603
611
|
@server.windows? ? timeout = 1800 : timeout = 300
|
|
@@ -617,13 +625,20 @@ module MU
|
|
|
617
625
|
kb.name_args = [@server.mu_name]
|
|
618
626
|
kb.config[:manual] = true
|
|
619
627
|
kb.config[:winrm_transport] = :ssl
|
|
620
|
-
kb.config[:host] = @server.mu_name
|
|
621
628
|
kb.config[:winrm_port] = 5986
|
|
622
629
|
kb.config[:session_timeout] = timeout
|
|
623
630
|
kb.config[:operation_timeout] = timeout
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
631
|
+
if retries % 2 == 0
|
|
632
|
+
kb.config[:host] = canonical_addr
|
|
633
|
+
kb.config[:winrm_authentication_protocol] = :basic
|
|
634
|
+
kb.config[:winrm_user] = @server.config['windows_admin_username']
|
|
635
|
+
kb.config[:winrm_password] = @server.getWindowsAdminPassword
|
|
636
|
+
else
|
|
637
|
+
kb.config[:host] = @server.mu_name
|
|
638
|
+
kb.config[:winrm_authentication_protocol] = :cert
|
|
639
|
+
kb.config[:winrm_client_cert] = "#{MU.mySSLDir}/#{@server.mu_name}-winrm.crt"
|
|
640
|
+
kb.config[:winrm_client_key] = "#{MU.mySSLDir}/#{@server.mu_name}-winrm.key"
|
|
641
|
+
end
|
|
627
642
|
# kb.config[:ca_trust_file] = "#{MU.mySSLDir}/Mu_CA.pem"
|
|
628
643
|
# XXX ca_trust_file doesn't work for some reason, so we have to set the below for now
|
|
629
644
|
kb.config[:winrm_ssl_verify_mode] = :verify_none
|
|
@@ -658,7 +673,7 @@ module MU
|
|
|
658
673
|
}
|
|
659
674
|
# throws Net::HTTPServerException if we haven't really bootstrapped
|
|
660
675
|
::Chef::Node.load(@server.mu_name)
|
|
661
|
-
rescue
|
|
676
|
+
rescue SystemExit, Timeout::Error, MU::Cloud::BootstrapTempFail, Net::HTTPServerException, HTTPClient::ConnectTimeoutError, WinRM::WinRMError, Net::SSH::AuthenticationFailed, Net::SSH::Disconnect, Net::SSH::ConnectionTimeout, Net::SSH::Proxy::ConnectError, Net::SSH::Exception, Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ECONNREFUSED, Errno::EPIPE, SocketError, IOError => e
|
|
662
677
|
if retries < max_retries
|
|
663
678
|
retries += 1
|
|
664
679
|
# Bad Chef installs are possible culprits of bootstrap failures, so
|
|
@@ -671,9 +686,9 @@ module MU
|
|
|
671
686
|
!@config['forced_preclean']
|
|
672
687
|
begin
|
|
673
688
|
preClean(false) # it's ok for this to fail
|
|
674
|
-
rescue
|
|
689
|
+
rescue StandardError => e
|
|
675
690
|
end
|
|
676
|
-
MU::Groomer::Chef.
|
|
691
|
+
MU::Groomer::Chef.purge(@server.mu_name, nodeonly: true)
|
|
677
692
|
@config['forced_preclean'] = true
|
|
678
693
|
@server.reboot if @server.windows? # *sigh*
|
|
679
694
|
end
|
|
@@ -683,7 +698,7 @@ module MU
|
|
|
683
698
|
else
|
|
684
699
|
raise MuError, "#{@server.mu_name}: Knife Bootstrap failed too many times with #{e.inspect}"
|
|
685
700
|
end
|
|
686
|
-
rescue
|
|
701
|
+
rescue StandardError => e
|
|
687
702
|
MU.log e.inspect, MU::ERR, details: e.backtrace
|
|
688
703
|
sleep 10*retries
|
|
689
704
|
retry
|
|
@@ -700,7 +715,7 @@ retry
|
|
|
700
715
|
end
|
|
701
716
|
}
|
|
702
717
|
knifeAddToRunList("role[mu-node]")
|
|
703
|
-
knifeAddToRunList("mu-tools::selinux")
|
|
718
|
+
knifeAddToRunList("recipe[mu-tools::selinux]")
|
|
704
719
|
|
|
705
720
|
grantSecretAccess(@server.mu_name, "windows_credentials") if @server.windows?
|
|
706
721
|
grantSecretAccess(@server.mu_name, "ssl_cert")
|
|
@@ -748,7 +763,7 @@ retry
|
|
|
748
763
|
return
|
|
749
764
|
end
|
|
750
765
|
|
|
751
|
-
@server.describe
|
|
766
|
+
@server.describe
|
|
752
767
|
saveChefMetadata
|
|
753
768
|
begin
|
|
754
769
|
chef_node = ::Chef::Node.load(@server.mu_name)
|
|
@@ -785,17 +800,57 @@ retry
|
|
|
785
800
|
chef_node.save
|
|
786
801
|
end
|
|
787
802
|
return chef_node['deployment']
|
|
788
|
-
rescue Net::HTTPServerException
|
|
803
|
+
rescue Net::HTTPServerException
|
|
789
804
|
MU.log "Attempted to save deployment to Chef node #{@server.mu_name} before it was bootstrapped.", MU::DEBUG
|
|
790
805
|
end
|
|
791
806
|
end
|
|
792
807
|
|
|
808
|
+
# Purge Chef resources matching a particular deploy
|
|
809
|
+
# @param deploy_id [String]
|
|
810
|
+
# @param noop [Boolean]
|
|
811
|
+
def self.cleanup(deploy_id, noop = false)
|
|
812
|
+
return nil if deploy_id.nil? or deploy_id.empty?
|
|
813
|
+
begin
|
|
814
|
+
if File.exist?(Etc.getpwuid(Process.uid).dir+"/.chef/knife.rb")
|
|
815
|
+
::Chef::Config.from_file(Etc.getpwuid(Process.uid).dir+"/.chef/knife.rb")
|
|
816
|
+
end
|
|
817
|
+
deadnodes = []
|
|
818
|
+
::Chef::Config[:environment] ||= MU.environment
|
|
819
|
+
q = ::Chef::Search::Query.new
|
|
820
|
+
begin
|
|
821
|
+
q.search("node", "tags_MU-ID:#{deploy_id}").each { |item|
|
|
822
|
+
next if item.is_a?(Integer)
|
|
823
|
+
item.each { |node|
|
|
824
|
+
deadnodes << node.name
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
rescue Net::HTTPServerException
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
begin
|
|
831
|
+
q.search("node", "name:#{deploy_id}-*").each { |item|
|
|
832
|
+
next if item.is_a?(Integer)
|
|
833
|
+
item.each { |node|
|
|
834
|
+
deadnodes << node.name
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
rescue Net::HTTPServerException
|
|
838
|
+
end
|
|
839
|
+
MU.log "Missed some Chef resources in node cleanup, purging now", MU::NOTICE if deadnodes.size > 0
|
|
840
|
+
deadnodes.uniq.each { |node|
|
|
841
|
+
MU::Groomer::Chef.purge(node, [], noop)
|
|
842
|
+
}
|
|
843
|
+
rescue LoadError
|
|
844
|
+
end
|
|
845
|
+
|
|
846
|
+
end
|
|
847
|
+
|
|
793
848
|
# Expunge Chef resources associated with a node.
|
|
794
849
|
# @param node [String]: The Mu name of the node in question.
|
|
795
850
|
# @param vaults_to_clean [Array<Hash>]: Some vaults to expunge
|
|
796
851
|
# @param noop [Boolean]: Skip actual deletion, just state what we'd do
|
|
797
852
|
# @param nodeonly [Boolean]: Just delete the node and its keys, but leave other artifacts
|
|
798
|
-
def self.
|
|
853
|
+
def self.purge(node, vaults_to_clean = [], noop = false, nodeonly: false)
|
|
799
854
|
loadChefLib
|
|
800
855
|
MU.log "Deleting Chef resources associated with #{node}"
|
|
801
856
|
if !nodeonly
|
|
@@ -804,7 +859,7 @@ retry
|
|
|
804
859
|
MU.log "knife vault remove #{vault['vault']} #{vault['item']} --search name:#{node}", MU::NOTICE
|
|
805
860
|
begin
|
|
806
861
|
::Chef::Knife.run(['vault', 'remove', vault['vault'], vault['item'], "--search", "name:#{node}"]) if !noop
|
|
807
|
-
rescue
|
|
862
|
+
rescue StandardError => e
|
|
808
863
|
MU.log "Error removing vault access for #{node} from #{vault['vault']} #{vault['item']}", MU::ERR, details: e.inspect
|
|
809
864
|
end
|
|
810
865
|
MU::MommaCat.unlock("vault-#{vault['vault']}")
|
|
@@ -858,7 +913,7 @@ retry
|
|
|
858
913
|
::Chef::Knife.run(['vault', 'refresh', vault['vault'], vault['item']])
|
|
859
914
|
end
|
|
860
915
|
end
|
|
861
|
-
rescue JSON::ParserError
|
|
916
|
+
rescue JSON::ParserError
|
|
862
917
|
MU.log "Error parsing JSON from data bag #{vault['vault']} #{vault['item']}_keys, skipping vault client cleanse", MU::WARN
|
|
863
918
|
end
|
|
864
919
|
end
|
|
@@ -887,18 +942,34 @@ retry
|
|
|
887
942
|
MU.log "Granting #{host} access to #{vault} #{item}"
|
|
888
943
|
begin
|
|
889
944
|
::Chef::Knife.run(['vault', 'update', vault, item, "--search", "name:#{host}"])
|
|
890
|
-
rescue
|
|
945
|
+
rescue StandardError => e
|
|
891
946
|
MU.log e.inspect, MU::ERR, details: caller
|
|
892
947
|
end
|
|
893
948
|
MU::MommaCat.unlock("vault-#{vault}", true)
|
|
894
949
|
end
|
|
895
950
|
|
|
951
|
+
# Execute a +knife+ command, and return its exit status and output
|
|
952
|
+
# @param cmd [String]: The knife subcommand to run, such as +vault list+
|
|
953
|
+
# @param showoutput [String]: Print the results to stdout
|
|
954
|
+
# @return [Array<Integer,String>]
|
|
955
|
+
def self.knifeCmd(cmd, showoutput = false)
|
|
956
|
+
MU.log "knife #{cmd}", MU::NOTICE if showoutput
|
|
957
|
+
output = `#{MU::Groomer::Chef.knife} #{cmd}`
|
|
958
|
+
exitstatus = $?.exitstatus
|
|
959
|
+
|
|
960
|
+
if showoutput
|
|
961
|
+
puts output
|
|
962
|
+
puts "Exit status: #{exitstatus}"
|
|
963
|
+
end
|
|
964
|
+
return [exitstatus, output]
|
|
965
|
+
end
|
|
966
|
+
|
|
896
967
|
private
|
|
897
968
|
|
|
898
969
|
# Save common Mu attributes to this node's Chef node structure.
|
|
899
970
|
def saveChefMetadata
|
|
900
971
|
self.class.loadChefLib
|
|
901
|
-
|
|
972
|
+
@server.getSSHConfig # why though
|
|
902
973
|
MU.log "Saving #{@server.mu_name} Chef artifacts"
|
|
903
974
|
|
|
904
975
|
begin
|
|
@@ -998,7 +1069,7 @@ retry
|
|
|
998
1069
|
deploy = MU::MommaCat.getLitter(MU.deploy_id, use_cache: false)
|
|
999
1070
|
@config['dependencies'].each{ |dep|
|
|
1000
1071
|
if dep['type'] == "database" && deploy.deployment.has_key?("databases") && deploy.deployment["databases"].has_key?(dep['name'])
|
|
1001
|
-
deploy.deployment["databases"][dep['name']].each { |
|
|
1072
|
+
deploy.deployment["databases"][dep['name']].values.each { |database|
|
|
1002
1073
|
grantSecretAccess(database['vault_name'], database['vault_item']) if database.has_key?("vault_name") && database.has_key?("vault_item")
|
|
1003
1074
|
}
|
|
1004
1075
|
end
|
|
@@ -1019,18 +1090,6 @@ retry
|
|
|
1019
1090
|
@secrets_granted["#{vault}:#{item}"] = item
|
|
1020
1091
|
end
|
|
1021
1092
|
|
|
1022
|
-
def self.knifeCmd(cmd, showoutput = false)
|
|
1023
|
-
MU.log "knife #{cmd}", MU::NOTICE if showoutput
|
|
1024
|
-
output = `#{MU::Groomer::Chef.knife} #{cmd}`
|
|
1025
|
-
exitstatus = $?.exitstatus
|
|
1026
|
-
|
|
1027
|
-
if showoutput
|
|
1028
|
-
puts output
|
|
1029
|
-
puts "Exit status: #{exitstatus}"
|
|
1030
|
-
end
|
|
1031
|
-
return [exitstatus, output]
|
|
1032
|
-
end
|
|
1033
|
-
|
|
1034
1093
|
def knifeCmd(cmd, showoutput = false)
|
|
1035
1094
|
self.class.knifeCmd(cmd, showoutput)
|
|
1036
1095
|
end
|
|
@@ -1063,9 +1122,11 @@ retry
|
|
|
1063
1122
|
if multiple.size == 0
|
|
1064
1123
|
multiple = [rl_entry]
|
|
1065
1124
|
end
|
|
1066
|
-
multiple.
|
|
1125
|
+
multiple.map! { |entry|
|
|
1067
1126
|
if !entry.match(/^role|recipe\[/)
|
|
1068
|
-
|
|
1127
|
+
"#{type}[#{entry}]"
|
|
1128
|
+
else
|
|
1129
|
+
entry
|
|
1069
1130
|
end
|
|
1070
1131
|
}
|
|
1071
1132
|
|
|
@@ -1110,8 +1171,8 @@ retry
|
|
|
1110
1171
|
MU.log("Adding #{rl_string} to Chef run_list of #{@server.mu_name}")
|
|
1111
1172
|
MU.log("Running #{query}", MU::DEBUG)
|
|
1112
1173
|
output=%x{#{query}}
|
|
1113
|
-
# XXX rescue
|
|
1114
|
-
rescue
|
|
1174
|
+
# XXX rescue StandardError is bad style
|
|
1175
|
+
rescue StandardError => e
|
|
1115
1176
|
raise MuError, "FAIL: #{MU::Groomer::Chef.knife} node run_list add #{@server.mu_name} \"#{rl_string}\": #{e.message} (output was #{output})"
|
|
1116
1177
|
end
|
|
1117
1178
|
end
|
data/modules/mu/logger.rb
CHANGED
|
@@ -33,6 +33,33 @@ module MU
|
|
|
33
33
|
# Show DEBUG log entries and extra call stack and threading info
|
|
34
34
|
LOUD = 2.freeze
|
|
35
35
|
|
|
36
|
+
# stash a hash map for color outputs
|
|
37
|
+
COLORMAP = {
|
|
38
|
+
MU::DEBUG => { :html => "orange", :ansi => :yellow },
|
|
39
|
+
MU::INFO => { :html => "green", :ansi => :green },
|
|
40
|
+
MU::NOTICE => { :html => "yellow", :ansi => :yellow },
|
|
41
|
+
MU::WARN => { :html => "orange", :ansi => :light_red },
|
|
42
|
+
MU::ERR => { :html => "red", :ansi => :red }
|
|
43
|
+
}.freeze
|
|
44
|
+
|
|
45
|
+
# minimum log verbosity at which we'll print various types of messages
|
|
46
|
+
PRINT_MSG_IF = {
|
|
47
|
+
MU::DEBUG => { :msg => LOUD, :details => LOUD },
|
|
48
|
+
MU::INFO => { :msg => NORMAL, :details => LOUD },
|
|
49
|
+
MU::NOTICE => { :msg => nil, :details => QUIET },
|
|
50
|
+
MU::WARN => { :msg => nil, :details => SILENT },
|
|
51
|
+
MU::ERR => { :msg => nil, :details => nil }
|
|
52
|
+
}.freeze
|
|
53
|
+
|
|
54
|
+
# Syslog equivalents of our log levels
|
|
55
|
+
SYSLOG_MAP = {
|
|
56
|
+
MU::DEBUG => Syslog::LOG_DEBUG,
|
|
57
|
+
MU::INFO => Syslog::LOG_NOTICE,
|
|
58
|
+
MU::NOTICE => Syslog::LOG_NOTICE,
|
|
59
|
+
MU::WARN => Syslog::LOG_WARNING,
|
|
60
|
+
MU::ERR => Syslog::LOG_ERR
|
|
61
|
+
}.freeze
|
|
62
|
+
|
|
36
63
|
attr_accessor :verbosity
|
|
37
64
|
@verbosity = MU::Logger::NORMAL
|
|
38
65
|
@quiet = false
|
|
@@ -66,66 +93,38 @@ module MU
|
|
|
66
93
|
def log(msg,
|
|
67
94
|
level=INFO,
|
|
68
95
|
details: nil,
|
|
69
|
-
html:
|
|
70
|
-
verbosity:
|
|
71
|
-
handle:
|
|
72
|
-
color:
|
|
96
|
+
html: nil,
|
|
97
|
+
verbosity: nil,
|
|
98
|
+
handle: nil,
|
|
99
|
+
color: nil,
|
|
73
100
|
deploy: MU.mommacat
|
|
74
101
|
)
|
|
75
102
|
verbosity ||= @verbosity
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
103
|
+
html ||= @html
|
|
104
|
+
handle ||= @handle
|
|
105
|
+
color ||= @color
|
|
79
106
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
mod_root = Regexp.quote("#{ENV['MU_LIBDIR']}/modules/mu/")
|
|
84
|
-
bin_root = Regexp.quote("#{ENV['MU_INSTALLDIR']}/bin/")
|
|
85
|
-
caller_name = caller[1]
|
|
107
|
+
if verbosity == MU::Logger::SILENT or (verbosity < MU::Logger::LOUD and level == DEBUG) or (verbosity < MU::Logger::NORMAL and level == INFO)
|
|
108
|
+
return
|
|
109
|
+
end
|
|
86
110
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
caller_name
|
|
93
|
-
caller_name.sub!(/^modules\//, "")
|
|
111
|
+
if level == SUMMARY
|
|
112
|
+
@summary << msg
|
|
113
|
+
return
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
caller_name = extract_caller_name(caller[1])
|
|
94
117
|
|
|
95
118
|
time = Time.now.strftime("%b %d %H:%M:%S").to_s
|
|
96
119
|
|
|
97
120
|
Syslog.open("Mu/"+caller_name, Syslog::LOG_PID, Syslog::LOG_DAEMON | Syslog::LOG_LOCAL3) if !Syslog.opened?
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
details = details[:details]
|
|
101
|
-
end
|
|
102
|
-
details = PP.pp(details, '') if !details.is_a?(String)
|
|
103
|
-
end
|
|
104
|
-
details = "<pre>"+details+"</pre>" if @html
|
|
105
|
-
# We get passed literal quoted newlines sometimes, fix 'em. Get Windows'
|
|
106
|
-
# ugly line feeds too.
|
|
107
|
-
if !details.nil?
|
|
108
|
-
details = details.dup # in case it's frozen or something
|
|
109
|
-
details.gsub!(/\\n/, "\n")
|
|
110
|
-
details.gsub!(/(\\r|\r)/, "")
|
|
111
|
-
end
|
|
121
|
+
|
|
122
|
+
details = format_details(details, html)
|
|
112
123
|
|
|
113
124
|
msg = msg.first if msg.is_a?(Array)
|
|
114
125
|
msg = "" if msg == nil
|
|
115
126
|
msg = msg.to_s if !msg.is_a?(String) and msg.respond_to?(:to_s)
|
|
116
127
|
|
|
117
|
-
# wrapper for writing a log entry to multiple filehandles
|
|
118
|
-
# @param handles [Array<IO>]
|
|
119
|
-
# @param msgs [Array<String>]
|
|
120
|
-
def write(handles = [], msgs = [])
|
|
121
|
-
return if handles.nil? or msgs.nil?
|
|
122
|
-
handles.each { |h|
|
|
123
|
-
msgs.each { |m|
|
|
124
|
-
h.puts m
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
end
|
|
128
|
-
|
|
129
128
|
@@log_semaphere.synchronize {
|
|
130
129
|
handles = [handle]
|
|
131
130
|
extra_logfile = if deploy and deploy.deploy_dir and Dir.exist?(deploy.deploy_dir)
|
|
@@ -134,110 +133,41 @@ module MU
|
|
|
134
133
|
handles << extra_logfile if extra_logfile
|
|
135
134
|
msgs = []
|
|
136
135
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
end
|
|
152
|
-
Syslog.log(Syslog::LOG_DEBUG, msg.gsub(/%/, ''))
|
|
153
|
-
Syslog.log(Syslog::LOG_DEBUG, details.gsub(/%/, '')) if details
|
|
154
|
-
end
|
|
155
|
-
when INFO
|
|
156
|
-
if verbosity >= MU::Logger::NORMAL
|
|
157
|
-
if @html
|
|
158
|
-
html_out "#{time} - #{caller_name} - #{msg}", "green"
|
|
159
|
-
elsif color
|
|
160
|
-
msgs << "#{time} - #{caller_name} - #{msg}".green.on_black
|
|
161
|
-
else
|
|
162
|
-
msgs << "#{time} - #{caller_name} - #{msg}"
|
|
163
|
-
end
|
|
164
|
-
if verbosity >= MU::Logger::LOUD
|
|
165
|
-
if @html
|
|
166
|
-
html_out " #{details}"
|
|
167
|
-
elsif color
|
|
168
|
-
msgs << "#{details}".white.on_black if details
|
|
169
|
-
else
|
|
170
|
-
msgs << "#{details}" if details
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
Syslog.log(Syslog::LOG_NOTICE, msg.gsub(/%/, ''))
|
|
174
|
-
Syslog.log(Syslog::LOG_NOTICE, details.gsub(/%/, '')) if details
|
|
175
|
-
end
|
|
176
|
-
when NOTICE
|
|
177
|
-
if @html
|
|
178
|
-
html_out "#{time} - #{caller_name} - #{msg}", "yellow"
|
|
179
|
-
elsif color
|
|
180
|
-
msgs << "#{time} - #{caller_name} - #{msg}".yellow.on_black
|
|
181
|
-
else
|
|
182
|
-
msgs << "#{time} - #{caller_name} - #{msg}"
|
|
183
|
-
end
|
|
184
|
-
if verbosity >= MU::Logger::QUIET
|
|
185
|
-
if @html
|
|
186
|
-
html_out "#{caller_name} - #{msg}"
|
|
187
|
-
elsif color
|
|
188
|
-
msgs << "#{details}".white.on_black if details
|
|
189
|
-
else
|
|
190
|
-
msgs << "#{details}" if details
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
Syslog.log(Syslog::LOG_NOTICE, msg.gsub(/%/, ''))
|
|
194
|
-
Syslog.log(Syslog::LOG_NOTICE, details.gsub(/%/, '')) if details
|
|
195
|
-
when WARN
|
|
196
|
-
if @html
|
|
197
|
-
html_out "#{time} - #{caller_name} - #{msg}", "orange"
|
|
198
|
-
elsif color
|
|
199
|
-
msgs << "#{time} - #{caller_name} - #{msg}".light_red.on_black
|
|
200
|
-
else
|
|
201
|
-
msgs << "#{time} - #{caller_name} - #{msg}"
|
|
202
|
-
end
|
|
203
|
-
if verbosity >= MU::Logger::SILENT
|
|
204
|
-
if @html
|
|
205
|
-
html_out "#{caller_name} - #{msg}"
|
|
206
|
-
elsif color
|
|
207
|
-
msgs << "#{details}".white.on_black if details
|
|
208
|
-
else
|
|
209
|
-
msgs << "#{details}" if details
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
Syslog.log(Syslog::LOG_WARNING, msg.gsub(/%/, ''))
|
|
213
|
-
Syslog.log(Syslog::LOG_WARNING, details.gsub(/%/, '')) if details
|
|
214
|
-
when ERR
|
|
215
|
-
if @html
|
|
216
|
-
html_out "#{time} - #{caller_name} - #{msg}", "red"
|
|
217
|
-
html_out " #{details}" if details
|
|
218
|
-
elsif color
|
|
219
|
-
msgs << "#{time} - #{caller_name} - #{msg}".red.on_black
|
|
220
|
-
msgs << "#{details}".white.on_black if details
|
|
221
|
-
else
|
|
222
|
-
msgs << "#{time} - #{caller_name} - #{msg}"
|
|
223
|
-
msgs << "#{details}" if details
|
|
224
|
-
end
|
|
225
|
-
Syslog.log(Syslog::LOG_ERR, msg.gsub(/%/, ''))
|
|
226
|
-
Syslog.log(Syslog::LOG_ERR, details.gsub(/%/, '')) if details
|
|
136
|
+
if !PRINT_MSG_IF[level][:msg] or level >= PRINT_MSG_IF[level][:msg]
|
|
137
|
+
if html
|
|
138
|
+
html_out "#{time} - #{caller_name} - #{msg}", COLORMAP[level][:html]
|
|
139
|
+
else
|
|
140
|
+
str = "#{time} - #{caller_name} - #{msg}"
|
|
141
|
+
str = str.send(COLORMAP[level][:ansi]).on_black if color
|
|
142
|
+
msgs << str
|
|
143
|
+
end
|
|
144
|
+
Syslog.log(SYSLOG_MAP[level], msg.gsub(/%/, ''))
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
if details and (!PRINT_MSG_IF[level][:details] or level >= PRINT_MSG_IF[level][:details])
|
|
148
|
+
if html
|
|
149
|
+
html_out " #{details}"
|
|
227
150
|
else
|
|
228
|
-
if
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
msgs << "#{time} - #{caller_name} - #{msg}".white.on_black
|
|
233
|
-
msgs << "#{details}".white.on_black if details
|
|
234
|
-
else
|
|
235
|
-
msgs << "#{time} - #{caller_name} - #{msg}"
|
|
236
|
-
msgs << "#{details}" if details
|
|
237
|
-
end
|
|
238
|
-
Syslog.log(Syslog::LOG_NOTICE, msg.gsub(/%/, ''))
|
|
239
|
-
Syslog.log(Syslog::LOG_NOTICE, details.gsub(/%/, '')) if details
|
|
151
|
+
details = details.white.on_black if color
|
|
152
|
+
msgs << details
|
|
153
|
+
end
|
|
154
|
+
Syslog.log(SYSLOG_MAP[level], details.gsub(/%/, ''))
|
|
240
155
|
end
|
|
156
|
+
|
|
157
|
+
# else
|
|
158
|
+
# if html
|
|
159
|
+
# html_out "#{time} - #{caller_name} - #{msg}"
|
|
160
|
+
# html_out " #{details}" if details
|
|
161
|
+
# elsif color
|
|
162
|
+
# msgs << "#{time} - #{caller_name} - #{msg}".white.on_black
|
|
163
|
+
# msgs << "#{details}".white.on_black if details
|
|
164
|
+
# else
|
|
165
|
+
# msgs << "#{time} - #{caller_name} - #{msg}"
|
|
166
|
+
# msgs << "#{details}" if details
|
|
167
|
+
# end
|
|
168
|
+
# Syslog.log(Syslog::LOG_NOTICE, msg.gsub(/%/, ''))
|
|
169
|
+
# Syslog.log(Syslog::LOG_NOTICE, details.gsub(/%/, '')) if details
|
|
170
|
+
|
|
241
171
|
write(handles, msgs)
|
|
242
172
|
|
|
243
173
|
extra_logfile.close if extra_logfile
|
|
@@ -247,6 +177,43 @@ module MU
|
|
|
247
177
|
|
|
248
178
|
private
|
|
249
179
|
|
|
180
|
+
def format_details(details, html = false)
|
|
181
|
+
return if details.nil?
|
|
182
|
+
|
|
183
|
+
if details.is_a?(Hash) and details.has_key?(:details)
|
|
184
|
+
details = details[:details]
|
|
185
|
+
end
|
|
186
|
+
details = PP.pp(details, '') if !details.is_a?(String)
|
|
187
|
+
|
|
188
|
+
details = "<pre>"+details+"</pre>" if html
|
|
189
|
+
# We get passed literal quoted newlines sometimes, fix 'em. Get Windows'
|
|
190
|
+
# ugly line feeds too.
|
|
191
|
+
|
|
192
|
+
details = details.dup # in case it's frozen or something
|
|
193
|
+
details.gsub!(/\\n/, "\n")
|
|
194
|
+
details.gsub!(/(\\r|\r)/, "")
|
|
195
|
+
|
|
196
|
+
details
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# By which we mean, "get the filename (with the .rb stripped off) which
|
|
200
|
+
# originated the call to this method. Which, for our purposes, is the
|
|
201
|
+
# MU subclass that called us. Useful information. And it looks like Perl.
|
|
202
|
+
def extract_caller_name(caller_name)
|
|
203
|
+
return nil if !caller_name or !caller_name.is_a?(String)
|
|
204
|
+
mod_root = Regexp.quote("#{ENV['MU_LIBDIR']}/modules/mu/")
|
|
205
|
+
bin_root = Regexp.quote("#{ENV['MU_INSTALLDIR']}/bin/")
|
|
206
|
+
|
|
207
|
+
caller_name.sub!(/:.*/, "")
|
|
208
|
+
caller_name.sub!(/^\.\//, "")
|
|
209
|
+
caller_name.sub!(/^#{mod_root}/, "")
|
|
210
|
+
caller_name.sub!(/^#{bin_root}/, "")
|
|
211
|
+
caller_name.sub!(/\.r[ub]$/, "")
|
|
212
|
+
caller_name.sub!(/#{Regexp.quote(MU.myRoot)}\//, "")
|
|
213
|
+
caller_name.sub!(/^modules\//, "")
|
|
214
|
+
caller_name
|
|
215
|
+
end
|
|
216
|
+
|
|
250
217
|
# Output a log message as HTML.
|
|
251
218
|
#
|
|
252
219
|
# @param msg [String]: The log message to print
|
|
@@ -256,5 +223,17 @@ module MU
|
|
|
256
223
|
@handle.puts "<span style='color:#{rgb.css_rgb};'>#{msg}</span>"
|
|
257
224
|
end
|
|
258
225
|
|
|
226
|
+
# wrapper for writing a log entry to multiple filehandles
|
|
227
|
+
# @param handles [Array<IO>]
|
|
228
|
+
# @param msgs [Array<String>]
|
|
229
|
+
def write(handles = [], msgs = [])
|
|
230
|
+
return if handles.nil? or msgs.nil?
|
|
231
|
+
handles.each { |h|
|
|
232
|
+
msgs.each { |m|
|
|
233
|
+
h.puts m
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
end
|
|
237
|
+
|
|
259
238
|
end #class
|
|
260
239
|
end #module
|