drbd 0.1.0 → 0.1.1

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 (4) hide show
  1. data/README.rdoc +53 -5
  2. data/VERSION +1 -1
  3. data/lib/drbd.rb +73 -20
  4. metadata +4 -4
data/README.rdoc CHANGED
@@ -10,34 +10,82 @@ Ruby wrapper for DRBD
10
10
 
11
11
  == Limitations
12
12
 
13
- * Just one-morning prototype
14
13
  * Best with drbd version > 8.3.7
14
+ * Hostname used for connection must be one of hostnames in drbd.conf (FQDN ideally)
15
+ * It'sJust one-morning's prototype, take patience
15
16
  * No tests
16
17
  * No documentation
17
18
  * Absolutely no warranty, use it at your own risk
18
19
 
20
+ == Installation
21
+
22
+ <code>gem install drbd</code>
19
23
 
20
- == How it works
21
24
 
25
+ == How it works
26
+ # simply fetch data from remote host
22
27
  d = Drbd.new("fqdn.domain.tld")
23
28
 
29
+ # you can specify command to be executed
30
+
31
+ d = Drbd.new("fqdn.domain.tld", :command => 'sudo /sbin/drbdadm')
32
+
33
+ # obtain array of configured resources
24
34
  r = d.resources.first
25
35
 
36
+ # get resource name
26
37
  r.name
27
38
 
39
+ # get resource protocol
40
+ r.protocol
41
+
42
+ # get hosts for resource
43
+ r.hosts
44
+
45
+ # get status for resource
46
+ r.status
47
+
48
+ # get node addresses
28
49
  r.hosts.map{|h| h.address }
29
50
 
51
+ # get status
52
+ # resource status is hash with keys:
53
+ # [:cs, :resynced_percent, :minor, :ro1, :ds1, :ro2, :ds2, :name]
30
54
  r.status
31
55
 
56
+ # find resource by name
32
57
  r = d.find_resource_by_name("r0")
33
58
 
34
- r.consinstent?
35
-
59
+ # find resource by backing disk
36
60
  r = d.find_resource_by_disk("/dev/volgroup-logvolume--name")
37
61
 
62
+ # true if both of devices are UpToDate
63
+ r.consinstent?
64
+
65
+ # true if resynced_percent is present in status
38
66
  r.resync_running?
39
67
 
40
- r.status[:resynced_percent]
68
+ # true if resource status is "Connected"
69
+ r.up?
70
+
71
+ # true if resource status is "Unconfigured"
72
+ r.down?
73
+
74
+ # perform drbdadm up on resource (use at your own risk!)
75
+ r.up!
76
+
77
+ # perform drbdadm down on resource (use at your own risk!)
78
+ r.down!
79
+
80
+ # perform forced drbdadm create-md on resource (use at your own risk!)
81
+ r.init_metadata
82
+
83
+
84
+ == TODO
85
+
86
+ * Replace IO.popen("ssh ...") with native ruby net/ssh
87
+ * Add states to actions (analyze exit status)
88
+ * Test suite
41
89
 
42
90
 
43
91
  == Copyright
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
data/lib/drbd.rb CHANGED
@@ -1,24 +1,29 @@
1
1
  require 'rubygems'
2
2
  require 'nokogiri'
3
3
  class DRBD
4
- attr_reader :resources
4
+ attr_reader :resources, :host, :command
5
5
 
6
- def initialize host
6
+ def initialize host, opts = {}
7
+ parse_opts opts
7
8
  @host = host
8
9
  load!
9
10
  end
10
11
 
12
+ def parse_opts opts
13
+ opts[:command].nil? ? @command = "sudo /sbin/drbdadm" : @command = opts[:command]
14
+ end
15
+
11
16
  def load!
12
17
  load_resources!
13
18
  load_status!
14
19
  end
15
20
 
16
21
  def load_resources!
17
- @resources = Config.new(IO.popen("ssh #{@host} \"sudo /sbin/drbdadm dump-xml\"")).resources
22
+ @resources = Resource.load_config(IO.popen("ssh #{@host} \"#{@command} dump-xml\""), self)
18
23
  end
19
24
 
20
25
  def load_status!
21
- raw_xml = IO.popen("ssh #{@host} \"sudo /sbin/drbdadm status\"")
26
+ raw_xml = IO.popen("ssh #{@host} \"#{@command} status\"")
22
27
  statuses = Status.new(raw_xml).resources
23
28
  set_resources_status statuses
24
29
  end
@@ -37,35 +42,33 @@ class DRBD
37
42
  def find_resource_by_disk disk_name
38
43
  @resources.select{|r| r.hosts.inject(false){|sum,h| (h.disk == disk_name && sum == false) ? true : sum}}.first
39
44
  end
40
-
41
- class Config
42
- attr_reader :xml
43
-
44
- def initialize xml
45
- @xml = Nokogiri::XML(xml)
46
- end
47
-
48
- def resources
49
- @xml.xpath("//config/resource").map{|r| Resource.new r }
50
- end
51
- end
52
-
45
+
53
46
  class Host
54
- attr_reader :name, :device, :disk, :address, :meta_disk
47
+ attr_reader :name, :device, :disk, :address, :meta_disk, :minor
55
48
  def initialize host
56
49
  @name = host['name']
57
50
  @device = host.xpath(".//device").text
51
+ @minor = host.xpath(".//device").attr("minor").value
58
52
  @disk = host.xpath(".//disk").text
59
53
  @address = host.xpath(".//address").text
54
+ @family = host.xpath(".//address").attr("family").value
55
+ @port = host.xpath(".//address").attr("port").value
60
56
  @meta_disk = host.xpath(".//meta-disk").text
61
57
  end
62
58
  end
63
59
 
64
60
  class Resource
65
- attr_reader :name, :device, :disk, :address, :meta_disk, :hosts
61
+ attr_reader :name, :protocol, :hosts, :drbd
66
62
  attr_accessor :status
67
- def initialize nokogiri_resource
63
+
64
+ def self.load_config raw, drbd
65
+ xml = Nokogiri::XML(raw)
66
+ xml.xpath("//config/resource").map{|r| Resource.new r, drbd }
67
+ end
68
+
69
+ def initialize nokogiri_resource, drbd
68
70
  xml = nokogiri_resource
71
+ @drbd = drbd
69
72
  @name = xml['name']
70
73
  @protocol = xml['protocol']
71
74
  @hosts = xml.xpath(".//host").to_a.map do |host_xml|
@@ -80,6 +83,53 @@ class DRBD
80
83
  def consistent?
81
84
  status[:ds1] == "UpToDate" && status[:ds2] == "UpToDate" && status[:resynced_percent] == nil
82
85
  end
86
+
87
+ def up?
88
+ status[:cs] == "Connected" || status[:cs] == "SyncTarget"
89
+ end
90
+
91
+ def down?
92
+ status[:cs] == "Unconfigured"
93
+ end
94
+
95
+ def up!
96
+ args = "up #{self.name}"
97
+ command = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
98
+ system(command)
99
+ drbd.load_status!
100
+ end
101
+
102
+ def down!
103
+ args = "down #{self.name}"
104
+ command = "ssh #{drbd.host} \"#{drbd.command} #{args}\""
105
+ system(command)
106
+ drbd.load_status!
107
+ end
108
+
109
+ def init_metadata!
110
+ if self.down?
111
+ #drbdmeta 0 v08 /dev/mapper/dikobraz-www--emailmaster--cz_root_meta 0 create-md
112
+ command = "ssh #{drbd.host} \"sudo /sbin/drbdmeta --force #{local_minor} v08 #{local_host.meta_disk} 0 create-md\""
113
+ system(command)
114
+ return true
115
+ else
116
+ return false
117
+ end
118
+ end
119
+
120
+
121
+ def local_host
122
+ hosts.select{|h| h.name == drbd.host}.first
123
+ end
124
+
125
+ def local_minor
126
+ retrurn nil if local_host == nil
127
+ local_host.minor
128
+ end
129
+
130
+ def state
131
+ status[:cs]
132
+ end
83
133
  end
84
134
 
85
135
  class Status
@@ -105,3 +155,6 @@ class DRBD
105
155
  end
106
156
  end
107
157
 
158
+ D = DRBD.new("dikobraz.vmin.cz")
159
+ require 'irb'
160
+ IRB.start
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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
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-01-17 00:00:00 +01:00
18
+ date: 2011-01-18 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency