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.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,6 +1,14 @@
|
|
1
|
-
=== 0.
|
1
|
+
=== 0.1.1 / 2008-07-21
|
2
|
+
|
3
|
+
* 1 major enhancement
|
4
|
+
* A complete rewrite! We won't bother attempting to wrap complex lvm
|
5
|
+
operations, but instead provide LVM.raw() command. The wrapper now focuses
|
6
|
+
purely on translating lvm lv/vg/pv data into the most useful ruby objects
|
7
|
+
possible. The arguments passed to the underlying binaries have been broken
|
8
|
+
out into a ruby-lvm-attributes package.
|
2
9
|
|
3
|
-
|
10
|
+
=== 0.0.1 / 2008-05-28
|
4
11
|
|
12
|
+
* 1 major enhancement
|
5
13
|
* Birthday!
|
6
14
|
* Test release.
|
data/Manifest.txt
CHANGED
@@ -5,23 +5,24 @@ Rakefile
|
|
5
5
|
Todo.txt
|
6
6
|
examples/create_snapshot.rb
|
7
7
|
examples/error_handling.rb
|
8
|
-
examples/
|
9
|
-
helpers/generate_field_data.rb
|
8
|
+
examples/show_lvm_config.rb
|
10
9
|
lib/lvm.rb
|
11
|
-
lib/lvm/attrib/lvs.yaml
|
12
|
-
lib/lvm/attrib/pvs.yaml
|
13
|
-
lib/lvm/attrib/vgs.yaml
|
14
10
|
lib/lvm/external.rb
|
15
|
-
lib/lvm/
|
16
|
-
lib/lvm/
|
17
|
-
lib/lvm/
|
18
|
-
lib/lvm/
|
19
|
-
lib/lvm/
|
20
|
-
lib/lvm/
|
21
|
-
lib/lvm/
|
22
|
-
lib/lvm/
|
23
|
-
lib/lvm/
|
24
|
-
lib/lvm/
|
25
|
-
lib/lvm/
|
26
|
-
lib/lvm/
|
11
|
+
lib/lvm/logical_volume.rb
|
12
|
+
lib/lvm/logical_volume_segment.rb
|
13
|
+
lib/lvm/logical_volumes.rb
|
14
|
+
lib/lvm/physical_volume.rb
|
15
|
+
lib/lvm/physical_volume_segment.rb
|
16
|
+
lib/lvm/physical_volumes.rb
|
17
|
+
lib/lvm/userland.rb
|
18
|
+
lib/lvm/volume_group.rb
|
19
|
+
lib/lvm/volume_groups.rb
|
20
|
+
lib/lvm/volumes.rb
|
21
|
+
lib/lvm/wrapper.rb
|
22
|
+
lib/lvm/wrapper/constants.rb
|
23
|
+
lib/lvm/wrapper/lvs.rb
|
24
|
+
lib/lvm/wrapper/lvsseg.rb
|
25
|
+
lib/lvm/wrapper/pvs.rb
|
26
|
+
lib/lvm/wrapper/pvsseg.rb
|
27
|
+
lib/lvm/wrapper/vgs.rb
|
27
28
|
test/test_lvm.rb
|
data/README.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= ruby-lvm
|
2
2
|
|
3
3
|
* http://ruby-lvm.rubyforge.org
|
4
|
-
* mailto:
|
4
|
+
* mailto:mkent@magoazul.com
|
5
5
|
|
6
6
|
== DESCRIPTION:
|
7
7
|
|
@@ -10,29 +10,42 @@ function it to convert physical volumes, logical volumes and volume groups
|
|
10
10
|
into easy to use ruby objects. It also provides a simple wrapper for typical
|
11
11
|
create/delete/etc operations.
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
See this thread
|
17
|
-
http://www.redhat.com/archives/libvir-list/2007-March/msg00192.html for a
|
18
|
-
similar discussion.
|
13
|
+
Due to a lack of LVM2 api this is a best effort attempt at ruby integration but
|
14
|
+
subject to complete replacement in the future.
|
19
15
|
|
20
16
|
== FEATURES/PROBLEMS:
|
21
17
|
|
22
|
-
*
|
18
|
+
* Exposes all possible data from the lvs/vgs/pvs commands. Data is grouped
|
19
|
+
sensibly (I hope).
|
20
|
+
* Doesn't nicely wrap creation/deletion/etc operations, they must be created
|
21
|
+
by hand and passed as raw commands.
|
23
22
|
|
24
23
|
== SYNOPSIS:
|
25
24
|
|
26
|
-
|
25
|
+
require 'lvm'
|
26
|
+
|
27
|
+
LVM::LVM.new({:command => "/usr/bin/sudo /sbin/lvm"}) do |lvm|
|
28
|
+
puts "lvm version: #{lvm.version}\n"
|
29
|
+
|
30
|
+
lvm.volume_groups.each do |vg|
|
31
|
+
puts "vg: #{vg.name}"
|
32
|
+
end
|
33
|
+
end
|
27
34
|
|
28
35
|
== REQUIREMENTS:
|
29
36
|
|
37
|
+
* ruby-lvm-attributes
|
30
38
|
* popen4
|
31
39
|
|
32
40
|
== INSTALL:
|
33
41
|
|
34
42
|
* sudo gem install ruby-lvm
|
35
43
|
|
44
|
+
== FEEDBACK:
|
45
|
+
|
46
|
+
Please feel free to submit patches or constructive criticism, I'm still pretty
|
47
|
+
new to ruby and object oriented programming in general.
|
48
|
+
|
36
49
|
== LICENSE:
|
37
50
|
|
38
51
|
(The MIT License)
|
data/Rakefile
CHANGED
@@ -5,9 +5,10 @@ require 'hoe'
|
|
5
5
|
$:.unshift(File.dirname(__FILE__) + "/lib")
|
6
6
|
require 'lvm'
|
7
7
|
|
8
|
-
Hoe.new('ruby-lvm',
|
9
|
-
p.developer('Matthew Kent', '
|
8
|
+
Hoe.new('ruby-lvm', LVM::VERSION) do |p|
|
9
|
+
p.developer('Matthew Kent', 'mkent@magoazul.com')
|
10
10
|
p.extra_deps << ['open4', '>= 0.9.6']
|
11
|
+
p.extra_deps << ['ruby-lvm-attrib', '>= 0.0.1']
|
11
12
|
p.remote_rdoc_dir = ''
|
12
13
|
end
|
13
14
|
|
data/Todo.txt
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
= to do
|
2
2
|
|
3
|
-
== 0.1
|
4
|
-
*
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
*
|
9
|
-
*
|
10
|
-
* compatibility check and warning, pass flag to shutup
|
3
|
+
== 0.2.1
|
4
|
+
* basic test suite, how?
|
5
|
+
|
6
|
+
== 0.1.2
|
7
|
+
* test on more distributions!
|
8
|
+
* more documentation.
|
9
|
+
* debug mode, logger?
|
data/examples/create_snapshot.rb
CHANGED
@@ -1,16 +1,28 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
+
# Demonstration of the creation of an lvm snapshot, using sudo, and reading its
|
4
|
+
# attributes.
|
5
|
+
|
3
6
|
$: << File.dirname(__FILE__) + "/../lib"
|
4
7
|
|
5
8
|
require 'lvm'
|
6
|
-
require 'lvm/lvmanager'
|
7
|
-
require 'lvm/pvmanager'
|
8
|
-
require 'lvm/vgmanager'
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
vol = "sys.vg/tmp.lv"
|
11
|
+
snap = "demo_snap"
|
12
|
+
|
13
|
+
lvm = LVM::LVM.new(:command => "/usr/bin/sudo /sbin/lvm")
|
14
|
+
|
15
|
+
if lvm.logical_volumes[snap]
|
16
|
+
puts "#{snap} exists! Remove it"
|
17
|
+
exit(1)
|
18
|
+
end
|
12
19
|
|
13
|
-
|
14
|
-
lv
|
20
|
+
lvm.raw("lvcreate --snapshot --size 10M --name #{snap} #{vol}")
|
21
|
+
lv = lvm.logical_volumes[snap]
|
15
22
|
|
16
|
-
|
23
|
+
out=<<msg
|
24
|
+
snapshot of #{vol}, #{snap}, created
|
25
|
+
- uuid: #{lv.uuid}
|
26
|
+
- major,minor: #{lv.kernel_major},#{lv.kernel_minor}
|
27
|
+
msg
|
28
|
+
puts out
|
data/examples/error_handling.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
+
# Demonstration of the exception handling with raw commands.
|
4
|
+
|
3
5
|
$: << File.dirname(__FILE__) + "/../lib"
|
4
6
|
|
5
7
|
require 'lvm'
|
6
8
|
|
7
|
-
lvm =
|
9
|
+
lvm = LVM::LVM.new(:command => "/usr/bin/sudo /sbin/lvm")
|
8
10
|
|
9
|
-
|
11
|
+
begin
|
12
|
+
lvm.raw("--blah blah")
|
13
|
+
rescue LVM::External::ExternalFailure => error
|
14
|
+
puts "Raw operation failed with [#{error}]"
|
15
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# A more advanced demonstration displaying a complete overview of the current
|
4
|
+
# lvm configuration.
|
5
|
+
|
6
|
+
$: << File.dirname(__FILE__) + "/../lib"
|
7
|
+
|
8
|
+
require 'lvm'
|
9
|
+
|
10
|
+
LVM::LVM.new({:command => "/usr/bin/sudo /sbin/lvm"}) do |lvm|
|
11
|
+
puts "lvm version: #{lvm.version}\n"
|
12
|
+
|
13
|
+
puts "\nlogical view"
|
14
|
+
puts "------------"
|
15
|
+
lvm.volume_groups.each do |vg|
|
16
|
+
puts "vg: #{vg.name}"
|
17
|
+
vg.logical_volumes.each do |lv|
|
18
|
+
puts " lv: #{lv.name} #{lv.size}"
|
19
|
+
lv.segments.each do |lvseg|
|
20
|
+
puts " lvseg: #{lvseg.devices} ##{lv.segments.index(lvseg)} #{lvseg.start} - #{lvseg.finish} = #{lvseg.size}"
|
21
|
+
end
|
22
|
+
if lv.snapshot?
|
23
|
+
puts " snapshot origin: #{lv.origin}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
puts "\nphysical view"
|
29
|
+
puts "-------------"
|
30
|
+
lvm.volume_groups.each do |vg|
|
31
|
+
puts "vg: #{vg.name}"
|
32
|
+
vg.physical_volumes.each do |pv|
|
33
|
+
puts " pv: #{pv.name}"
|
34
|
+
pv.segments.each do |pvseg|
|
35
|
+
puts " pvseg: ##{pv.segments.index(pvseg)} #{pvseg.start} - #{pvseg.finish}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/lib/lvm.rb
CHANGED
@@ -1,39 +1,82 @@
|
|
1
1
|
require 'lvm/external'
|
2
|
+
require 'lvm/userland'
|
3
|
+
require 'lvm/logical_volumes'
|
4
|
+
require 'lvm/volume_groups'
|
5
|
+
require 'lvm/physical_volumes'
|
2
6
|
|
3
|
-
module
|
4
|
-
VERSION = '0.
|
5
|
-
COMPAT_VERSION = '2.02.26-RHEL5'
|
7
|
+
module LVM
|
8
|
+
VERSION = '0.1.1'
|
6
9
|
|
7
10
|
class LVM
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
attr_reader :command
|
12
|
+
attr_reader :logical_volumes
|
13
|
+
attr_reader :volume_groups
|
14
|
+
attr_reader :physical_volumes
|
15
|
+
|
16
|
+
VALID_OPTIONS = [
|
17
|
+
:command,
|
18
|
+
:version,
|
19
|
+
:debug
|
20
|
+
]
|
11
21
|
|
12
22
|
DEFAULT_COMMAND = '/sbin/lvm'
|
13
23
|
|
14
|
-
def initialize(
|
15
|
-
|
16
|
-
|
24
|
+
def initialize(options={})
|
25
|
+
# handy, thanks net-ssh!
|
26
|
+
invalid_options = options.keys - VALID_OPTIONS
|
27
|
+
if invalid_options.any?
|
28
|
+
raise ArgumentError, "invalid option(s): #{invalid_options.join(', ')}"
|
29
|
+
end
|
30
|
+
|
31
|
+
@command = options[:command] || DEFAULT_COMMAND
|
32
|
+
|
33
|
+
# default to loading attributes for the current version
|
34
|
+
options[:version] ||= version
|
35
|
+
options[:debug] ||= false
|
36
|
+
|
37
|
+
@logical_volumes = LogicalVolumes.new(options)
|
38
|
+
@volume_groups = VolumeGroups.new(options)
|
39
|
+
@physical_volumes = PhysicalVolumes.new(options)
|
40
|
+
|
41
|
+
if block_given?
|
42
|
+
yield self
|
43
|
+
else
|
44
|
+
return self
|
45
|
+
end
|
17
46
|
end
|
18
47
|
|
19
|
-
def raw(args)
|
20
|
-
|
48
|
+
def raw(args)
|
49
|
+
output = []
|
50
|
+
External.cmd("#{@command} #{args}") do |line|
|
51
|
+
output << line
|
52
|
+
end
|
53
|
+
if block_given?
|
54
|
+
return output.each { |l| yield l }
|
55
|
+
else
|
56
|
+
return output.join
|
57
|
+
end
|
21
58
|
end
|
22
59
|
|
23
|
-
def
|
24
|
-
|
25
|
-
puts "Going to execute `#{to_exec}`" if @debug
|
26
|
-
raw(to_exec)
|
60
|
+
def version
|
61
|
+
%r{^(.*?)(-| )}.match(userland.lvm_version)[1]
|
27
62
|
end
|
28
63
|
|
29
|
-
|
30
|
-
|
31
|
-
|
64
|
+
# helper methods
|
65
|
+
def userland
|
66
|
+
userland = UserLand.new
|
67
|
+
raw('version') do |line|
|
68
|
+
case line
|
69
|
+
when %r{^\s+LVM version:\s+([0-9].*)$}
|
70
|
+
userland.lvm_version = $1
|
71
|
+
when %r{^\s+Library version:\s+([0-9].*)$}
|
72
|
+
userland.library_version = $1
|
73
|
+
when %r{^\s+Driver version:\s+([0-9].*)$}
|
74
|
+
userland.driver_version = $1
|
75
|
+
end
|
32
76
|
end
|
33
|
-
def cmd(args)
|
34
|
-
new(args).raw(args)
|
35
|
-
end
|
36
|
-
end # self
|
37
77
|
|
38
|
-
|
39
|
-
end
|
78
|
+
return userland
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
data/lib/lvm/external.rb
CHANGED
@@ -1,41 +1,36 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'open4'
|
3
3
|
|
4
|
-
module
|
5
|
-
|
4
|
+
module LVM
|
5
|
+
module External
|
6
6
|
class ExternalFailure < RuntimeError; end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
output = []
|
15
|
-
error = nil
|
16
|
-
stat = Open4::popen4(cmd) do |pid, stdin, stdout, stderr|
|
17
|
-
while line = stdout.gets
|
18
|
-
output << line
|
19
|
-
end
|
20
|
-
error = stderr.read.strip
|
8
|
+
def cmd(cmd)
|
9
|
+
output = []
|
10
|
+
error = nil
|
11
|
+
stat = Open4.popen4(cmd) do |pid, stdin, stdout, stderr|
|
12
|
+
while line = stdout.gets
|
13
|
+
output << line
|
21
14
|
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
raise ExternalFailure, "Fatal error, `#{cmd}` got signal #{stat.termsig} and terminated"
|
28
|
-
elsif stat.stopped?
|
29
|
-
raise ExternalFailure, "Fatal error, `#{cmd}` got signal #{stat.stopsig} and is stopped"
|
15
|
+
error = stderr.read.strip
|
16
|
+
end
|
17
|
+
if stat.exited?
|
18
|
+
if stat.exitstatus > 0
|
19
|
+
raise ExternalFailure, "Fatal error, `#{cmd}` returned #{stat.exitstatus} with '#{error}'"
|
30
20
|
end
|
21
|
+
elsif stat.signaled?
|
22
|
+
raise ExternalFailure, "Fatal error, `#{cmd}` got signal #{stat.termsig} and terminated"
|
23
|
+
elsif stat.stopped?
|
24
|
+
raise ExternalFailure, "Fatal error, `#{cmd}` got signal #{stat.stopsig} and is stopped"
|
25
|
+
end
|
31
26
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
27
|
+
if block_given?
|
28
|
+
return output.each { |l| yield l }
|
29
|
+
else
|
30
|
+
return output.join
|
37
31
|
end
|
38
32
|
end
|
33
|
+
module_function :cmd
|
39
34
|
|
40
|
-
end #
|
41
|
-
end # module
|
35
|
+
end # module External
|
36
|
+
end # module LVM
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'lvm/volumes'
|
2
|
+
require 'lvm/wrapper/lvs'
|
3
|
+
require 'lvm/wrapper/lvsseg'
|
4
|
+
|
5
|
+
module LVM
|
6
|
+
class LogicalVolumes
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
include Volumes
|
10
|
+
include Wrapper
|
11
|
+
|
12
|
+
def initialize(options)
|
13
|
+
@lvs = LVS.new(options)
|
14
|
+
@lvsseg = LVSSEG.new(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Gather all information about logical volumes.
|
18
|
+
#
|
19
|
+
# See VolumeGroups.each for a better representation of LVM data.
|
20
|
+
def each
|
21
|
+
lvs = @lvs.list
|
22
|
+
lvsseg = @lvsseg.list
|
23
|
+
|
24
|
+
lvs.each do |lv|
|
25
|
+
lv.segments ||= []
|
26
|
+
lvsseg.each do |lvseg|
|
27
|
+
if lvseg.lv_uuid == lv.uuid
|
28
|
+
lv.segments << lvseg
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
return lvs.each {|l| yield l}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|