drbd 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.rdoc +26 -9
  2. data/VERSION +1 -1
  3. data/lib/drbd.rb +93 -31
  4. metadata +4 -4
@@ -25,11 +25,17 @@ Ruby wrapper for DRBD
25
25
 
26
26
 
27
27
  == How it works
28
- - simply fetch data from remote host
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 specify command to be executed
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.7
1
+ 0.1.8
@@ -1,35 +1,89 @@
1
1
  require 'rubygems'
2
2
  require 'nokogiri'
3
+ require 'net/ssh'
3
4
  class DRBD
4
- attr_reader :resources, :host, :command
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
- io = IO.popen("ssh #{@host} \"#{@command} dump-xml\"")
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
- io = IO.popen("ssh #{@host} \"#{@command} status\"")
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
120
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
128
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
140
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
148
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
156
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
163
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
171
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
179
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
187
- system(command)
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 = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
196
- system(command)
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: 21
4
+ hash: 11
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 7
10
- version: 0.1.7
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-09 00:00:00 +01:00
18
+ date: 2011-02-16 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency