rha 0.1.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.
- data/Changelog +0 -0
- data/MIT-LICENSE +21 -0
- data/README +73 -0
- data/lib/rha/authkeys.rb +80 -0
- data/lib/rha/daemon.rb +227 -0
- data/lib/rha/ha_cf.rb +762 -0
- data/lib/rha/haresources.rb +63 -0
- data/lib/rha/version.rb +17 -0
- data/lib/rha.rb +9 -0
- data/setup.rb +1585 -0
- data/test/test_helper.rb +2 -0
- data/test/test_rha.rb +11 -0
- metadata +78 -0
data/Changelog
ADDED
File without changes
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Joel Bryan Juliano <joelbryan.juliano@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
README for Rha
|
2
|
+
==================
|
3
|
+
|
4
|
+
Rha is a gem providing a ruby interface to Heartbeat High Availability Cluster.
|
5
|
+
|
6
|
+
To install, type 'gem install rha'
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
require 'rha'
|
12
|
+
|
13
|
+
ha_cf = RhaConfig.new
|
14
|
+
ha_cf.use_logd = "on"
|
15
|
+
ha_cf.mcast = "eth0 239.0.0.42 694 1 0"
|
16
|
+
ha_cf.bcast = "eth1"
|
17
|
+
ha_cf.node = "alice bob"
|
18
|
+
ha_cf.keepalive = "1000ms"
|
19
|
+
ha_cf.deadtime = "30000ms"
|
20
|
+
ha_cf.realtime = true
|
21
|
+
ha_cf.conn_logd_time = "60"
|
22
|
+
ha_cf.crm = "false"
|
23
|
+
ha_cf.compression = "zlib"
|
24
|
+
ha_cf.compression_threshold = 2
|
25
|
+
|
26
|
+
authkeys = RhaAuthkeys.new
|
27
|
+
authkeys.auth(1)
|
28
|
+
authkeys.add_md5(1, 1, "secret")
|
29
|
+
authkeys.add_sha1(1, 2, "secret")
|
30
|
+
authkeys.add_crc(1, 3)
|
31
|
+
|
32
|
+
haresources = RhaResources.new
|
33
|
+
haresources.preferred_node = "alice"
|
34
|
+
haresources.resource_name = "192.168.1.10"
|
35
|
+
haresources.script_name = "sshd nginx mysql"
|
36
|
+
|
37
|
+
ha_cf_file = File.new("ha.cf", "w+")
|
38
|
+
ha_cf_file.puts(ha_cf.config)
|
39
|
+
|
40
|
+
authkeys_file = File.new("authkeys", "w+")
|
41
|
+
authkeys_file.puts(authkeys.config)
|
42
|
+
|
43
|
+
haresources_file = File.new("haresources", "w+")
|
44
|
+
haresources_file.puts(haresources.config)
|
45
|
+
|
46
|
+
ha_cf_file.close
|
47
|
+
authkeys_file.close
|
48
|
+
haresources_file.close
|
49
|
+
|
50
|
+
ha.cf:
|
51
|
+
|
52
|
+
use_logd on
|
53
|
+
bcast eth1
|
54
|
+
compression zlib
|
55
|
+
compression_threshold 2
|
56
|
+
conn_logd_time 60
|
57
|
+
crm false
|
58
|
+
deadtime 30000ms
|
59
|
+
keepalive 1000ms
|
60
|
+
mcast eth0 239.0.0.42 694 1 0
|
61
|
+
node alice bob
|
62
|
+
realtime true
|
63
|
+
|
64
|
+
authkeys:
|
65
|
+
|
66
|
+
auth 1
|
67
|
+
3 crc
|
68
|
+
2 sha1 secret
|
69
|
+
1 md5 secret
|
70
|
+
|
71
|
+
haresources:
|
72
|
+
|
73
|
+
alice 192.168.1.10 sshd nginx mysql
|
data/lib/rha/authkeys.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# = rha - A Heartbeat gem for Ruby
|
2
|
+
#
|
3
|
+
# Homepage:: http://github.com/jjuliano/rha
|
4
|
+
# Author:: Joel Bryan Juliano
|
5
|
+
# Copyright:: (cc) 2011 Joel Bryan Juliano
|
6
|
+
# License:: MIT
|
7
|
+
|
8
|
+
#
|
9
|
+
# class RhaAuthkeys.new( array, str, array)
|
10
|
+
#
|
11
|
+
|
12
|
+
#
|
13
|
+
# RhaAuthkeys are authentication configurations for heartbeat.
|
14
|
+
#
|
15
|
+
class RhaAuthkeys
|
16
|
+
#
|
17
|
+
# Returns a new RhaConfig Object
|
18
|
+
#
|
19
|
+
def initialize()
|
20
|
+
@num ||= []
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# auth num selects the currently active authentication method and secret.
|
25
|
+
#
|
26
|
+
# num is a numerical identifier, between 1 and 15 inclusive.
|
27
|
+
# It must be unique within the file.
|
28
|
+
#
|
29
|
+
def auth(value)
|
30
|
+
@num.push("auth #{value}")
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# MD5 hash method. This method requires a shared secret.
|
35
|
+
#
|
36
|
+
def add_md5(auth_num, method_num, secret)
|
37
|
+
begin
|
38
|
+
num_index = @num.index("auth #{auth_num}")
|
39
|
+
@num.insert(num_index + 1, method_num.to_s + " md5 " + secret.to_s + "\n")
|
40
|
+
rescue
|
41
|
+
puts "no such auth num #{auth_num}"
|
42
|
+
return false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# SHA-1 hash method. This method requires a shared secret.
|
48
|
+
#
|
49
|
+
def add_sha1(auth_num, method_num, secret)
|
50
|
+
begin
|
51
|
+
num_index = @num.index("auth #{auth_num}")
|
52
|
+
@num.insert(num_index + 1, method_num.to_s + " sha1 " + secret.to_s + "\n")
|
53
|
+
rescue
|
54
|
+
puts "no such auth num #{auth_num}"
|
55
|
+
return false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Cyclic Redundancy Check hash method. This method does not require
|
61
|
+
# a shared secret and is insecure; it's use is strongly discouraged.
|
62
|
+
#
|
63
|
+
def add_crc(auth_num, method_num)
|
64
|
+
begin
|
65
|
+
num_index = @num.index("auth #{auth_num}")
|
66
|
+
@num.insert(num_index + 1, method_num.to_s + " crc " + "\n")
|
67
|
+
rescue
|
68
|
+
puts "no such auth num #{auth_num}"
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Return the RhaAuthkeys configuration
|
75
|
+
#
|
76
|
+
def config
|
77
|
+
return @num
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
data/lib/rha/daemon.rb
ADDED
@@ -0,0 +1,227 @@
|
|
1
|
+
# = rha - A Heartbeat gem for Ruby
|
2
|
+
#
|
3
|
+
# Homepage:: http://github.com/jjuliano/rha
|
4
|
+
# Author:: Joel Bryan Juliano
|
5
|
+
# Copyright:: (cc) 2011 Joel Bryan Juliano
|
6
|
+
# License:: MIT
|
7
|
+
|
8
|
+
#
|
9
|
+
# class RhaDaemon.new( array, str, array)
|
10
|
+
#
|
11
|
+
|
12
|
+
#
|
13
|
+
# RhaDaemon controls the heartbeat daemon
|
14
|
+
#
|
15
|
+
class RhaDaemon
|
16
|
+
|
17
|
+
#
|
18
|
+
# Increment debugging level. Higher levels are more verbose.
|
19
|
+
#
|
20
|
+
attr_accessor :debug_level
|
21
|
+
|
22
|
+
#
|
23
|
+
# Alternate path to heartbeat. If this is not set, environment path
|
24
|
+
# is used.
|
25
|
+
#
|
26
|
+
attr_accessor :path_to_heartbeat
|
27
|
+
|
28
|
+
#
|
29
|
+
# Set heartbeat daemon option; This will set an arbitrary
|
30
|
+
# heartbeat option.
|
31
|
+
#
|
32
|
+
attr_accessor :option
|
33
|
+
|
34
|
+
#
|
35
|
+
# Returns a new RhaDaemon Object
|
36
|
+
#
|
37
|
+
def initialize()
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Reload heartbeat. This option is functionally identical to
|
42
|
+
# sending a running heartbeat process a HUP signal. If the
|
43
|
+
# configuration has not changed, then this option is essentially
|
44
|
+
# a no-op. If ha.cf or authkeys has changed, then heartbeat
|
45
|
+
# will re-read these files and update its configuration.
|
46
|
+
#
|
47
|
+
def reload
|
48
|
+
tmp = Tempfile.new('tmp')
|
49
|
+
command = option_string() + "-r " + " 2> " + tmp.path
|
50
|
+
success = system(command)
|
51
|
+
if success
|
52
|
+
begin
|
53
|
+
while (line = tmp.readline)
|
54
|
+
line.chomp
|
55
|
+
selected_string = line
|
56
|
+
end
|
57
|
+
rescue EOFError
|
58
|
+
tmp.close
|
59
|
+
end
|
60
|
+
return selected_string
|
61
|
+
else
|
62
|
+
tmp.close!
|
63
|
+
return success
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Kill (stop) heartbeat.
|
69
|
+
#
|
70
|
+
def reload
|
71
|
+
tmp = Tempfile.new('tmp')
|
72
|
+
command = option_string() + "-k " + " 2> " + tmp.path
|
73
|
+
success = system(command)
|
74
|
+
if success
|
75
|
+
begin
|
76
|
+
while (line = tmp.readline)
|
77
|
+
line.chomp
|
78
|
+
selected_string = line
|
79
|
+
end
|
80
|
+
rescue EOFError
|
81
|
+
tmp.close
|
82
|
+
end
|
83
|
+
return selected_string
|
84
|
+
else
|
85
|
+
tmp.close!
|
86
|
+
return success
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Report heartbeat status.
|
92
|
+
#
|
93
|
+
def report
|
94
|
+
tmp = Tempfile.new('tmp')
|
95
|
+
command = option_string() + "-k " + " 2> " + tmp.path
|
96
|
+
success = system(command)
|
97
|
+
if success
|
98
|
+
begin
|
99
|
+
while (line = tmp.readline)
|
100
|
+
line.chomp
|
101
|
+
selected_string = line
|
102
|
+
end
|
103
|
+
rescue EOFError
|
104
|
+
tmp.close
|
105
|
+
end
|
106
|
+
return selected_string
|
107
|
+
else
|
108
|
+
tmp.close!
|
109
|
+
return success
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Heartbeat restart exec flag (internal use only).
|
115
|
+
#
|
116
|
+
def restart
|
117
|
+
tmp = Tempfile.new('tmp')
|
118
|
+
command = option_string() + "-R " + " 2> " + tmp.path
|
119
|
+
success = system(command)
|
120
|
+
if success
|
121
|
+
begin
|
122
|
+
while (line = tmp.readline)
|
123
|
+
line.chomp
|
124
|
+
selected_string = line
|
125
|
+
end
|
126
|
+
rescue EOFError
|
127
|
+
tmp.close
|
128
|
+
end
|
129
|
+
return selected_string
|
130
|
+
else
|
131
|
+
tmp.close!
|
132
|
+
return success
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# Report heartbeat status.
|
138
|
+
#
|
139
|
+
def status
|
140
|
+
tmp = Tempfile.new('tmp')
|
141
|
+
command = option_string() + "-s " + " 2> " + tmp.path
|
142
|
+
success = system(command)
|
143
|
+
if success
|
144
|
+
begin
|
145
|
+
while (line = tmp.readline)
|
146
|
+
line.chomp
|
147
|
+
selected_string = line
|
148
|
+
end
|
149
|
+
rescue EOFError
|
150
|
+
tmp.close
|
151
|
+
end
|
152
|
+
return selected_string
|
153
|
+
else
|
154
|
+
tmp.close!
|
155
|
+
return success
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
#
|
160
|
+
# Heartbeat current resource state for restart (internal use only).
|
161
|
+
#
|
162
|
+
def restart_with_current_resources
|
163
|
+
tmp = Tempfile.new('tmp')
|
164
|
+
command = option_string() + "-R -C " + " 2> " + tmp.path
|
165
|
+
success = system(command)
|
166
|
+
if success
|
167
|
+
begin
|
168
|
+
while (line = tmp.readline)
|
169
|
+
line.chomp
|
170
|
+
selected_string = line
|
171
|
+
end
|
172
|
+
rescue EOFError
|
173
|
+
tmp.close
|
174
|
+
end
|
175
|
+
return selected_string
|
176
|
+
else
|
177
|
+
tmp.close!
|
178
|
+
return success
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# Print out heartbeat version.
|
184
|
+
#
|
185
|
+
def version
|
186
|
+
tmp = Tempfile.new('tmp')
|
187
|
+
command = option_string() + "-V " + " 2> " + tmp.path
|
188
|
+
success = system(command)
|
189
|
+
if success
|
190
|
+
begin
|
191
|
+
while (line = tmp.readline)
|
192
|
+
line.chomp
|
193
|
+
selected_string = line
|
194
|
+
end
|
195
|
+
rescue EOFError
|
196
|
+
tmp.close
|
197
|
+
end
|
198
|
+
return selected_string
|
199
|
+
else
|
200
|
+
tmp.close!
|
201
|
+
return success
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
def option_string()
|
208
|
+
|
209
|
+
unless @path_to_heartbeat
|
210
|
+
ostring = "heartbeat "
|
211
|
+
else
|
212
|
+
ostring = @path_to_heartbeat + " "
|
213
|
+
end
|
214
|
+
|
215
|
+
if @option
|
216
|
+
ostring += @option + " "
|
217
|
+
end
|
218
|
+
|
219
|
+
if @debug_level
|
220
|
+
ostring += "-d " + @debug_level
|
221
|
+
end
|
222
|
+
|
223
|
+
return ostring
|
224
|
+
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|