Commit a3a4a698 authored by Thibault VINCENT's avatar Thibault VINCENT
Browse files

add: better lvm interface

parent ddb77017
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ from multiprocessing import cpu_count
from platform import platform, machine, system
from socket import gethostbyaddr, gethostname
from jobs import JobManager
from lvm import LVM


class Host(object):
@@ -36,6 +37,7 @@ class LocalHost(Host):
        '''
        super(LocalHost, self).__init__()
        self.jobmgr = JobManager(self)
        self.lvm = LVM()
    
    def scheduler_run(self):
        '''
+193 −170
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@

import os
from errors import LVMError
from utils import Exec
from utils import Exec, RWLock

class LVM(object):
    '''
@@ -28,11 +28,16 @@ class LVM(object):
    VGREMOVE      = os.path.join(BIN_PATH, 'vgremove')
    DMSETUP       = os.path.join(BIN_PATH, 'dmsetup')
    
    # global class lock : do not abuse LVM/DM too much
    _mutex = RWLock()
    
    def __init__(self):
        '''
        '''
        self.reload()
    
    """
    FIXME not working anymore
    def __str__(self):
        '''
        '''
@@ -49,25 +54,27 @@ class LVM(object):
                s += '    %s (path: %s, size: %s)' % (lv.name, lv.path,
                                                                    lv.total)
        return s
    """
    
    def _reload_pvs(self):
        '''
        '''
        with self._mutex.write:
            self._pvs = {}
            # execute query command
            (rc, output) = Exec.call([self.LVM,
                                  "pvs",
                                  "--nosuffix",
                                  "--noheadings",
                                  "--units", "b",
                                  "--separator", "~",
                                  "-o", ("pv_uuid,pv_name,vg_name,pv_fmt,"
                                         "pv_attr,dev_size,pv_size,pv_free,"
                                         "pv_used,pv_pe_count,"
                                         "pv_pe_alloc_count")],
                                      'pvs',
                                      '--nosuffix',
                                      '--noheadings',
                                      '--units', 'b',
                                      '--separator', '~',
                                      '-o', ('pv_uuid,pv_name,vg_name,pv_fmt,'
                                             'pv_attr,dev_size,pv_size,pv_free,'
                                             'pv_used,pv_pe_count,'
                                             'pv_pe_alloc_count')],
                                     merge_output = False)
            if rc != 0:
            raise LVMError("error getting list of PV")
                raise LVMError('error getting list of PV')
            # parse command output
            for line in output[0].splitlines():
                # extract tokens
@@ -83,7 +90,7 @@ class LVM(object):
                    p_used,
                    p_extent,
                    p_ext_alloc,
            ) = line.strip().split("~")
                ) = line.strip().split('~')
                # if the PV is not used, set VG to None
                if not len(p_vg):
                    p_vg = None
@@ -96,25 +103,26 @@ class LVM(object):
                # register obj
                self._pvs[p_name] = pv
                if p_vg:
                self._vgs[p_vg].pvs[p_name] = pv
                    self._vgs[p_vg]._pvs[p_name] = pv
    
    def _reload_vgs(self):
        '''
        '''
        with self._mutex.write:
            self._vgs = {}
            # execute query command
            (rc, output) = Exec.call([self.LVM,
                                  "vgs",
                                  "--nosuffix",
                                  "--noheadings",
                                  "--units", "b",
                                  "--separator", "~",
                                  "-o", ("vg_uuid,vg_name,vg_fmt,vg_attr,"
                                         "vg_size,vg_free,vg_extent_size,"
                                         "vg_extent_count,vg_free_count")],
                                      'vgs',
                                      '--nosuffix',
                                      '--noheadings',
                                      '--units', 'b',
                                      '--separator', '~',
                                      '-o', ('vg_uuid,vg_name,vg_fmt,vg_attr,'
                                             'vg_size,vg_free,vg_extent_size,'
                                             'vg_extent_count,vg_free_count')],
                                     merge_output = False)
            if rc != 0:
            raise LVMError("error getting list of VG")
                raise LVMError('error getting list of VG')
            # parse command output
            for line in output[0].splitlines():
                # extract tokens
@@ -128,7 +136,7 @@ class LVM(object):
                    v_ext_size,
                    v_extent,
                    v_ext_free,
            ) = line.strip().split("~")
                ) = line.strip().split('~')
                # create VG object
                vg = self._VG(self, v_uuid, v_name, v_format, v_attr, int(v_size),
                        int(v_free), int(v_ext_size), int(v_extent),
@@ -139,18 +147,19 @@ class LVM(object):
    def _reload_lvs(self):
        '''
        '''
        with self._mutex.write:
            # execute query command
            (rc, output) = Exec.call([self.LVM,
                                  "lvs",
                                  "--nosuffix",
                                  "--noheadings",
                                  "--units", "b",
                                  "--separator", "~",
                                  "-o", ("lv_uuid,lv_name,vg_name,lv_attr,"
                                         "lv_size")],
                                      'lvs',
                                      '--nosuffix',
                                      '--noheadings',
                                      '--units', 'b',
                                      '--separator', '~',
                                      '-o', ('lv_uuid,lv_name,vg_name,lv_attr,'
                                             'lv_size')],
                                     merge_output = False)
            if rc != 0:
            raise LVMError("error getting list of LV")
                raise LVMError('error getting list of LV')
            # parse command output
            for line in output[0].splitlines():
                # extract tokens
@@ -160,11 +169,12 @@ class LVM(object):
                    l_vg,
                    l_attr,
                    l_size,
            ) = line.strip().split("~")
                ) = line.strip().split('~')
                # create LV object
            lv = self._LV(self, self._vgs[l_vg], l_uuid, l_name, l_attr, l_size)
                lv = self._LV(self, self._vgs[l_vg], l_uuid, l_name, l_attr,
                                                                        l_size)
                # register object
            self._vgs[l_vg].lvs[l_name] = lv
                self._vgs[l_vg]._lvs[l_name] = lv
    
    def reload(self):
        # VG must be reloaded before PV
@@ -175,43 +185,49 @@ class LVM(object):
    def get_pv(self, path):
        '''
        '''
        with self._mutex.read:
            return self._pvs[path]
    
    def get_vg(self, name):
        '''
        '''
        with self._mutex.read:
            return self._vgs[name]
    
    def get_lv(self, vgname, name):
        '''
        '''
        return self._vgs[vgname].lvs[name]
        with self._mutex.read:
            return self._vgs[vgname]._lvs[name]
    
    def dm_create(self, name, table):
        '''
        '''
        with self._mutex.write:
            rc = Exec.silent([self.DMSETUP,
                              'create',
                              name],
                              input=table)
            if rc:
            raise LVMError("failed to create DM device")
                raise LVMError('failed to create DM device')
    
    def dm_remove(self, dm_name, force=True):
    def dm_remove(self, name, force=True):
        '''
        '''
        with self._mutex.write:
            # build command arguments
            argv = [self.DMSETUP, 'remove']
            if force is True:
                argv.append('--force')
        argv.append(dm_name)
            argv.append(name)
            # execute command
            if Exec.silent(argv):
            raise LVMError("failed to remove DM")
                raise LVMError('failed to remove DM')
    
    def dm_get_table(self, name):
        '''
        '''
        with self._mutex.read:
            rc, output = Exec.call([self.DMSETUP,
                                    'table',
                                    '--showkeys',
@@ -219,18 +235,19 @@ class LVM(object):
                                    merge_output=False)
            table = str(output[0]).strip()
            if rc or not len(table):
            raise LVMError("failed to get DM table")
                raise LVMError('failed to get DM table')
            return table
    
    def dm_set_table(self, name, table):
        '''
        '''
        with self._mutex.write:
            rc = Exec.silent([self.DMSETUP,
                              'load',
                              name],
                              input=table)
            if rc:
            raise LVMError("failed to change DM table")
                raise LVMError('failed to change DM table')
    
    
    class _Vol(object):
@@ -239,9 +256,9 @@ class LVM(object):
        def __init__(self, mngr, vg, uuid, name, attrs):
            self._mngr = mngr
            self.vg = vg
            self.uuid = uuid
            self.name = name
            self.attrs = attrs
            self.uuid = str(uuid)
            self.name = str(name)
            self.attrs = str(attrs)
    
    
    class _PV(_Vol):
@@ -250,13 +267,13 @@ class LVM(object):
        def __init__(self, mngr, vg, uuid, name, format, attrs, device_size,
                                size, free, used, extent_total, extent_used):
            super(LVM._PV, self).__init__(mngr, vg, uuid, name, attrs)
            self.format = format
            self.device_size = device_size
            self.size = size
            self.free = free
            self.used = used
            self.extent_total = extent_total
            self.extent_used = extent_used
            self.format = str(format)
            self.device_size = int(device_size)
            self.size = int(size)
            self.free = int(free)
            self.used = int(used)
            self.extent_total = int(extent_total)
            self.extent_used = int(extent_used)
    
    
    class _VG(_Vol):
@@ -265,41 +282,48 @@ class LVM(object):
        def __init__(self, mngr, uuid, name, format, attrs, size, free,
                                    extent_size, extent_total, extent_free):
            super(LVM._VG, self).__init__(mngr, self, uuid, name, attrs)
            self.pvs = {}
            self.lvs = {}
            self.format = format
            self.size = size
            self.free = free
            self.extent_size = extent_size
            self.extent_total = extent_total
            self.extent_free = extent_free
            self._pvs = {}
            self._lvs = {}
            self.format = str(format)
            self.size = int(size)
            self.free = int(free)
            self.extent_size = int(extent_size)
            self.extent_total = int(extent_total)
            self.extent_free = int(extent_free)
        
        def create(self, name, size):
            '''
            '''
            # execute create command
            if Exec.silent([self.LVCREATE,
                            "-l", int(size),
                            "-n", name,
            if Exec.silent([LVM.LVCREATE,
                            '-L', '%iB' % size,
                            '-n', name,
                            self.name]) != 0:
                raise LVMError("error creating LV")
                raise LVMError('error creating LV')
        
        def remove(self, name):
            '''
            '''
            # execute create command
            if Exec.silent([self.LVREMOVE,
                            "-f",
                            "%s/%s" % (self.name, name)]) != 0:
                raise LVMError("error removing LV")
            if Exec.silent([LVM.LVREMOVE,
                            '-f',
                            '%s/%s' % (self.name, name)]) != 0:
                raise LVMError('error removing LV')
        
        def get_lv(self, name):
            '''
            '''
            with self._mngr._mutex.read:
                return self._lvs[name]
    
    class _LV(_Vol):
        '''
        '''
        def __init__(self, mngr, vg, uuid, name, attrs, size):
            super(LVM._LV, self).__init__(mngr, vg, uuid, name, attrs)
            self.size = size
            self.size = int(size)
            #fixme
            self.path = '/dev/%s/%s' % (self.vg.name, self.name)
        
        def dm_name(self):
            '''
@@ -311,4 +335,3 @@ class LVM(object):
            '''
            '''
            return self._mngr.dm_get_table(self.dm_name())