Added resizing based on %values. Included support for VG|PVS|FREE
This commit is contained in:
parent
fff5ae6994
commit
b5d75234a3
1 changed files with 86 additions and 9 deletions
|
@ -42,8 +42,8 @@ options:
|
|||
- The size of the logical volume, according to lvcreate(8) --size, by
|
||||
default in megabytes or optionally with one of [bBsSkKmMgGtTpPeE] units; or
|
||||
according to lvcreate(8) --extents as a percentage of [VG|PVS|FREE];
|
||||
resizing is not supported with percentages. Float values must begin
|
||||
with a digit.
|
||||
Float values must begin with a digit.
|
||||
Resizing using percentage values was not supported prior to 2.1.
|
||||
state:
|
||||
choices: [ "present", "absent" ]
|
||||
default: present
|
||||
|
@ -87,6 +87,15 @@ EXAMPLES = '''
|
|||
# Extend the logical volume to 1024m.
|
||||
- lvol: vg=firefly lv=test size=1024
|
||||
|
||||
# Extend the logical volume to consume all remaining space in the volume group
|
||||
- lvol: vg=firefly lv=test size=+100%FREE
|
||||
|
||||
# Extend the logical volume to take all remaining space of the PVs
|
||||
- lvol: vg=firefly lv=test size=100%PVS
|
||||
|
||||
# Resize the logical volume to % of VG
|
||||
- lvol: vg-firefly lv=test size=80%VG force=yes
|
||||
|
||||
# Reduce the logical volume to 512m
|
||||
- lvol: vg=firefly lv=test size=512 force=yes
|
||||
|
||||
|
@ -98,23 +107,35 @@ EXAMPLES = '''
|
|||
'''
|
||||
|
||||
import re
|
||||
import logging
|
||||
|
||||
decimal_point = re.compile(r"(\.|,)")
|
||||
decimal_point = re.compile(r"(\d+)")
|
||||
|
||||
def mkversion(major, minor, patch):
|
||||
return (1000 * 1000 * int(major)) + (1000 * int(minor)) + int(patch)
|
||||
|
||||
|
||||
def parse_lvs(data):
|
||||
lvs = []
|
||||
for line in data.splitlines():
|
||||
parts = line.strip().split(';')
|
||||
lvs.append({
|
||||
'name': parts[0],
|
||||
'size': int(decimal_point.split(parts[1])[0]),
|
||||
'size': int(decimal_point.match(parts[1]).group(1))
|
||||
})
|
||||
return lvs
|
||||
|
||||
def parse_vgs(data):
|
||||
vgs = []
|
||||
for line in data.splitlines():
|
||||
parts = line.strip().split(';')
|
||||
vgs.append({
|
||||
'name': parts[0],
|
||||
'size': int(decimal_point.match(parts[1]).group(1)),
|
||||
'free': int(decimal_point.match(parts[2]).group(1)),
|
||||
'ext_size': int(decimal_point.match(parts[3]).group(1))
|
||||
})
|
||||
return vgs
|
||||
|
||||
|
||||
def get_lvm_version(module):
|
||||
ver_cmd = module.get_bin_path("lvm", required=True)
|
||||
|
@ -197,6 +218,21 @@ def main():
|
|||
else:
|
||||
unit = size_unit
|
||||
|
||||
# Get information on volume group requested
|
||||
vgs_cmd = module.get_bin_path("vgs", required=True)
|
||||
rc, current_vgs, err = module.run_command(
|
||||
"%s --noheadings -o vg_name,size,free,vg_extent_size --units %s --separator ';' %s" % (vgs_cmd, unit, vg))
|
||||
|
||||
if rc != 0:
|
||||
if state == 'absent':
|
||||
module.exit_json(changed=False, stdout="Volume group %s does not exist." % vg, stderr=False)
|
||||
else:
|
||||
module.fail_json(msg="Volume group %s does not exist." % vg, rc=rc, err=err)
|
||||
|
||||
vgs = parse_vgs(current_vgs)
|
||||
this_vg = vgs[0]
|
||||
|
||||
# Get information on logical volume requested
|
||||
lvs_cmd = module.get_bin_path("lvs", required=True)
|
||||
rc, current_lvs, err = module.run_command(
|
||||
"%s --noheadings --nosuffix -o lv_name,size --units %s --separator ';' %s" % (lvs_cmd, unit, vg))
|
||||
|
@ -260,17 +296,58 @@ def main():
|
|||
module.fail_json(msg="Failed to remove logical volume %s" % (lv), rc=rc, err=err)
|
||||
|
||||
elif size_opt == 'l':
|
||||
module.exit_json(changed=False, msg="Resizing extents with percentage not supported.")
|
||||
### Resize LV based on % value
|
||||
tool = None
|
||||
size_free = this_vg['free']
|
||||
if size_whole == 'VG' or size_whole == 'PVS':
|
||||
size_requested = size_percent * this_vg['size'] / 100
|
||||
else: # size_whole == 'FREE':
|
||||
size_requested = size_percent * this_vg['free'] / 100
|
||||
if '+' in size:
|
||||
size_requested += this_lv['size']
|
||||
if this_lv['size'] < size_requested:
|
||||
if (size_free > 0) and (('+' not in size) or (size_free >= (size_requested - this_lv['size']))):
|
||||
tool = module.get_bin_path("lvextend", required=True)
|
||||
else:
|
||||
module.fail_json(msg="Logical Volume %s could not be extended. Not enough free space left (%s%s required / %s%s available)" % (this_lv['name'], (size_requested - this_lv['size']), unit, size_free, unit))
|
||||
elif this_lv['size'] > size_requested + this_vg['ext_size']: # more than an extent too large
|
||||
if size_requested == 0:
|
||||
module.fail_json(msg="Sorry, no shrinking of %s to 0 permitted." % (this_lv['name']))
|
||||
elif not force:
|
||||
module.fail_json(msg="Sorry, no shrinking of %s without force=yes" % (this_lv['name']))
|
||||
else:
|
||||
tool = module.get_bin_path("lvreduce", required=True)
|
||||
tool = '%s %s' % (tool, '--force')
|
||||
|
||||
if tool:
|
||||
if module.check_mode:
|
||||
changed = True
|
||||
else:
|
||||
cmd = "%s -%s %s%s %s/%s" % (tool, size_opt, size, size_unit, vg, this_lv['name'])
|
||||
rc, out, err = module.run_command(cmd)
|
||||
if "Reached maximum COW size" in out:
|
||||
module.fail_json(msg="Unable to resize %s to %s%s" % (lv, size, size_unit), rc=rc, err=err, out=out)
|
||||
elif rc == 0:
|
||||
changed = True
|
||||
msg="Volume %s resized to %s%s" % (this_lv['name'], size_requested, unit)
|
||||
elif "matches existing size" in err:
|
||||
module.exit_json(changed=False, vg=vg, lv=this_lv['name'], size=this_lv['size'])
|
||||
else:
|
||||
module.fail_json(msg="Unable to resize %s to %s%s" % (lv, size, size_unit), rc=rc, err=err)
|
||||
|
||||
else:
|
||||
### resize LV
|
||||
### resize LV based on absolute values
|
||||
tool = None
|
||||
if int(size) > this_lv['size']:
|
||||
tool = module.get_bin_path("lvextend", required=True)
|
||||
elif int(size) < this_lv['size']:
|
||||
if int(size) == 0:
|
||||
module.fail_json(msg="Sorry, no shrinking of %s to 0 permitted." % (this_lv['name']))
|
||||
if not force:
|
||||
module.fail_json(msg="Sorry, no shrinking of %s without force=yes." % (this_lv['name']))
|
||||
tool = module.get_bin_path("lvreduce", required=True)
|
||||
tool = '%s %s' % (tool, '--force')
|
||||
else:
|
||||
tool = module.get_bin_path("lvreduce", required=True)
|
||||
tool = '%s %s' % (tool, '--force')
|
||||
|
||||
if tool:
|
||||
if module.check_mode:
|
||||
|
|
Loading…
Reference in a new issue