Hi list,
i wrote a simple type and provider to manage logical volumes with
puppet. This is my first attempt and it may not match the puppet
styles and best practices. I'm hoping for your improvement
suggestions.
Type:
=====
Puppet::Type.newtype(:logicalvolume) do
@doc = "Manage logical volumes"
ensurable
newparam(:lvname) do
desc "The logcal volumes name"
validate do |value|
unless value =~ /^[a-z0-9]+/
raise ArgumentError , "%s is not a valid lv name" %
value
end
end
isnamevar
end
newproperty(:size) do
desc "The size in M or G"
validate do |value|
unless value =~ /^[0-9]+[MGTPE]/
raise ArgumentError , "%s is not a valid lv size" %
value
end
end
end
newparam(:vg) do
desc "The volumevg to create the volume in"
validate do |value|
unless value =~ /^[a-z0-9]+/
raise ArgumentError , "%s is not a valid lv name" %
value
end
end
end
end
Provider:
========
Puppet::Type.type(:logicalvolume).provide(:logicalvolume) do
include Puppet::Util
def size
lvm_size_units = { "M" => 1024, "G" => 1048576, "T" =>
1073741824, "P" => 1099511627776, "E" => 1125899906842624 }
lvm_size_units_match = lvm_size_units.keys().join('|')
output = Puppet::Util.execute(["lvs", "--noheading", "/dev/
#{resource[:vg]}/#{resource[:name]}", "-o", "size"])
if output =~ /^\s+(\d+)\.\d+
(#{lvm_size_units_match.downcase})/
size = $1 + $2.capitalize
debug("Size of /dev/#{resource[:vg]}/#{resource[:name]} is
#{size}")
return size
else
fail("Failed to parse current volume size!")
end
end
def size=(size)
lvm_size_units = { "M" => 1024, "G" => 1048576, "T" =>
1073741824, "P" => 1099511627776, "E" => 1125899906842624 }
lvm_size_units_match = lvm_size_units.keys().join('|')
resizeable = false
c_size = self.size()
if size =~ /(\d+)(#{lvm_size_units_match})/
n_size_bytes = $1.to_i
n_size_unit = $2
end
if c_size =~ /(\d+)(#{lvm_size_units_match})/
c_size_bytes = $1.to_i
c_size_unit = $2
end
## Check if given requested size matches extend size of VG
output = Puppet::Util.execute(["vgdisplay", "-c",
resource[:vg]])
vg_extend = output.split(':')[12].to_i
if n_size_bytes * lvm_size_units[n_size_unit] % vg_extend != 0
fail("Cannot extend to size #{size} because VG extend is
#{vg_extend}KB")
end
## Veritfy that it's a extend: Only extends are allowed
if lvm_size_units[c_size_unit] < lvm_size_units[n_size_unit]
resizeable = true
elsif lvm_size_units[c_size_unit] ==
lvm_size_units[n_size_unit]
if n_size_bytes > c_size_bytes
resizeable = true
end
end
if not resizeable
fail("Cannot change size of /dev/#{resource[:vg]}/
#{resource[:name]} as #{size} < #{c_size}")
else
output = Puppet::Util.execute(["lvextend", "-L", size, "/
dev/#{resource[:vg]}/#{resource[:name]}"])
debug(output)
return true
end
end
def create
output = Puppet::Util.execute(["lvcreate", "-L",
resource[:size], "-n", resource[:name], resource[:vg]])
debug(output)
return true
end
def destroy
output = Puppet::Util.execute(["lvchange", "-an", "/dev/
#{resource[:vg]}/#{resource[:name]}"])
output = Puppet::Util.execute(["lvremove", "-f", "/dev/
#{resource[:vg]}/#{resource[:name]}"])
debug(output)
return true
end
def exists?
output = Puppet::Util.execute(["lvs", "--noheading", "/dev/
#{resource[:vg]}/#{resource[:name]}"], :failonfail => false, :combine
=> true)
debug(output)
if output.include?("One or more specified logical volume(s)
not found.")
return nil
else
return true
end
end
end
Thanks,
Daniel
--
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en.