Added resizing based on %values. Included support for VG|PVS|FREE
This commit is contained in:
parent
2095aa5100
commit
2149a7b1f6
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
|
- The size of the logical volume, according to lvcreate(8) --size, by
|
||||||
default in megabytes or optionally with one of [bBsSkKmMgGtTpPeE] units; or
|
default in megabytes or optionally with one of [bBsSkKmMgGtTpPeE] units; or
|
||||||
according to lvcreate(8) --extents as a percentage of [VG|PVS|FREE];
|
according to lvcreate(8) --extents as a percentage of [VG|PVS|FREE];
|
||||||
resizing is not supported with percentages. Float values must begin
|
Float values must begin with a digit.
|
||||||
with a digit.
|
Resizing using percentage values was not supported prior to 2.1.
|
||||||
state:
|
state:
|
||||||
choices: [ "present", "absent" ]
|
choices: [ "present", "absent" ]
|
||||||
default: present
|
default: present
|
||||||
|
@ -88,6 +88,15 @@ EXAMPLES = '''
|
||||||
# Extend the logical volume to 1024m.
|
# Extend the logical volume to 1024m.
|
||||||
- lvol: vg=firefly lv=test size=1024
|
- 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
|
# Reduce the logical volume to 512m
|
||||||
- lvol: vg=firefly lv=test size=512 force=yes
|
- lvol: vg=firefly lv=test size=512 force=yes
|
||||||
|
|
||||||
|
@ -99,23 +108,35 @@ EXAMPLES = '''
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import logging
|
||||||
|
|
||||||
decimal_point = re.compile(r"(\.|,)")
|
decimal_point = re.compile(r"(\d+)")
|
||||||
|
|
||||||
def mkversion(major, minor, patch):
|
def mkversion(major, minor, patch):
|
||||||
return (1000 * 1000 * int(major)) + (1000 * int(minor)) + int(patch)
|
return (1000 * 1000 * int(major)) + (1000 * int(minor)) + int(patch)
|
||||||
|
|
||||||
|
|
||||||
def parse_lvs(data):
|
def parse_lvs(data):
|
||||||
lvs = []
|
lvs = []
|
||||||
for line in data.splitlines():
|
for line in data.splitlines():
|
||||||
parts = line.strip().split(';')
|
parts = line.strip().split(';')
|
||||||
lvs.append({
|
lvs.append({
|
||||||
'name': parts[0],
|
'name': parts[0],
|
||||||
'size': int(decimal_point.split(parts[1])[0]),
|
'size': int(decimal_point.match(parts[1]).group(1))
|
||||||
})
|
})
|
||||||
return lvs
|
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):
|
def get_lvm_version(module):
|
||||||
ver_cmd = module.get_bin_path("lvm", required=True)
|
ver_cmd = module.get_bin_path("lvm", required=True)
|
||||||
|
@ -198,6 +219,21 @@ def main():
|
||||||
else:
|
else:
|
||||||
unit = size_unit
|
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)
|
lvs_cmd = module.get_bin_path("lvs", required=True)
|
||||||
rc, current_lvs, err = module.run_command(
|
rc, current_lvs, err = module.run_command(
|
||||||
"lvs --noheadings --nosuffix -o lv_name,size --units %s --separator ';' %s" % (unit, vg))
|
"lvs --noheadings --nosuffix -o lv_name,size --units %s --separator ';' %s" % (unit, vg))
|
||||||
|
@ -261,17 +297,58 @@ def main():
|
||||||
module.fail_json(msg="Failed to remove logical volume %s" % (lv), rc=rc, err=err)
|
module.fail_json(msg="Failed to remove logical volume %s" % (lv), rc=rc, err=err)
|
||||||
|
|
||||||
elif size_opt == 'l':
|
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:
|
else:
|
||||||
### resize LV
|
### resize LV based on absolute values
|
||||||
tool = None
|
tool = None
|
||||||
if int(size) > this_lv['size']:
|
if int(size) > this_lv['size']:
|
||||||
tool = module.get_bin_path("lvextend", required=True)
|
tool = module.get_bin_path("lvextend", required=True)
|
||||||
elif int(size) < this_lv['size']:
|
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:
|
if not force:
|
||||||
module.fail_json(msg="Sorry, no shrinking of %s without force=yes." % (this_lv['name']))
|
module.fail_json(msg="Sorry, no shrinking of %s without force=yes." % (this_lv['name']))
|
||||||
tool = module.get_bin_path("lvreduce", required=True)
|
else:
|
||||||
tool = '%s %s' % (tool, '--force')
|
tool = module.get_bin_path("lvreduce", required=True)
|
||||||
|
tool = '%s %s' % (tool, '--force')
|
||||||
|
|
||||||
if tool:
|
if tool:
|
||||||
if module.check_mode:
|
if module.check_mode:
|
||||||
|
|
Loading…
Reference in a new issue