bosh_agent 1.5.0.pre.1113

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.
Files changed (76) hide show
  1. data/CHANGELOG +0 -0
  2. data/bin/bosh_agent +102 -0
  3. data/lib/bosh_agent/alert.rb +191 -0
  4. data/lib/bosh_agent/alert_processor.rb +96 -0
  5. data/lib/bosh_agent/apply_plan/helpers.rb +30 -0
  6. data/lib/bosh_agent/apply_plan/job.rb +235 -0
  7. data/lib/bosh_agent/apply_plan/package.rb +58 -0
  8. data/lib/bosh_agent/apply_plan/plan.rb +96 -0
  9. data/lib/bosh_agent/bootstrap.rb +341 -0
  10. data/lib/bosh_agent/config.rb +5 -0
  11. data/lib/bosh_agent/configuration.rb +102 -0
  12. data/lib/bosh_agent/disk_util.rb +103 -0
  13. data/lib/bosh_agent/errors.rb +25 -0
  14. data/lib/bosh_agent/ext.rb +48 -0
  15. data/lib/bosh_agent/file_aggregator.rb +78 -0
  16. data/lib/bosh_agent/file_matcher.rb +45 -0
  17. data/lib/bosh_agent/handler.rb +440 -0
  18. data/lib/bosh_agent/heartbeat.rb +74 -0
  19. data/lib/bosh_agent/heartbeat_processor.rb +45 -0
  20. data/lib/bosh_agent/http_handler.rb +135 -0
  21. data/lib/bosh_agent/infrastructure/aws/registry.rb +177 -0
  22. data/lib/bosh_agent/infrastructure/aws/settings.rb +59 -0
  23. data/lib/bosh_agent/infrastructure/aws.rb +17 -0
  24. data/lib/bosh_agent/infrastructure/dummy.rb +24 -0
  25. data/lib/bosh_agent/infrastructure/openstack/registry.rb +220 -0
  26. data/lib/bosh_agent/infrastructure/openstack/settings.rb +76 -0
  27. data/lib/bosh_agent/infrastructure/openstack.rb +17 -0
  28. data/lib/bosh_agent/infrastructure/vsphere/settings.rb +135 -0
  29. data/lib/bosh_agent/infrastructure/vsphere.rb +16 -0
  30. data/lib/bosh_agent/infrastructure.rb +25 -0
  31. data/lib/bosh_agent/message/apply.rb +184 -0
  32. data/lib/bosh_agent/message/base.rb +38 -0
  33. data/lib/bosh_agent/message/compile_package.rb +250 -0
  34. data/lib/bosh_agent/message/drain.rb +195 -0
  35. data/lib/bosh_agent/message/list_disk.rb +25 -0
  36. data/lib/bosh_agent/message/logs.rb +108 -0
  37. data/lib/bosh_agent/message/migrate_disk.rb +55 -0
  38. data/lib/bosh_agent/message/mount_disk.rb +102 -0
  39. data/lib/bosh_agent/message/ssh.rb +109 -0
  40. data/lib/bosh_agent/message/state.rb +47 -0
  41. data/lib/bosh_agent/message/unmount_disk.rb +29 -0
  42. data/lib/bosh_agent/monit.rb +354 -0
  43. data/lib/bosh_agent/monit_client.rb +158 -0
  44. data/lib/bosh_agent/mounter.rb +42 -0
  45. data/lib/bosh_agent/ntp.rb +32 -0
  46. data/lib/bosh_agent/platform/centos/disk.rb +27 -0
  47. data/lib/bosh_agent/platform/centos/network.rb +39 -0
  48. data/lib/bosh_agent/platform/centos/templates/centos-ifcfg.erb +9 -0
  49. data/lib/bosh_agent/platform/centos/templates/dhclient_conf.erb +56 -0
  50. data/lib/bosh_agent/platform/centos/templates/logrotate.erb +8 -0
  51. data/lib/bosh_agent/platform/centos.rb +4 -0
  52. data/lib/bosh_agent/platform/dummy/templates/dummy_template.erb +1 -0
  53. data/lib/bosh_agent/platform/linux/adapter.rb +36 -0
  54. data/lib/bosh_agent/platform/linux/disk.rb +121 -0
  55. data/lib/bosh_agent/platform/linux/logrotate.rb +32 -0
  56. data/lib/bosh_agent/platform/linux/network.rb +124 -0
  57. data/lib/bosh_agent/platform/linux/password.rb +22 -0
  58. data/lib/bosh_agent/platform/linux.rb +4 -0
  59. data/lib/bosh_agent/platform/ubuntu/network.rb +59 -0
  60. data/lib/bosh_agent/platform/ubuntu/templates/dhclient_conf.erb +56 -0
  61. data/lib/bosh_agent/platform/ubuntu/templates/interfaces.erb +14 -0
  62. data/lib/bosh_agent/platform/ubuntu/templates/logrotate.erb +8 -0
  63. data/lib/bosh_agent/platform/ubuntu.rb +4 -0
  64. data/lib/bosh_agent/platform.rb +26 -0
  65. data/lib/bosh_agent/remote_exception.rb +62 -0
  66. data/lib/bosh_agent/runner.rb +36 -0
  67. data/lib/bosh_agent/settings.rb +61 -0
  68. data/lib/bosh_agent/sigar_box.rb +26 -0
  69. data/lib/bosh_agent/smtp_server.rb +96 -0
  70. data/lib/bosh_agent/state.rb +100 -0
  71. data/lib/bosh_agent/syslog_monitor.rb +53 -0
  72. data/lib/bosh_agent/template.rb +50 -0
  73. data/lib/bosh_agent/util.rb +190 -0
  74. data/lib/bosh_agent/version.rb +8 -0
  75. data/lib/bosh_agent.rb +92 -0
  76. metadata +332 -0
@@ -0,0 +1,158 @@
1
+ require "logger"
2
+ require "net/http"
3
+ require "crack"
4
+
5
+ module Bosh::Agent
6
+ class MonitClient
7
+ TYPES = {
8
+ :file_system => 0,
9
+ :directory => 1,
10
+ :file => 2,
11
+ :process => 3,
12
+ :remote_host => 4,
13
+ :system => 5,
14
+ :fifo => 6
15
+ }
16
+
17
+ TYPES_INVERSE = TYPES.invert
18
+
19
+ STATUS_MESSAGES = {
20
+ :file_system => "accessible",
21
+ :directory => "accessible",
22
+ :file => "accessible",
23
+ :process => "running",
24
+ :remote_host => "online with all services",
25
+ :system => "running",
26
+ :fifo => "accessible"
27
+ }
28
+
29
+ MONITOR = {
30
+ :no => 0,
31
+ :yes => 1,
32
+ :init => 2
33
+ }
34
+
35
+ MONITOR_INVERSE = MONITOR.invert
36
+
37
+ def initialize(uri, options = {})
38
+ @logger = options[:logger] || Logger.new(nil)
39
+ @uri = URI.parse(uri)
40
+ end
41
+
42
+ def start(arg)
43
+ service_names(arg).each { |service_name| service_action(service_name, "start") }
44
+ end
45
+
46
+ def stop(arg)
47
+ service_names(arg).each { |service_name| service_action(service_name, "stop") }
48
+ end
49
+
50
+ def restart(arg)
51
+ service_names(arg).each { |service_name| service_action(service_name, "restart") }
52
+ end
53
+
54
+ def monitor(arg)
55
+ service_names(arg).each { |service_name| service_action(service_name, "monitor") }
56
+ end
57
+
58
+ def unmonitor(arg)
59
+ service_names(arg).each { |service_name| service_action(service_name, "unmonitor") }
60
+ end
61
+
62
+ def status(arg)
63
+ status = get_status
64
+ services = get_services(status, arg)
65
+ result = {}
66
+ services.each do |service|
67
+ type = TYPES_INVERSE[service["type"].to_i]
68
+ status_message = service["status_message"] || STATUS_MESSAGES[type]
69
+ result[service["name"]] = {
70
+ :type => type,
71
+ :status => {
72
+ :code => service["status"].to_i,
73
+ :message => status_message
74
+ },
75
+ :monitor => MONITOR_INVERSE[service["monitor"].to_i],
76
+ :raw => service
77
+ }
78
+ end
79
+ result
80
+ end
81
+
82
+ def monit_info
83
+ status = get_status
84
+ monit_status = status["monit"]
85
+ {
86
+ :id => monit_status["id"],
87
+ :incarnation => monit_status["incarnation"],
88
+ :version => monit_status["version"]
89
+ }
90
+ end
91
+
92
+ private
93
+
94
+ def get_status
95
+ http = Net::HTTP.new(@uri.host, @uri.port)
96
+ request = Net::HTTP::Get.new("/_status2?format=xml")
97
+ request.basic_auth(@uri.user, @uri.password) if @uri.user || @uri.password
98
+ response = http.request(request)
99
+ if response.code != "200"
100
+ raise response.message
101
+ end
102
+
103
+ Crack::XML.parse(response.body)
104
+ end
105
+
106
+ def service_names(arg)
107
+ status = get_status
108
+ services = get_services(status, arg)
109
+ services.collect { |service| service["name"] }
110
+ end
111
+
112
+ def get_services(status, arg)
113
+ services = status["monit"]["services"]["service"]
114
+ services = [services] unless services.kind_of?(Array)
115
+
116
+ service_groups_index = {}
117
+ if status["monit"]["servicegroups"]
118
+ groups = status["monit"]["servicegroups"]["servicegroup"]
119
+ groups = [groups] unless groups.kind_of?(Array)
120
+ groups.each do |group|
121
+ service_names = group["service"]
122
+ service_names = [service_names] unless service_names.kind_of?(Array)
123
+
124
+ service_names.each do |service_name|
125
+ service_groups_index[service_name] ||= Set.new
126
+ service_groups_index[service_name] << group["name"]
127
+ end
128
+ end
129
+ end
130
+
131
+ if arg.kind_of?(Hash)
132
+ if arg.has_key?(:group)
133
+ services = services.select { |service| service_groups_index[service["name"]] &&
134
+ service_groups_index[service["name"]].include?(arg[:group]) }
135
+ end
136
+ services = services.select { |service| service["type"] == TYPES[arg[:type]].to_s } if arg.has_key?(:type)
137
+ services
138
+ elsif arg.kind_of?(String)
139
+ services.select { |service| service["name"] == arg }
140
+ else
141
+ raise ArgumentError
142
+ end
143
+ end
144
+
145
+ def service_action(service_name, action)
146
+ @logger.debug("Requesting '#{action}' for #{service_name}")
147
+ http = Net::HTTP.new(@uri.host, @uri.port)
148
+ request = Net::HTTP::Post.new("/#{service_name}")
149
+ request.basic_auth(@uri.user, @uri.password) if @uri.user || @uri.password
150
+ request.content_type = ("application/x-www-form-urlencoded")
151
+ request.body = "action=#{action}"
152
+ response = http.request(request)
153
+ if response.code != "200"
154
+ raise response.message
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,42 @@
1
+ require 'bosh_agent'
2
+
3
+ module Bosh::Agent
4
+ class Mounter
5
+ def initialize(logger, shell_runner=Bosh::Exec)
6
+ @logger = logger
7
+ @shell_runner = shell_runner
8
+ end
9
+
10
+ def mount(partition, mount_point, options_hash={})
11
+ @logger.info("Mounting: #{partition} #{mount_point}")
12
+ options = build_command_line_options(options_hash)
13
+
14
+ results = shell_runner.sh("mount #{options} #{partition} #{mount_point}", on_error: :return)
15
+
16
+ if results.failed?
17
+ raise Bosh::Agent::MessageHandlerError,
18
+ "Failed to mount: '#{partition}' '#{mount_point}' Exit status: #{results.exit_status} Output: #{results.output}"
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :shell_runner
25
+
26
+ def build_command_line_options(options_hash)
27
+ command_options = { read_only: '-o ro' }
28
+ commands = []
29
+
30
+ command_options.each do |key,value|
31
+ if options_hash[key]
32
+ commands << value
33
+ options_hash.delete(key)
34
+ end
35
+ end
36
+
37
+ raise Bosh::Agent::Error, "Invalid options: #{options_hash.inspect}" unless options_hash.empty?
38
+
39
+ commands.join(' ')
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Agent
4
+ class NTP
5
+ BAD_SERVER = "bad ntp server"
6
+ FILE_MISSING = "file missing"
7
+ BAD_CONTENTS = "bad file contents"
8
+
9
+ def self.offset(ntpdate="#{Config.base_dir}/bosh/log/ntpdate.out")
10
+ result = {}
11
+ if File.exist?(ntpdate)
12
+ lines = []
13
+ File.open(ntpdate) do |file|
14
+ lines = file.readlines
15
+ end
16
+ case lines.last
17
+ when /^(.+)\s+ntpdate.+offset\s+(-*\d+\.\d+)/
18
+ result["timestamp"] = $1
19
+ result["offset"] = $2
20
+ when /no server suitable for synchronization found/
21
+ result["message"] = BAD_SERVER
22
+ else
23
+ result["message"] = BAD_CONTENTS
24
+ end
25
+ else
26
+ result["message"] = FILE_MISSING
27
+ end
28
+ result
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ module Bosh::Agent
2
+ class Platform::Centos::Disk < Platform::Linux::Disk
3
+ def detect_block_device(disk_id)
4
+ device_path = "/sys/bus/scsi/devices/#{root_disk_scsi_host_id}:0:#{disk_id}:0/block/*"
5
+ dirs = Dir.glob(device_path)
6
+ raise Bosh::Agent::DiskNotFoundError, "Unable to find disk #{device_path}" if dirs.empty?
7
+
8
+ File.basename(dirs.first)
9
+ end
10
+
11
+ private
12
+
13
+ def rescan_scsi_bus
14
+ File.open("/sys/class/scsi_host/host#{root_disk_scsi_host_id}/scan", 'w') do |file|
15
+ file.puts '- - -'
16
+ end
17
+ end
18
+
19
+ def root_disk_scsi_host_id
20
+ Dir.glob('/sys/bus/scsi/devices/*:0:0:0/block/*').each do |device|
21
+ if %r{/(?<host_id>\d):0:0:0/.*/sda} =~ device
22
+ return host_id
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ module Bosh::Agent
2
+ class Platform::Centos::Network < Platform::Linux::Network
3
+ include Bosh::Exec
4
+
5
+ def initialize(template_dir)
6
+ super
7
+ end
8
+
9
+ def write_network_interfaces
10
+ template = ERB.new(load_erb("centos-ifcfg.erb"), 0, '%<>-')
11
+ networks.each do |name, network|
12
+ result = template.result(binding)
13
+ Bosh::Agent::Util::update_file(result, "/etc/sysconfig/network-scripts/ifcfg-#{name}")
14
+ end
15
+ restart_networking_service
16
+ end
17
+
18
+ def restart_networking_service
19
+ @logger.info("Restarting network")
20
+ sh "service network restart"
21
+ end
22
+
23
+ def write_dhcp_conf
24
+ template = ERB.new(load_erb("dhclient_conf.erb"), 0, '%<>-')
25
+ result = template.result(binding)
26
+ updated = Bosh::Agent::Util::update_file(result, '/etc/dhclient.conf')
27
+ if updated
28
+ @logger.info("Updated dhclient.conf")
29
+ restart_dhclient
30
+ end
31
+ end
32
+
33
+ def restart_dhclient
34
+ @logger.info("Restarting network to restart dhclient")
35
+ sh "service network restart"
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ DEVICE=<%= network['interface'] %>
2
+ BOOTPROTO=static
3
+ IPADDR=<%= network['ip']%>
4
+ NETMASK=<%= network['netmask']%>
5
+ BROADCAST=<%= network['broadcast'] %>
6
+ <% if network.fetch('default', []).include?('gateway') -%>
7
+ GATEWAY=<%= network['gateway'] %>
8
+ <% end %>
9
+ ONBOOT=yes
@@ -0,0 +1,56 @@
1
+ # Configuration file for /sbin/dhclient, which is included in Debian's
2
+ # dhcp3-client package.
3
+ #
4
+ # This is a sample configuration file for dhclient. See dhclient.conf's
5
+ # man page for more information about the syntax of this file
6
+ # and a more comprehensive list of the parameters understood by
7
+ # dhclient.
8
+ #
9
+ # Normally, if the DHCP server provides reasonable information and does
10
+ # not leave anything out (like the domain name, for example), then
11
+ # few changes must be made to this file, if any.
12
+ #
13
+
14
+ option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
15
+
16
+ send host-name "<hostname>";
17
+ #send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
18
+ #send dhcp-lease-time 3600;
19
+ #supersede domain-name "fugue.com home.vix.com";
20
+ request subnet-mask, broadcast-address, time-offset, routers,
21
+ domain-name, domain-name-servers, domain-search, host-name,
22
+ netbios-name-servers, netbios-scope, interface-mtu,
23
+ rfc3442-classless-static-routes, ntp-servers;
24
+ <% dns.reverse.each do |server| -%>
25
+ prepend domain-name-servers <%= server %>;
26
+ <% end -%>
27
+
28
+ #require subnet-mask, domain-name-servers;
29
+ #timeout 60;
30
+ #retry 60;
31
+ #reboot 10;
32
+ #select-timeout 5;
33
+ #initial-interval 2;
34
+ #script "/etc/dhcp3/dhclient-script";
35
+ #media "-link0 -link1 -link2", "link0 link1";
36
+ #reject 192.33.137.209;
37
+
38
+ #alias {
39
+ # interface "eth0";
40
+ # fixed-address 192.5.5.213;
41
+ # option subnet-mask 255.255.255.255;
42
+ #}
43
+
44
+ #lease {
45
+ # interface "eth0";
46
+ # fixed-address 192.33.137.200;
47
+ # medium "link0 link1";
48
+ # option host-name "andare.swiftmedia.com";
49
+ # option subnet-mask 255.255.255.0;
50
+ # option broadcast-address 192.33.137.255;
51
+ # option routers 192.33.137.250;
52
+ # option domain-name-servers 127.0.0.1;
53
+ # renew 2 2000/1/12 00:00:01;
54
+ # rebind 2 2000/1/12 00:00:01;
55
+ # expire 2 2000/1/12 00:00:01;
56
+ #}
@@ -0,0 +1,8 @@
1
+ <%= base_dir %>/data/sys/log/*.log <%= base_dir %>/data/sys/log/*/*.log <%= base_dir %>/data/sys/log/*/*/*.log {
2
+ missingok
3
+ rotate 7
4
+ compress
5
+ delaycompress
6
+ copytruncate
7
+ size=<%= size %>
8
+ }
@@ -0,0 +1,4 @@
1
+ module Bosh::Agent
2
+ module Platform::Centos
3
+ end
4
+ end
@@ -0,0 +1 @@
1
+ This is a dummy variable with <%= dummy %> value
@@ -0,0 +1,36 @@
1
+ module Bosh::Agent
2
+ module Platform::Linux
3
+ class Adapter
4
+ def initialize(disk, logrotate, password, network)
5
+ @disk = disk
6
+ @logrotate = logrotate
7
+ @password = password
8
+ @network = network
9
+ end
10
+
11
+ def mount_persistent_disk(cid)
12
+ @disk.mount_persistent_disk(cid)
13
+ end
14
+
15
+ def update_logging(spec)
16
+ @logrotate.install(spec)
17
+ end
18
+
19
+ def update_passwords(settings)
20
+ @password.update(settings)
21
+ end
22
+
23
+ def lookup_disk_by_cid(cid)
24
+ @disk.lookup_disk_by_cid(cid)
25
+ end
26
+
27
+ def get_data_disk_device_name
28
+ @disk.get_data_disk_device_name
29
+ end
30
+
31
+ def setup_networking
32
+ @network.setup_networking
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,121 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Agent
4
+ class Platform::Linux::Disk
5
+ include Bosh::Exec
6
+
7
+ VSPHERE_DATA_DISK = "/dev/sdb"
8
+ DEV_PATH_TIMEOUT=180
9
+ DISK_RETRY_MAX_DEFAULT = 30
10
+
11
+ def initialize
12
+ @config = Bosh::Agent::Config
13
+ @platform_name = @config.platform_name
14
+ @logger = @config.logger
15
+ @store_dir = File.join(@config.base_dir, 'store')
16
+ @dev_path_timeout = DEV_PATH_TIMEOUT
17
+ @disk_retry_timeout = DISK_RETRY_MAX_DEFAULT
18
+ @mounter = Mounter.new(@logger)
19
+ end
20
+
21
+ def mount_persistent_disk(cid, options={})
22
+ FileUtils.mkdir_p(@store_dir)
23
+ disk = lookup_disk_by_cid(cid)
24
+ partition = "#{disk}1"
25
+ if File.blockdev?(partition) && !mount_exists?(partition)
26
+ mounter.mount(partition, @store_dir, options)
27
+ end
28
+ end
29
+
30
+ def get_data_disk_device_name
31
+ case @config.infrastructure_name
32
+ when "vsphere"
33
+ VSPHERE_DATA_DISK
34
+ when "aws", "openstack"
35
+ settings = @config.settings
36
+ dev_path = settings['disks']['ephemeral']
37
+ unless dev_path
38
+ raise Bosh::Agent::FatalError, "Unknown data or ephemeral disk" if @config.infrastructure_name == "aws"
39
+ @logger.warn("No ephemeral disk set, using root device for BOSH agent data!!!")
40
+ return nil
41
+ end
42
+ get_available_path(dev_path)
43
+ else
44
+ raise Bosh::Agent::FatalError, "Lookup disk failed, unsupported infrastructure #{Bosh::Agent::Config.infrastructure_name}"
45
+ end
46
+ end
47
+
48
+ def lookup_disk_by_cid(cid)
49
+ disk_id = @config.settings['disks']['persistent'][cid]
50
+
51
+ if disk_id.nil?
52
+ raise Bosh::Agent::FatalError, "Unknown persistent disk: #{cid}"
53
+ end
54
+
55
+ case @config.infrastructure_name
56
+ when "vsphere"
57
+ # VSphere passes in scsi disk id
58
+ get_available_scsi_path(disk_id)
59
+ when "aws", "openstack"
60
+ # AWS & OpenStack pass in the device name
61
+ get_available_path(disk_id)
62
+ else
63
+ raise Bosh::Agent::FatalError, "Lookup disk failed, unsupported infrastructure #{Bosh::Agent::Config.infrastructure_name}"
64
+ end
65
+ end
66
+
67
+ def detect_block_device(disk_id)
68
+ device_path = "/sys/bus/scsi/devices/2:0:#{disk_id}:0/block/*"
69
+ dirs = Dir.glob(device_path, 0)
70
+ raise Bosh::Agent::DiskNotFoundError, "Unable to find disk #{device_path}" if dirs.empty?
71
+
72
+ File.basename(dirs.first)
73
+ end
74
+
75
+ private
76
+
77
+ def rescan_scsi_bus
78
+ sh "rescan-scsi-bus.sh"
79
+ end
80
+
81
+ def get_dev_paths(dev_path)
82
+ dev_paths = [] << dev_path
83
+ dev_path_suffix = dev_path.match("/dev/sd(.*)")
84
+ unless dev_path_suffix.nil?
85
+ dev_paths << "/dev/vd#{dev_path_suffix[1]}" # KVM
86
+ dev_paths << "/dev/xvd#{dev_path_suffix[1]}" # Xen
87
+ end
88
+ dev_paths
89
+ end
90
+
91
+ def get_available_path(dev_path)
92
+ start = Time.now
93
+ dev_paths = get_dev_paths(dev_path)
94
+ while Dir.glob(dev_paths).empty?
95
+ @logger.info("Waiting for #{dev_paths}")
96
+ sleep 0.1
97
+ if (Time.now - start) > @dev_path_timeout
98
+ raise Bosh::Agent::FatalError, "Timed out waiting for #{dev_paths}"
99
+ end
100
+ end
101
+ Dir.glob(dev_paths).last
102
+ end
103
+
104
+ def get_available_scsi_path(disk_id)
105
+ rescan_scsi_bus
106
+ blockdev = nil
107
+ Bosh::Common.retryable(tries: @disk_retry_timeout, on: Bosh::Agent::DiskNotFoundError) do
108
+ blockdev = detect_block_device(disk_id)
109
+ end
110
+ File.join('/dev', blockdev)
111
+ end
112
+
113
+ def mount_exists?(partition)
114
+ File.read('/proc/mounts').lines.select { |l| l.match(/#{partition}/) }.first
115
+ end
116
+
117
+ private
118
+
119
+ attr_reader :mounter
120
+ end
121
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module Bosh::Agent
4
+ class Platform::Linux::Logrotate
5
+ DEFAULT_MAX_LOG_FILE_SIZE = "50M"
6
+
7
+ def initialize(template_dir)
8
+ @logger = Bosh::Agent::Config.logger
9
+ @template_src = File.join template_dir, "logrotate.erb"
10
+ @template_dst = File.join Bosh::Agent::Config.system_root, "etc", "logrotate.d", BOSH_APP_GROUP
11
+ end
12
+
13
+ def install(spec={})
14
+ # These local variables are used in the template context
15
+ # (see Bosh::Agent::Template class implementation)
16
+ base_dir = Bosh::Agent::Config.base_dir
17
+ size = max_log_file_size(spec['properties'])
18
+ @logger.debug "Compiling template #@template_src to #@template_dst"
19
+ Template.write do |t|
20
+ t.src @template_src
21
+ t.dst @template_dst
22
+ end
23
+ end
24
+
25
+ private
26
+ def max_log_file_size(properties)
27
+ (properties || {}).
28
+ fetch('logging', {}).
29
+ fetch('max_log_file_size', DEFAULT_MAX_LOG_FILE_SIZE)
30
+ end
31
+ end
32
+ end