Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for resizeing with extents #194

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 98 additions & 13 deletions lib/puppet/provider/logical_volume/lvm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
:blkid => 'blkid',
:dmsetup => 'dmsetup',
:lvconvert => 'lvconvert',
:lvdisplay => 'lvdisplay'
:lvdisplay => 'lvdisplay',
:vgs => 'vgs',
:pvs => 'pvs'

optional_commands :xfs_growfs => 'xfs_growfs',
:resize4fs => 'resize4fs'
Expand Down Expand Up @@ -137,6 +139,85 @@ def exists?
lvs(@resource[:volume_group]) =~ lvs_pattern
end

def extents
lvm_size_units = { "K" => 1, "M" => 1024, "G" => 1024**2, "T" => 1024**3, "P" => 1024**4, "E" => 1024**5 }

if @resource[:extents] =~ /^(\d+)((%)?(vg))?$/i
extents_size = $1.to_f
extents_full_type = $2.downcase unless $2.nil?
end

raw_vgs = vgs('--noheading', '-o','name,vg_extent_count,seg_size,vg_extent_size', path)

# Calculate the total extents of the Volume Group and the total used extents of the Logical Volume.
vgs_size = Hash.new
total_vgs_extents = 0
raw_vgs.split("\n").each do |lvs|

if lvs =~ /\s+(\w+)\s+(\d+)\s+(\d+(\.\d+)?)([KMGTPE])\s+(\d+(\.\d+)?)([KMGTPE])/i
vg_name = $1
vg_extents_count = $2.to_i

lv_size = $3.to_f
lv_unit = $5.upcase

ex_size = $6.to_f
ex_unit = $8.upcase

# Number of extents in use by LV
lv_extents_count = (lv_size / ex_size) * (lvm_size_units[lv_unit] / lvm_size_units[ex_unit])

end
total_vgs_extents += vg_extents_count unless vgs_size.keys.include?(vg_name)
vgs_size[vg_name] ||= 0
vgs_size[vg_name] += lv_extents_count
end

total_used_lvs_extents = vgs_size.values.inject(:+)
# End calculation

if !extents_full_type.nil? and extents_full_type.eql? '%vg'
current_perc = ((total_used_lvs_extents / total_vgs_extents) * 100).round(0).to_s
current_value = current_perc + extents_full_type

return current_value
end

return total_used_lvs_extents.to_s
end

def extents=(new_extents)

current_extents = extents()

if current_extents =~ /^(\d+(\.\d+)?)(%vg)?$/i
current_extents_value = $1.to_f
current_extents_type = $3.upcase unless $3.nil?
end

if new_extents =~ /^(\d+(%vg)?)?$/i
new_extents_value = $1.to_i
new_extents_type = $2.upcase unless $2.nil?

new_extent_size = new_extents_value.to_s
new_extent_size += new_extents_type unless new_extents_type.nil?
end

# If types does not match, do not resize
unless current_extents_type.eql? new_extents_type
fail("Cannot resize with different types (current: #{current_extents_type} vs new: #{new_extents_type}")
end

# Reduce in size is not possible
if new_extents_value.to_f < current_extents_value
fail("Decreasing the size requires manual intervention (#{new_extents_value} < #{current_extents_value})")
end

lvextend('--extents', new_extent_size, path)

resizefs(path, new_extent_size)
end

def size
if @resource[:size] =~ /^\d+\.?\d{0,2}([KMGTPE])/i
unit = $1.downcase
Expand Down Expand Up @@ -201,18 +282,7 @@ def size=(new_size)

lvextend( '-L', new_size, path) || fail( "Cannot extend to size #{new_size} because lvextend failed." )

unless @resource[:resize_fs] == :false or @resource[:resize_fs] == false or @resource[:resize_fs] == 'false'
blkid_type = blkid(path)
if command(:resize4fs) and blkid_type =~ /\bTYPE=\"(ext4)\"/
resize4fs( path) || fail( "Cannot resize file system to size #{new_size} because resize2fs failed." )
elsif blkid_type =~ /\bTYPE=\"(ext[34])\"/
resize2fs( path) || fail( "Cannot resize file system to size #{new_size} because resize2fs failed." )
elsif blkid_type =~ /\bTYPE=\"(xfs)\"/
xfs_growfs( path) || fail( "Cannot resize filesystem to size #{new_size} because xfs_growfs failed." )
elsif blkid_type =~ /\bTYPE=\"(swap)\"/
swapoff( path) && mkswap( path) && swapon( path) || fail( "Cannot resize swap to size #{new_size} because mkswap failed." )
end
end
resizefs(path, new_size)

end
end
Expand Down Expand Up @@ -305,4 +375,19 @@ def vgpath
"/dev/#{@resource[:volume_group]}"
end

def resizefs(path, new_size)
unless @resource[:resize_fs] == :false or @resource[:resize_fs] == false or @resource[:resize_fs] == 'false'
blkid_type = blkid(path)
if command(:resize4fs) and blkid_type =~ /\bTYPE=\"(ext4)\"/
resize4fs( path) || fail( "Cannot resize file system to size #{new_size} because resize2fs failed." )
elsif blkid_type =~ /\bTYPE=\"(ext[34])\"/
resize2fs( path) || fail( "Cannot resize file system to size #{new_size} because resize2fs failed." )
elsif blkid_type =~ /\bTYPE=\"(xfs)\"/
xfs_growfs( path) || fail( "Cannot resize filesystem to size #{new_size} because xfs_growfs failed." )
elsif blkid_type =~ /\bTYPE=\"(swap)\"/
swapoff( path) && mkswap( path) && swapon( path) || fail( "Cannot resize swap to size #{new_size} because mkswap failed." )
end
end
end

end
38 changes: 36 additions & 2 deletions lib/puppet/type/logical_volume.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,47 @@ def insync?(is)
end
end

newparam(:extents) do
desc "The number of logical extents to allocate for the new logical volume. Set to undef to use all available space"
newparam(:resize_extents) do
desc "Do resize when setting extents"
validate do |value|
unless [:true, true, "true", :false, false, "false"].include?(value)
raise ArgumentError , "resize_extents must be either be true or false"
end
end
defaultto false
end

newproperty(:extents) do
desc "The number of logical extents to allocate for the logical volume."
validate do |value|
unless value =~ /^\d+(%(?:vg|pvs|free|origin)?)?$/i
raise ArgumentError , "#{value} is not a valid logical volume extent"
end
end
def insync?(is)
unless [:true, true, "true"].include?(@resource[:resize_extents])
return true
end

if is =~ /^(\d+(\.\d+)?)(%)?(vg)?$/i
current_value = $1.to_f
current_percent = !$3.nil?
current_type = $4.downcase unless $4.nil?
end

if should =~ /^(\d+)(%)?(vg|pvs|free|origin)?$/i
new_value = $1.to_f
new_percent = !$2.nil?
new_type = $3.downcase unless $3.nil?
if not new_type.nil? and ['origin', 'pvs', 'free'].include?(new_type)
warn("Warning: #{new_type} is not supported as extents resize, currently set to #{should} and resize_extents set to #{@resource[:resize_extents]}")
return true
end
end

new_value <= current_value

end
end

newparam(:persistent) do
Expand Down
4 changes: 3 additions & 1 deletion manifests/logical_volume.pp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
$no_sync = undef,
$region_size = undef,
$alloc = undef,
$resize_extents = undef,
) {

validate_bool($mountpath_require)
Expand Down Expand Up @@ -95,7 +96,8 @@
mirrorlog => $mirrorlog,
no_sync => $no_sync,
region_size => $region_size,
alloc => $alloc
alloc => $alloc,
resize_extents => $resize_extents,
}

if $createfs {
Expand Down