From 01a9d79e11ad3146b8c74cd52a443dab46a1de99 Mon Sep 17 00:00:00 2001 From: Jeroen Hoekx Date: Wed, 27 Feb 2013 11:24:56 +0100 Subject: [PATCH] Add lvol module to manage logical volumes. --- library/lvol | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100755 library/lvol diff --git a/library/lvol b/library/lvol new file mode 100755 index 00000000000..afa1decff7d --- /dev/null +++ b/library/lvol @@ -0,0 +1,151 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2013, Jeroen Hoekx +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +DOCUMENTATION = ''' +--- +author: Jeroen Hoekx +module: lvol +short_description: Configure LVM logical volumes +description: + - This module creates, removes or resizes logical volumes. +version_added: "1.1" +options: + vg: + description: + - The volume group this logical volume is part of. + required: true + lv: + description: + - The name of the logical volume. + required: true + size: + description: + - The size of the logical volume in megabytes. + state: + choices: [ "present", "absent" ] + default: present + description: + - Control if the logical volume exists. + required: false +examples: + - description: Create a logical volume of 512m. + code: lvol vg=firefly lv=test size=512 + - description: Extend the logical volume to 1024m. + code: lvol vg=firefly lv=test size=1024 + - description: Reduce the logical volume to 512m + code: lvol vg=firefly lv=test size=512 + - description: Remove the logical volume. + code: lvol vg=firefly lv=test state=absent +notes: + - Filesystems on top of the volume are not resized. +''' + +def parse_lvs(data): + lvs = [] + for line in data.splitlines(): + parts = line.strip().split(';') + lvs.append({ + 'name': parts[0], + 'size': int(parts[1].split('.')[0]), + 'path': parts[2], + }) + return lvs + +def main(): + module = AnsibleModule( + argument_spec = dict( + vg=dict(required=True), + lv=dict(required=True), + size=dict(), + state=dict(choices=["absent", "present"], default='present'), + ), + supports_check_mode=True, + ) + + vg = module.params['vg'] + lv = module.params['lv'] + size = module.params['size'] + state = module.params['state'] + + if state=='present' and not size: + module.fail_json(msg="No size given.") + + if size: + size = int(size) + + rc,current_lvs,err = module.run_command("lvs --noheadings -o lv_name,size,lv_path --units m --separator ';' %s"%(vg)) + + if rc != 0: + module.fail_json(msg="Volume group %s does not exist."%vg, rc=rc, err=err) + + changed = False + + lvs = parse_lvs(current_lvs) + + for test_lv in lvs: + if test_lv['name'] == lv: + this_lv = test_lv + break + else: + this_lv = None + + if this_lv is None: + if state == 'present': + ### create LV + if module.check_mode: + changed = True + else: + rc,_,err = module.run_command("lvcreate -n %s -L %sm %s"%(lv, size, vg)) + if rc == 0: + changed = True + else: + module.fail_json(msg="Creating logical volume '%s' failed"%(lv), rc=rc, err=err) + else: + if state == 'absent': + ### remove LV + if module.check_mode: + module.exit_json(changed=True) + rc,_,err = module.run_command("lvremove --force %s"%(this_lv['path'])) + if rc == 0: + module.exit_json(changed=True) + else: + module.fail_json(msg="Failed to remove logical volume %s"%(lv),rc=rc, err=err) + ### resize LV + tool = None + if size > this_lv['size']: + tool = 'lvextend' + elif size < this_lv['size']: + tool = 'lvreduce --force' + + if tool: + if module.check_mode: + changed = True + else: + rc,_,err = module.run_command("%s -L %sm %s"%(tool, size, this_lv['path'])) + if rc == 0: + changed = True + else: + module.fail_json(msg="Unable to resize %s to %sm."%(lv,size),rc=rc,err=err) + + module.exit_json(changed=changed) + +# this is magic, see lib/ansible/module_common.py +#<> +main()