ruby-lvm 0.0.1 → 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.
- data.tar.gz.sig +0 -0
- data/History.txt +10 -2
- data/Manifest.txt +18 -17
- data/README.txt +22 -9
- data/Rakefile +3 -2
- data/Todo.txt +7 -8
- data/examples/create_snapshot.rb +20 -8
- data/examples/error_handling.rb +8 -2
- data/examples/show_lvm_config.rb +40 -0
- data/lib/lvm.rb +67 -24
- data/lib/lvm/external.rb +25 -30
- data/lib/lvm/logical_volume.rb +9 -0
- data/lib/lvm/logical_volume_segment.rb +5 -0
- data/lib/lvm/logical_volumes.rb +37 -0
- data/lib/lvm/physical_volume.rb +5 -0
- data/lib/lvm/physical_volume_segment.rb +5 -0
- data/lib/lvm/physical_volumes.rb +37 -0
- data/lib/lvm/userland.rb +5 -0
- data/lib/lvm/volume_group.rb +5 -0
- data/lib/lvm/volume_groups.rb +46 -0
- data/lib/lvm/volumes.rb +16 -0
- data/lib/lvm/wrapper.rb +53 -0
- data/lib/lvm/wrapper/constants.rb +11 -0
- data/lib/lvm/wrapper/lvs.rb +127 -0
- data/lib/lvm/wrapper/lvsseg.rb +59 -0
- data/lib/lvm/wrapper/pvs.rb +84 -0
- data/lib/lvm/wrapper/pvsseg.rb +57 -0
- data/lib/lvm/wrapper/vgs.rb +112 -0
- metadata +109 -90
- metadata.gz.sig +0 -0
- data/examples/show_volumes.rb +0 -26
- data/helpers/generate_field_data.rb +0 -117
- data/lib/lvm/attrib/lvs.yaml +0 -88
- data/lib/lvm/attrib/pvs.yaml +0 -46
- data/lib/lvm/attrib/vgs.yaml +0 -55
- data/lib/lvm/lv.rb +0 -19
- data/lib/lvm/lvmanager.rb +0 -95
- data/lib/lvm/lvs.rb +0 -143
- data/lib/lvm/lvseg.rb +0 -14
- data/lib/lvm/proc.rb +0 -39
- data/lib/lvm/pv.rb +0 -15
- data/lib/lvm/pvmanager.rb +0 -22
- data/lib/lvm/pvs.rb +0 -109
- data/lib/lvm/pvseg.rb +0 -14
- data/lib/lvm/vg.rb +0 -15
- data/lib/lvm/vgmanager.rb +0 -68
- data/lib/lvm/vgs.rb +0 -123
data/lib/lvm/lvseg.rb
DELETED
data/lib/lvm/proc.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
module LVMWrapper
|
2
|
-
class External
|
3
|
-
class ExternalFailure < RuntimeError; end
|
4
|
-
|
5
|
-
# Class Methods
|
6
|
-
#
|
7
|
-
class<<self
|
8
|
-
# Return output of external command
|
9
|
-
# Yield each line or return entire output
|
10
|
-
#
|
11
|
-
def cmd(cmd)
|
12
|
-
output = []
|
13
|
-
IO.popen(cmd, "r") do |p|
|
14
|
-
while line = p.gets
|
15
|
-
if defined? yield
|
16
|
-
yield line
|
17
|
-
else
|
18
|
-
output << line
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
stat = $?
|
23
|
-
if stat.exited?
|
24
|
-
if stat.exitstatus > 0
|
25
|
-
raise ExternalFailure, "Fatal error, `#{cmd}` returned #{stat.exitstatus}"
|
26
|
-
end
|
27
|
-
elsif stat.signaled?
|
28
|
-
raise ExternalFailure, "Fatal error, `#{cmd}` got signal #{stat.termsig} and terminated"
|
29
|
-
elsif stat.stopped?
|
30
|
-
raise ExternalFailure, "Fatal error, `#{cmd}` got signal #{stat.stopsig} and is stopped"
|
31
|
-
end
|
32
|
-
output.join
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Instance Methods
|
37
|
-
#
|
38
|
-
end # class
|
39
|
-
end # module
|
data/lib/lvm/pv.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
module LVMWrapper
|
2
|
-
class PhysicalVolume
|
3
|
-
def initialize(args)
|
4
|
-
@attributes = args
|
5
|
-
|
6
|
-
# so many attributes.. we let the caller define them :)
|
7
|
-
meta = class << self; self; end
|
8
|
-
args.each_key do |name|
|
9
|
-
meta.send(:define_method, name) { @attributes[name] }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# helper methods
|
14
|
-
end # class
|
15
|
-
end # module
|
data/lib/lvm/pvmanager.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'lvm/pv'
|
2
|
-
require 'lvm/pvs'
|
3
|
-
require 'lvm/pvseg'
|
4
|
-
|
5
|
-
module LVMWrapper
|
6
|
-
class PhysicalVolumeManager
|
7
|
-
|
8
|
-
def initialize(lvm)
|
9
|
-
@lvm = lvm
|
10
|
-
end
|
11
|
-
|
12
|
-
def create(args)
|
13
|
-
end
|
14
|
-
|
15
|
-
def list
|
16
|
-
data = @lvm.cmd(PVS.command)
|
17
|
-
PVS.parse(data)
|
18
|
-
end
|
19
|
-
alias pvs list
|
20
|
-
|
21
|
-
end # class
|
22
|
-
end # module
|
data/lib/lvm/pvs.rb
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
module LVMWrapper
|
2
|
-
class PVS
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
BASE_COMMAND = 'pvs --verbose --separator=, --noheadings --nosuffix --units=b --unbuffered --options %s'
|
6
|
-
ATTRIBUTES = 'attrib/pvs.yaml'
|
7
|
-
|
8
|
-
EMPTY = '-'
|
9
|
-
|
10
|
-
# pv_attr attribute handling constants
|
11
|
-
# roughly by order referenced in lib/report/report.c:360 (_pvstatus_disp)
|
12
|
-
#
|
13
|
-
ALLOCATABLE = {
|
14
|
-
# code says its a boolean
|
15
|
-
'a' => true
|
16
|
-
}
|
17
|
-
EXPORTED = {
|
18
|
-
# code says its a boolean
|
19
|
-
'x' => true
|
20
|
-
}
|
21
|
-
|
22
|
-
def self.command
|
23
|
-
opts = []
|
24
|
-
attributes = YAML.load_file(File.dirname(__FILE__) + '/' + ATTRIBUTES)
|
25
|
-
attributes.each do |a|
|
26
|
-
opts << a[:option]
|
27
|
-
end
|
28
|
-
|
29
|
-
BASE_COMMAND % opts.join(",")
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.parse_pv_attr(pv_attr)
|
33
|
-
ret = {}
|
34
|
-
# translate them into nice symbols and a couple booleans
|
35
|
-
ret[:allocatable] = ALLOCATABLE[pv_attr[0].chr] ? true : false
|
36
|
-
ret[:exported] = EXPORTED[pv_attr[1].chr] ? true : false
|
37
|
-
ret
|
38
|
-
end
|
39
|
-
|
40
|
-
# Parses the output of self.command
|
41
|
-
def self.parse(output)
|
42
|
-
volumes = []
|
43
|
-
segs = []
|
44
|
-
|
45
|
-
# lvs columns will become lv attributes
|
46
|
-
attributes = YAML.load_file(File.dirname(__FILE__) + '/' + ATTRIBUTES)
|
47
|
-
|
48
|
-
output.split("\n").each do |line|
|
49
|
-
line.strip!
|
50
|
-
# each line of output is comma separated values
|
51
|
-
values = line.split(",")
|
52
|
-
# empty values to nil
|
53
|
-
values.map! do |value|
|
54
|
-
if value.empty?
|
55
|
-
nil
|
56
|
-
else
|
57
|
-
value
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
args = {}
|
62
|
-
# match up attribute => value
|
63
|
-
values.size.times do |i|
|
64
|
-
method = attributes[i][:method].to_sym
|
65
|
-
value = values[i]
|
66
|
-
# use our hints first for type conversion
|
67
|
-
if attributes[i][:type_hint] == "Integer"
|
68
|
-
value = value.to_i
|
69
|
-
elsif attributes[i][:type_hint] == "Float"
|
70
|
-
value = value.to_f
|
71
|
-
end
|
72
|
-
args[method] = value
|
73
|
-
end
|
74
|
-
|
75
|
-
# pvs produces duplicate lines while elaborating on the segments being
|
76
|
-
# used, collect the segment data
|
77
|
-
segs << PhysicalVolumeSegment.new(:start => args[:pvseg_start], :size => args[:pvseg_size])
|
78
|
-
if args[:pvseg_start] == args[:pe_alloc_count]
|
79
|
-
args[:segments] = segs.dup
|
80
|
-
# already have em
|
81
|
-
args.delete(:pvseg_start)
|
82
|
-
args.delete(:pvseg_size)
|
83
|
-
segs.clear
|
84
|
-
else
|
85
|
-
next
|
86
|
-
end
|
87
|
-
|
88
|
-
# now we force some types to ints since we've requested them as bytes
|
89
|
-
# without a suffix
|
90
|
-
args[:size] = args[:size].to_i
|
91
|
-
|
92
|
-
# we resolve the attributes line to nicer symbols
|
93
|
-
args.merge!(parse_pv_attr(args[:attr]))
|
94
|
-
|
95
|
-
# finally build our object
|
96
|
-
volume = PhysicalVolume.new(args)
|
97
|
-
|
98
|
-
if block_given?
|
99
|
-
yield volume
|
100
|
-
else
|
101
|
-
volumes << volume
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
volumes
|
106
|
-
end # parse
|
107
|
-
|
108
|
-
end # class
|
109
|
-
end # module
|
data/lib/lvm/pvseg.rb
DELETED
data/lib/lvm/vg.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
module LVMWrapper
|
2
|
-
class VolumeGroup
|
3
|
-
def initialize(args)
|
4
|
-
@attributes = args
|
5
|
-
|
6
|
-
# so many attributes.. we let the caller define them :)
|
7
|
-
meta = class << self; self; end
|
8
|
-
args.each_key do |name|
|
9
|
-
meta.send(:define_method, name) { @attributes[name] }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# helper methods
|
14
|
-
end # class
|
15
|
-
end # module
|
data/lib/lvm/vgmanager.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
require 'lvm/vg'
|
2
|
-
require 'lvm/vgs'
|
3
|
-
|
4
|
-
module LVMWrapper
|
5
|
-
class VolumeGroupManager
|
6
|
-
|
7
|
-
def initialize(lvm)
|
8
|
-
@lvm = lvm
|
9
|
-
end
|
10
|
-
|
11
|
-
# vgcfgbackup Backup volume group configuration(s)
|
12
|
-
# vgcfgrestore Restore volume group configuration
|
13
|
-
# vgchange Change volume group attributes
|
14
|
-
# vgck Check the consistency of volume group(s)
|
15
|
-
# vgconvert Change volume group metadata format
|
16
|
-
# vgcreate Create a volume group
|
17
|
-
# vgdisplay Display volume group information
|
18
|
-
# vgexport Unregister volume group(s) from the system
|
19
|
-
# vgextend Add physical volumes to a volume group
|
20
|
-
# vgimport Register exported volume group with system
|
21
|
-
# vgmerge Merge volume groups
|
22
|
-
# vgmknodes Create the special files for volume group devices in /dev
|
23
|
-
# vgreduce Remove physical volume(s) from a volume group
|
24
|
-
# vgremove Remove volume group(s)
|
25
|
-
# vgrename Rename a volume group
|
26
|
-
# vgs Display information about volume groups
|
27
|
-
# vgscan Search for all volume groups
|
28
|
-
# vgsplit Move physical volumes into a new volume group
|
29
|
-
|
30
|
-
def create(args)
|
31
|
-
end
|
32
|
-
|
33
|
-
def change(args)
|
34
|
-
vgname = args[:vgname] || nil
|
35
|
-
|
36
|
-
raise ArgumentError if vgname.nil?
|
37
|
-
|
38
|
-
args.delete(:vgname)
|
39
|
-
|
40
|
-
@lvm.cmd("vgchange #{args_to_long_opts(args)} #{vgname}")
|
41
|
-
end
|
42
|
-
|
43
|
-
# ruby hash of key values to long options
|
44
|
-
def args_to_long_opts(args)
|
45
|
-
opts = []
|
46
|
-
args.each do |key,value|
|
47
|
-
opts << "--#{key.to_s} #{value}"
|
48
|
-
end
|
49
|
-
opts.join(" ")
|
50
|
-
end
|
51
|
-
|
52
|
-
def lookup(vgname)
|
53
|
-
raw_data = @lvm.cmd("#{VGS.command} #{vgname}")
|
54
|
-
VGS.parse(raw_data)[0]
|
55
|
-
end
|
56
|
-
|
57
|
-
def [](vgname)
|
58
|
-
lookup(vgname)
|
59
|
-
end
|
60
|
-
|
61
|
-
def list
|
62
|
-
data = @lvm.cmd(VGS.command)
|
63
|
-
VGS.parse(data)
|
64
|
-
end
|
65
|
-
alias vgs list
|
66
|
-
|
67
|
-
end # class
|
68
|
-
end # module
|
data/lib/lvm/vgs.rb
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
module LVMWrapper
|
2
|
-
class VGS
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
BASE_COMMAND = 'vgs --verbose --separator=, --noheadings --nosuffix --units=b --unbuffered --options %s'
|
6
|
-
ATTRIBUTES = 'attrib/vgs.yaml'
|
7
|
-
|
8
|
-
EMPTY = '-'
|
9
|
-
|
10
|
-
# vg_attr attribute handling constants
|
11
|
-
# roughly by order referenced in lib/report/report.c:360 (_vgstatus_disp)
|
12
|
-
#
|
13
|
-
PERMISSIONS = {
|
14
|
-
'w' => :writeable,
|
15
|
-
'r' => :readonly,
|
16
|
-
}
|
17
|
-
RESIZEABLE = {
|
18
|
-
# code says its a boolean
|
19
|
-
'z' => true
|
20
|
-
}
|
21
|
-
EXPORTED = {
|
22
|
-
# code says its a boolean
|
23
|
-
'x' => true
|
24
|
-
}
|
25
|
-
PARTIAL = {
|
26
|
-
# code says its a boolean
|
27
|
-
'p' => true
|
28
|
-
}
|
29
|
-
ALLOCATION_POLICY = {
|
30
|
-
'c' => :contiguous,
|
31
|
-
'l' => :cling,
|
32
|
-
'n' => :normal,
|
33
|
-
'a' => :anywhere,
|
34
|
-
'i' => :inherited,
|
35
|
-
'C' => :contiguous_locked,
|
36
|
-
'L' => :cling_locked,
|
37
|
-
'N' => :normal_locked,
|
38
|
-
'A' => :anywhere_locked,
|
39
|
-
'I' => :inherited_locked
|
40
|
-
}
|
41
|
-
CLUSTERED = {
|
42
|
-
# code says its a boolean
|
43
|
-
'c' => true
|
44
|
-
}
|
45
|
-
|
46
|
-
def self.command
|
47
|
-
opts = []
|
48
|
-
attributes = YAML.load_file(File.dirname(__FILE__) + '/' + ATTRIBUTES)
|
49
|
-
attributes.each do |a|
|
50
|
-
opts << a[:option]
|
51
|
-
end
|
52
|
-
|
53
|
-
BASE_COMMAND % opts.join(",")
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.parse_vg_attr(vg_attr)
|
57
|
-
ret = {}
|
58
|
-
# translate them into nice symbols and a couple booleans
|
59
|
-
ret[:permissions] = PERMISSIONS[vg_attr[0].chr]
|
60
|
-
ret[:resizeable] = RESIZEABLE[vg_attr[1].chr] ? true : false
|
61
|
-
ret[:exported] = EXPORTED[vg_attr[2].chr] ? true : false
|
62
|
-
ret[:partial] = PARTIAL[vg_attr[3].chr] ? true : false
|
63
|
-
ret[:allocation_policy] = ALLOCATION_POLICY[vg_attr[4].chr]
|
64
|
-
ret[:clustered] = CLUSTERED[vg_attr[5].chr] ? true : false
|
65
|
-
ret
|
66
|
-
end
|
67
|
-
|
68
|
-
# Parses the output of self.command
|
69
|
-
def self.parse(output)
|
70
|
-
volumes = []
|
71
|
-
|
72
|
-
# lvs columns will become lv attributes
|
73
|
-
attributes = YAML.load_file(File.dirname(__FILE__) + '/' + ATTRIBUTES)
|
74
|
-
|
75
|
-
output.split("\n").each do |line|
|
76
|
-
line.strip!
|
77
|
-
# each line of output is comma separated values
|
78
|
-
values = line.split(",")
|
79
|
-
# empty values to nil
|
80
|
-
values.map! do |value|
|
81
|
-
if value.empty?
|
82
|
-
nil
|
83
|
-
else
|
84
|
-
value
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
args = {}
|
89
|
-
# match up attribute => value
|
90
|
-
values.size.times do |i|
|
91
|
-
method = attributes[i][:method].to_sym
|
92
|
-
value = values[i]
|
93
|
-
# use our hints first for type conversion
|
94
|
-
if attributes[i][:type_hint] == "Integer"
|
95
|
-
value = value.to_i
|
96
|
-
elsif attributes[i][:type_hint] == "Float"
|
97
|
-
value = value.to_f
|
98
|
-
end
|
99
|
-
args[method] = value
|
100
|
-
end
|
101
|
-
|
102
|
-
# now we force some types to ints since we've requested them as bytes
|
103
|
-
# without a suffix
|
104
|
-
args[:size] = args[:size].to_i
|
105
|
-
|
106
|
-
# we resolve the attributes line to nicer symbols
|
107
|
-
args.merge!(parse_vg_attr(args[:attr]))
|
108
|
-
|
109
|
-
# finally build our object
|
110
|
-
volume = VolumeGroup.new(args)
|
111
|
-
|
112
|
-
if block_given?
|
113
|
-
yield volume
|
114
|
-
else
|
115
|
-
volumes << volume
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
volumes
|
120
|
-
end # parse
|
121
|
-
|
122
|
-
end # class
|
123
|
-
end # module
|