%PDF- %PDF-
Direktori : /proc/thread-self/root/lib/python2.7/site-packages/salt/modules/ |
Current File : //proc/thread-self/root/lib/python2.7/site-packages/salt/modules/linux_lvm.py |
# -*- coding: utf-8 -*- ''' Support for Linux LVM2 ''' from __future__ import absolute_import, print_function, unicode_literals # Import python libs import logging import os.path # Import salt libs import salt.utils.path from salt.ext import six from salt.exceptions import CommandExecutionError # Set up logger log = logging.getLogger(__name__) # Define the module's virtual name __virtualname__ = 'lvm' def __virtual__(): ''' Only load the module if lvm is installed ''' if salt.utils.path.which('lvm'): return __virtualname__ return (False, 'The linux_lvm execution module cannot be loaded: the lvm binary is not in the path.') def version(): ''' Return LVM version from lvm version CLI Example: .. code-block:: bash salt '*' lvm.version ''' cmd = 'lvm version' out = __salt__['cmd.run'](cmd).splitlines() ret = out[0].split(': ') return ret[1].strip() def fullversion(): ''' Return all version info from lvm version CLI Example: .. code-block:: bash salt '*' lvm.fullversion ''' ret = {} cmd = 'lvm version' out = __salt__['cmd.run'](cmd).splitlines() for line in out: comps = line.split(':') ret[comps[0].strip()] = comps[1].strip() return ret def pvdisplay(pvname='', real=False): ''' Return information about the physical volume(s) pvname physical device name real dereference any symlinks and report the real device .. versionadded:: 2015.8.7 CLI Examples: .. code-block:: bash salt '*' lvm.pvdisplay salt '*' lvm.pvdisplay /dev/md0 ''' ret = {} cmd = ['pvdisplay', '-c'] if pvname: cmd.append(pvname) cmd_ret = __salt__['cmd.run_all'](cmd, python_shell=False) if cmd_ret['retcode'] != 0: return {} out = cmd_ret['stdout'].splitlines() for line in out: if 'is a new physical volume' not in line: comps = line.strip().split(':') if real: device = os.path.realpath(comps[0]) else: device = comps[0] ret[device] = { 'Physical Volume Device': comps[0], 'Volume Group Name': comps[1], 'Physical Volume Size (kB)': comps[2], 'Internal Physical Volume Number': comps[3], 'Physical Volume Status': comps[4], 'Physical Volume (not) Allocatable': comps[5], 'Current Logical Volumes Here': comps[6], 'Physical Extent Size (kB)': comps[7], 'Total Physical Extents': comps[8], 'Free Physical Extents': comps[9], 'Allocated Physical Extents': comps[10], } if real: ret[device]['Real Physical Volume Device'] = device return ret def vgdisplay(vgname=''): ''' Return information about the volume group(s) CLI Examples: .. code-block:: bash salt '*' lvm.vgdisplay salt '*' lvm.vgdisplay nova-volumes ''' ret = {} cmd = ['vgdisplay', '-c'] if vgname: cmd.append(vgname) cmd_ret = __salt__['cmd.run_all'](cmd, python_shell=False) if cmd_ret['retcode'] != 0: return {} out = cmd_ret['stdout'].splitlines() for line in out: comps = line.strip().split(':') ret[comps[0]] = { 'Volume Group Name': comps[0], 'Volume Group Access': comps[1], 'Volume Group Status': comps[2], 'Internal Volume Group Number': comps[3], 'Maximum Logical Volumes': comps[4], 'Current Logical Volumes': comps[5], 'Open Logical Volumes': comps[6], 'Maximum Logical Volume Size': comps[7], 'Maximum Physical Volumes': comps[8], 'Current Physical Volumes': comps[9], 'Actual Physical Volumes': comps[10], 'Volume Group Size (kB)': comps[11], 'Physical Extent Size (kB)': comps[12], 'Total Physical Extents': comps[13], 'Allocated Physical Extents': comps[14], 'Free Physical Extents': comps[15], 'UUID': comps[16], } return ret def lvdisplay(lvname='', quiet=False): ''' Return information about the logical volume(s) CLI Examples: .. code-block:: bash salt '*' lvm.lvdisplay salt '*' lvm.lvdisplay /dev/vg_myserver/root ''' ret = {} cmd = ['lvdisplay', '-c'] if lvname: cmd.append(lvname) if quiet: cmd_ret = __salt__['cmd.run_all'](cmd, python_shell=False, output_loglevel='quiet') else: cmd_ret = __salt__['cmd.run_all'](cmd, python_shell=False) if cmd_ret['retcode'] != 0: return {} out = cmd_ret['stdout'].splitlines() for line in out: comps = line.strip().split(':') ret[comps[0]] = { 'Logical Volume Name': comps[0], 'Volume Group Name': comps[1], 'Logical Volume Access': comps[2], 'Logical Volume Status': comps[3], 'Internal Logical Volume Number': comps[4], 'Open Logical Volumes': comps[5], 'Logical Volume Size': comps[6], 'Current Logical Extents Associated': comps[7], 'Allocated Logical Extents': comps[8], 'Allocation Policy': comps[9], 'Read Ahead Sectors': comps[10], 'Major Device Number': comps[11], 'Minor Device Number': comps[12], } return ret def pvcreate(devices, override=True, **kwargs): ''' Set a physical device to be used as an LVM physical volume override Skip devices, if they are already LVM physical volumes CLI Examples: .. code-block:: bash salt mymachine lvm.pvcreate /dev/sdb1,/dev/sdb2 salt mymachine lvm.pvcreate /dev/sdb1 dataalignmentoffset=7s ''' if not devices: return 'Error: at least one device is required' if isinstance(devices, six.string_types): devices = devices.split(',') cmd = ['pvcreate', '-y'] for device in devices: if not os.path.exists(device): raise CommandExecutionError('{0} does not exist'.format(device)) if not pvdisplay(device): cmd.append(device) elif not override: raise CommandExecutionError('Device "{0}" is already an LVM physical volume.'.format(device)) if not cmd[2:]: # All specified devices are already LVM volumes return True valid = ('metadatasize', 'dataalignment', 'dataalignmentoffset', 'pvmetadatacopies', 'metadatacopies', 'metadataignore', 'restorefile', 'norestorefile', 'labelsector', 'setphysicalvolumesize') no_parameter = ('force', 'norestorefile') for var in kwargs: if kwargs[var] and var in valid: cmd.extend(['--{0}'.format(var), kwargs[var]]) elif kwargs[var] and var in no_parameter: cmd.append('--{0}'.format(var)) out = __salt__['cmd.run_all'](cmd, python_shell=False) if out.get('retcode'): raise CommandExecutionError(out.get('stderr')) # Verify pvcreate was successful for device in devices: if not pvdisplay(device): raise CommandExecutionError('Device "{0}" was not affected.'.format(device)) return True def pvremove(devices, override=True): ''' Remove a physical device being used as an LVM physical volume override Skip devices, if they are already not used as LVM physical volumes CLI Examples: .. code-block:: bash salt mymachine lvm.pvremove /dev/sdb1,/dev/sdb2 ''' if isinstance(devices, six.string_types): devices = devices.split(',') cmd = ['pvremove', '-y'] for device in devices: if pvdisplay(device): cmd.append(device) elif not override: raise CommandExecutionError('{0} is not a physical volume'.format(device)) if not cmd[2:]: # Nothing to do return True out = __salt__['cmd.run_all'](cmd, python_shell=False) if out.get('retcode'): raise CommandExecutionError(out.get('stderr')) # Verify pvcremove was successful for device in devices: if pvdisplay(device): raise CommandExecutionError('Device "{0}" was not affected.'.format(device)) return True def vgcreate(vgname, devices, **kwargs): ''' Create an LVM volume group CLI Examples: .. code-block:: bash salt mymachine lvm.vgcreate my_vg /dev/sdb1,/dev/sdb2 salt mymachine lvm.vgcreate my_vg /dev/sdb1 clustered=y ''' if not vgname or not devices: return 'Error: vgname and device(s) are both required' if isinstance(devices, six.string_types): devices = devices.split(',') cmd = ['vgcreate', vgname] for device in devices: cmd.append(device) valid = ('clustered', 'maxlogicalvolumes', 'maxphysicalvolumes', 'vgmetadatacopies', 'metadatacopies', 'physicalextentsize') for var in kwargs: if kwargs[var] and var in valid: cmd.append('--{0}'.format(var)) cmd.append(kwargs[var]) out = __salt__['cmd.run'](cmd, python_shell=False).splitlines() vgdata = vgdisplay(vgname) vgdata['Output from vgcreate'] = out[0].strip() return vgdata def vgextend(vgname, devices): ''' Add physical volumes to an LVM volume group CLI Examples: .. code-block:: bash salt mymachine lvm.vgextend my_vg /dev/sdb1,/dev/sdb2 salt mymachine lvm.vgextend my_vg /dev/sdb1 ''' if not vgname or not devices: return 'Error: vgname and device(s) are both required' if isinstance(devices, six.string_types): devices = devices.split(',') cmd = ['vgextend', vgname] for device in devices: cmd.append(device) out = __salt__['cmd.run'](cmd, python_shell=False).splitlines() vgdata = {'Output from vgextend': out[0].strip()} return vgdata def lvcreate(lvname, vgname, size=None, extents=None, snapshot=None, pv=None, thinvolume=False, thinpool=False, force=False, **kwargs): ''' Create a new logical volume, with option for which physical volume to be used CLI Examples: .. code-block:: bash salt '*' lvm.lvcreate new_volume_name vg_name size=10G salt '*' lvm.lvcreate new_volume_name vg_name extents=100 pv=/dev/sdb salt '*' lvm.lvcreate new_snapshot vg_name snapshot=volume_name size=3G .. versionadded:: to_complete Support for thin pools and thin volumes CLI Examples: .. code-block:: bash salt '*' lvm.lvcreate new_thinpool_name vg_name size=20G thinpool=True salt '*' lvm.lvcreate new_thinvolume_name vg_name/thinpool_name size=10G thinvolume=True ''' if size and extents: return 'Error: Please specify only one of size or extents' if thinvolume and thinpool: return 'Error: Please set only one of thinvolume or thinpool to True' valid = ('activate', 'chunksize', 'contiguous', 'discards', 'stripes', 'stripesize', 'minor', 'persistent', 'mirrors', 'noudevsync', 'monitor', 'ignoremonitoring', 'permission', 'poolmetadatasize', 'readahead', 'regionsize', 'type', 'virtualsize', 'zero') no_parameter = ('noudevsync', 'ignoremonitoring', 'thin', ) extra_arguments = [] if kwargs: for k, v in six.iteritems(kwargs): if k in no_parameter: extra_arguments.append('--{0}'.format(k)) elif k in valid: extra_arguments.extend(['--{0}'.format(k), '{0}'.format(v)]) cmd = [salt.utils.path.which('lvcreate')] if thinvolume: cmd.extend(['--thin', '-n', lvname]) elif thinpool: cmd.extend(['--thinpool', lvname]) else: cmd.extend(['-n', lvname]) if snapshot: cmd.extend(['-s', '{0}/{1}'.format(vgname, snapshot)]) else: cmd.append(vgname) if size and thinvolume: cmd.extend(['-V', '{0}'.format(size)]) elif extents and thinvolume: return 'Error: Thin volume size cannot be specified as extents' elif size: cmd.extend(['-L', '{0}'.format(size)]) elif extents: cmd.extend(['-l', '{0}'.format(extents)]) else: return 'Error: Either size or extents must be specified' if pv: cmd.append(pv) if extra_arguments: cmd.extend(extra_arguments) if force: cmd.append('--yes') out = __salt__['cmd.run'](cmd, python_shell=False).splitlines() lvdev = '/dev/{0}/{1}'.format(vgname, lvname) lvdata = lvdisplay(lvdev) lvdata['Output from lvcreate'] = out[0].strip() return lvdata def vgremove(vgname): ''' Remove an LVM volume group CLI Examples: .. code-block:: bash salt mymachine lvm.vgremove vgname salt mymachine lvm.vgremove vgname force=True ''' cmd = ['vgremove', '-f', vgname] out = __salt__['cmd.run'](cmd, python_shell=False) return out.strip() def lvremove(lvname, vgname): ''' Remove a given existing logical volume from a named existing volume group CLI Example: .. code-block:: bash salt '*' lvm.lvremove lvname vgname force=True ''' cmd = ['lvremove', '-f', '{0}/{1}'.format(vgname, lvname)] out = __salt__['cmd.run'](cmd, python_shell=False) return out.strip() def lvresize(size=None, lvpath=None, extents=None): ''' Return information about the logical volume(s) CLI Examples: .. code-block:: bash salt '*' lvm.lvresize +12M /dev/mapper/vg1-test salt '*' lvm.lvresize lvpath=/dev/mapper/vg1-test extents=+100%FREE ''' if size and extents: log.error('Error: Please specify only one of size or extents') return {} cmd = ['lvresize'] if size: cmd.extend(['-L', '{0}'.format(size)]) elif extents: cmd.extend(['-l', '{0}'.format(extents)]) else: log.error('Error: Either size or extents must be specified') return {} cmd.append(lvpath) cmd_ret = __salt__['cmd.run'](cmd, python_shell=False).splitlines() return {'Output from lvresize': cmd_ret[0].strip()}