drbd 0.1.7 → 0.1.8
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/README.rdoc +26 -9
- data/VERSION +1 -1
- data/lib/drbd.rb +93 -31
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -25,11 +25,17 @@ Ruby wrapper for DRBD
|
|
25
25
|
|
26
26
|
|
27
27
|
== How it works
|
28
|
-
-
|
28
|
+
- you can connect to remote node with hostname, login will be executed with current user and his key
|
29
29
|
|
30
30
|
<tt>d = Drbd.new("fqdn.domain.tld")</tt>
|
31
31
|
|
32
|
-
you can
|
32
|
+
or you can "recycle" existing Net::SSH session to improve performance:
|
33
|
+
|
34
|
+
<tt>ssh = Net:SSH.start("fwdn.domain.tld", "root", :password => 'secret')</tt>
|
35
|
+
|
36
|
+
<tt>d = Drbd.new(ssh)</tt>
|
37
|
+
|
38
|
+
specify command to be executed:
|
33
39
|
|
34
40
|
<tt>d = Drbd.new("fqdn.domain.tld", :command => 'sudo /sbin/drbdadm')</tt>
|
35
41
|
|
@@ -55,6 +61,20 @@ Ruby wrapper for DRBD
|
|
55
61
|
|
56
62
|
<tt>r.down!</tt>
|
57
63
|
|
64
|
+
- analyze actual state
|
65
|
+
|
66
|
+
<tt>r.resync_running?</tt>
|
67
|
+
|
68
|
+
<tt>r.consistent?</tt>
|
69
|
+
|
70
|
+
<tt>r.connected?</tt>
|
71
|
+
|
72
|
+
<tt>r.down?</tt>
|
73
|
+
|
74
|
+
<tt>r.primary?</tt>
|
75
|
+
|
76
|
+
<tt>r.secondary?</tt>
|
77
|
+
|
58
78
|
- get resource name
|
59
79
|
|
60
80
|
<tt>r.name</tt>
|
@@ -67,15 +87,13 @@ Ruby wrapper for DRBD
|
|
67
87
|
|
68
88
|
<tt>r.hosts</tt>
|
69
89
|
|
70
|
-
- get status for resource
|
71
|
-
|
72
|
-
<tt>r.status</tt>
|
73
|
-
|
74
90
|
- get node addresses
|
75
91
|
|
76
92
|
<tt>r.hosts.map{|h| h.address }</tt>
|
77
93
|
|
78
|
-
- get status
|
94
|
+
- get status for resource
|
95
|
+
|
96
|
+
<tt>r.status</tt>
|
79
97
|
|
80
98
|
resource status is hash with keys:
|
81
99
|
|
@@ -135,11 +153,10 @@ Ruby wrapper for DRBD
|
|
135
153
|
|
136
154
|
== TODO
|
137
155
|
|
138
|
-
* Replace IO.popen("ssh ...") with native ruby net/ssh
|
139
156
|
* Add states to actions (analyze exit status)
|
140
157
|
* Test suite
|
141
158
|
|
142
159
|
|
143
160
|
== Copyright
|
144
161
|
|
145
|
-
Copyright (c) 2011 Adam Kliment. See LICENSE for details.
|
162
|
+
Copyright (c) 2011 Adam Kliment, Virtualmaster.cz. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.8
|
data/lib/drbd.rb
CHANGED
@@ -1,35 +1,89 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'nokogiri'
|
3
|
+
require 'net/ssh'
|
3
4
|
class DRBD
|
4
|
-
attr_reader :resources, :
|
5
|
+
attr_reader :resources, :connection, :command
|
5
6
|
|
6
7
|
def initialize host, opts = {}
|
8
|
+
connect host
|
7
9
|
parse_opts opts
|
8
|
-
@host = host
|
9
10
|
load!
|
10
11
|
end
|
11
12
|
|
13
|
+
def connect host
|
14
|
+
if host.class == String
|
15
|
+
@connection = Net::SSH.start(host, ENV['USER'])
|
16
|
+
elsif host.class == Net::SSH::Connection::Session
|
17
|
+
@connection = host
|
18
|
+
else
|
19
|
+
raise "Connection must be String with hostname or Net::SSH::Connection::Session object but it is #{host.class}."
|
20
|
+
end
|
21
|
+
end
|
12
22
|
def parse_opts opts
|
13
23
|
opts[:command].nil? ? @command = "sudo /sbin/drbdadm" : @command = opts[:command]
|
14
24
|
end
|
15
25
|
|
26
|
+
def ssh_output(command)
|
27
|
+
stdout = ""
|
28
|
+
stderr = ""
|
29
|
+
channel = @connection.open_channel do |ch|
|
30
|
+
ch.exec(command) do |ch, success|
|
31
|
+
raise "could not execute command" unless success
|
32
|
+
|
33
|
+
# "on_data" is called when the process writes something to stdout
|
34
|
+
ch.on_data do |c, data|
|
35
|
+
stdout << data
|
36
|
+
end
|
37
|
+
|
38
|
+
# "on_extended_data" is called when the process writes something to stderr
|
39
|
+
ch.on_extended_data do |c, type, data|
|
40
|
+
stderr << data
|
41
|
+
end
|
42
|
+
#ch.on_close { puts "done!" }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
channel.wait
|
46
|
+
#puts stderr
|
47
|
+
return stdout
|
48
|
+
end
|
49
|
+
|
50
|
+
def ssh_exec(command)
|
51
|
+
exit_status = nil
|
52
|
+
channel = @connection.open_channel do |ch|
|
53
|
+
ch.exec command
|
54
|
+
|
55
|
+
ch.on_data do |c, data|
|
56
|
+
puts data
|
57
|
+
end
|
58
|
+
ch.on_extended_data do |c, type, data|
|
59
|
+
puts data
|
60
|
+
end
|
61
|
+
|
62
|
+
ch.on_request("exit-status") do |ch, data|
|
63
|
+
exit_status = data.read_long
|
64
|
+
end
|
65
|
+
end
|
66
|
+
channel.wait
|
67
|
+
|
68
|
+
if exit_status > 0
|
69
|
+
return exit_status
|
70
|
+
else
|
71
|
+
return true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
16
75
|
def load!
|
17
76
|
load_resources!
|
18
77
|
load_status!
|
19
78
|
end
|
20
79
|
|
21
80
|
def load_resources!
|
22
|
-
|
23
|
-
xml = io.readlines.join("\n")
|
24
|
-
io.close
|
81
|
+
xml = ssh_output("#{@command} dump-xml")
|
25
82
|
@resources = Resource.load_config(xml, self)
|
26
83
|
end
|
27
84
|
|
28
85
|
def load_status!
|
29
|
-
|
30
|
-
xml = io.readlines.join("\n")
|
31
|
-
io.close
|
32
|
-
|
86
|
+
xml = ssh_output("#{@command} status")
|
33
87
|
statuses = Status.new(xml).resources
|
34
88
|
set_resources_status statuses
|
35
89
|
end
|
@@ -116,16 +170,26 @@ class DRBD
|
|
116
170
|
args = "primary #{self.name}"
|
117
171
|
end
|
118
172
|
|
119
|
-
command = "
|
120
|
-
|
173
|
+
command = "#{drbd.command} #{args}"
|
174
|
+
self.drbd.ssh_exec(command)
|
121
175
|
drbd.load_status!
|
122
176
|
nil
|
123
177
|
end
|
124
178
|
|
179
|
+
|
125
180
|
def secondary!
|
126
181
|
args = "-- --overwrite-data-of-peer secondary #{self.name}"
|
127
|
-
command = "
|
128
|
-
|
182
|
+
command = "#{drbd.command} #{args}"
|
183
|
+
self.drbd.ssh_exec(command)
|
184
|
+
drbd.load_status!
|
185
|
+
nil
|
186
|
+
end
|
187
|
+
|
188
|
+
def syncer!
|
189
|
+
args = "syncer #{self.name}"
|
190
|
+
|
191
|
+
command = "#{drbd.command} #{args}"
|
192
|
+
self.drbd.ssh_exec(command)
|
129
193
|
drbd.load_status!
|
130
194
|
nil
|
131
195
|
end
|
@@ -136,55 +200,55 @@ class DRBD
|
|
136
200
|
|
137
201
|
def connect!
|
138
202
|
args = "connect #{self.name}"
|
139
|
-
command = "
|
140
|
-
|
203
|
+
command = "#{drbd.command} #{args}"
|
204
|
+
self.drbd.ssh_exec(command)
|
141
205
|
drbd.load_status!
|
142
206
|
nil
|
143
207
|
end
|
144
208
|
|
145
209
|
def disconnect!
|
146
210
|
args = "disconnect #{self.name}"
|
147
|
-
command = "
|
148
|
-
|
211
|
+
command = "#{drbd.command} #{args}"
|
212
|
+
self.drbd.ssh_exec(command)
|
149
213
|
drbd.load_status!
|
150
214
|
nil
|
151
215
|
end
|
152
216
|
|
153
217
|
def resize!
|
154
218
|
args = "-- --assume-peer-has-space resize #{self.name}"
|
155
|
-
command = "
|
156
|
-
|
219
|
+
command = "#{drbd.command} #{args}"
|
220
|
+
self.drbd.ssh_exec(command)
|
157
221
|
drbd.load_status!
|
158
222
|
end
|
159
223
|
|
160
224
|
def attach!
|
161
225
|
args = "attach #{self.name}"
|
162
|
-
command = "
|
163
|
-
|
226
|
+
command = "#{drbd.command} #{args}"
|
227
|
+
self.drbd.ssh_exec(command)
|
164
228
|
drbd.load_status!
|
165
229
|
nil
|
166
230
|
end
|
167
231
|
|
168
232
|
def detach!
|
169
233
|
args = "detach #{self.name}"
|
170
|
-
command = "
|
171
|
-
|
234
|
+
command = "#{drbd.command} #{args}"
|
235
|
+
self.drbd.ssh_exec(command)
|
172
236
|
drbd.load_status!
|
173
237
|
nil
|
174
238
|
end
|
175
239
|
|
176
240
|
def up!
|
177
241
|
args = "up #{self.name}"
|
178
|
-
command = "
|
179
|
-
|
242
|
+
command = "#{drbd.command} #{args}"
|
243
|
+
self.drbd.ssh_exec(command)
|
180
244
|
drbd.load_status!
|
181
245
|
nil
|
182
246
|
end
|
183
247
|
|
184
248
|
def down!
|
185
249
|
args = "down #{self.name}"
|
186
|
-
command = "
|
187
|
-
|
250
|
+
command = "#{drbd.command} #{args}"
|
251
|
+
self.drbd.ssh_exec(command)
|
188
252
|
drbd.load_status!
|
189
253
|
nil
|
190
254
|
end
|
@@ -192,8 +256,8 @@ class DRBD
|
|
192
256
|
def init_metadata!
|
193
257
|
if self.down?
|
194
258
|
args = "-- --force create-md #{self.name}"
|
195
|
-
command = "
|
196
|
-
|
259
|
+
command = "#{drbd.command} #{args}"
|
260
|
+
self.drbd.ssh_exec(command)
|
197
261
|
return true
|
198
262
|
else
|
199
263
|
return false
|
@@ -238,8 +302,6 @@ class DRBD
|
|
238
302
|
r
|
239
303
|
end
|
240
304
|
end
|
241
|
-
|
242
|
-
|
243
305
|
end
|
244
306
|
end
|
245
307
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: drbd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 8
|
10
|
+
version: 0.1.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Kliment
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-16 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|