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.
- data/CHANGELOG +0 -0
- data/bin/bosh_agent +102 -0
- data/lib/bosh_agent/alert.rb +191 -0
- data/lib/bosh_agent/alert_processor.rb +96 -0
- data/lib/bosh_agent/apply_plan/helpers.rb +30 -0
- data/lib/bosh_agent/apply_plan/job.rb +235 -0
- data/lib/bosh_agent/apply_plan/package.rb +58 -0
- data/lib/bosh_agent/apply_plan/plan.rb +96 -0
- data/lib/bosh_agent/bootstrap.rb +341 -0
- data/lib/bosh_agent/config.rb +5 -0
- data/lib/bosh_agent/configuration.rb +102 -0
- data/lib/bosh_agent/disk_util.rb +103 -0
- data/lib/bosh_agent/errors.rb +25 -0
- data/lib/bosh_agent/ext.rb +48 -0
- data/lib/bosh_agent/file_aggregator.rb +78 -0
- data/lib/bosh_agent/file_matcher.rb +45 -0
- data/lib/bosh_agent/handler.rb +440 -0
- data/lib/bosh_agent/heartbeat.rb +74 -0
- data/lib/bosh_agent/heartbeat_processor.rb +45 -0
- data/lib/bosh_agent/http_handler.rb +135 -0
- data/lib/bosh_agent/infrastructure/aws/registry.rb +177 -0
- data/lib/bosh_agent/infrastructure/aws/settings.rb +59 -0
- data/lib/bosh_agent/infrastructure/aws.rb +17 -0
- data/lib/bosh_agent/infrastructure/dummy.rb +24 -0
- data/lib/bosh_agent/infrastructure/openstack/registry.rb +220 -0
- data/lib/bosh_agent/infrastructure/openstack/settings.rb +76 -0
- data/lib/bosh_agent/infrastructure/openstack.rb +17 -0
- data/lib/bosh_agent/infrastructure/vsphere/settings.rb +135 -0
- data/lib/bosh_agent/infrastructure/vsphere.rb +16 -0
- data/lib/bosh_agent/infrastructure.rb +25 -0
- data/lib/bosh_agent/message/apply.rb +184 -0
- data/lib/bosh_agent/message/base.rb +38 -0
- data/lib/bosh_agent/message/compile_package.rb +250 -0
- data/lib/bosh_agent/message/drain.rb +195 -0
- data/lib/bosh_agent/message/list_disk.rb +25 -0
- data/lib/bosh_agent/message/logs.rb +108 -0
- data/lib/bosh_agent/message/migrate_disk.rb +55 -0
- data/lib/bosh_agent/message/mount_disk.rb +102 -0
- data/lib/bosh_agent/message/ssh.rb +109 -0
- data/lib/bosh_agent/message/state.rb +47 -0
- data/lib/bosh_agent/message/unmount_disk.rb +29 -0
- data/lib/bosh_agent/monit.rb +354 -0
- data/lib/bosh_agent/monit_client.rb +158 -0
- data/lib/bosh_agent/mounter.rb +42 -0
- data/lib/bosh_agent/ntp.rb +32 -0
- data/lib/bosh_agent/platform/centos/disk.rb +27 -0
- data/lib/bosh_agent/platform/centos/network.rb +39 -0
- data/lib/bosh_agent/platform/centos/templates/centos-ifcfg.erb +9 -0
- data/lib/bosh_agent/platform/centos/templates/dhclient_conf.erb +56 -0
- data/lib/bosh_agent/platform/centos/templates/logrotate.erb +8 -0
- data/lib/bosh_agent/platform/centos.rb +4 -0
- data/lib/bosh_agent/platform/dummy/templates/dummy_template.erb +1 -0
- data/lib/bosh_agent/platform/linux/adapter.rb +36 -0
- data/lib/bosh_agent/platform/linux/disk.rb +121 -0
- data/lib/bosh_agent/platform/linux/logrotate.rb +32 -0
- data/lib/bosh_agent/platform/linux/network.rb +124 -0
- data/lib/bosh_agent/platform/linux/password.rb +22 -0
- data/lib/bosh_agent/platform/linux.rb +4 -0
- data/lib/bosh_agent/platform/ubuntu/network.rb +59 -0
- data/lib/bosh_agent/platform/ubuntu/templates/dhclient_conf.erb +56 -0
- data/lib/bosh_agent/platform/ubuntu/templates/interfaces.erb +14 -0
- data/lib/bosh_agent/platform/ubuntu/templates/logrotate.erb +8 -0
- data/lib/bosh_agent/platform/ubuntu.rb +4 -0
- data/lib/bosh_agent/platform.rb +26 -0
- data/lib/bosh_agent/remote_exception.rb +62 -0
- data/lib/bosh_agent/runner.rb +36 -0
- data/lib/bosh_agent/settings.rb +61 -0
- data/lib/bosh_agent/sigar_box.rb +26 -0
- data/lib/bosh_agent/smtp_server.rb +96 -0
- data/lib/bosh_agent/state.rb +100 -0
- data/lib/bosh_agent/syslog_monitor.rb +53 -0
- data/lib/bosh_agent/template.rb +50 -0
- data/lib/bosh_agent/util.rb +190 -0
- data/lib/bosh_agent/version.rb +8 -0
- data/lib/bosh_agent.rb +92 -0
- 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 @@
|
|
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
|