From 77fb5d3b40f4b7ac87865247415611119ef2a57f Mon Sep 17 00:00:00 2001 From: John Griffith Date: Tue, 14 May 2013 17:35:44 -0600 Subject: [PATCH] Add thin provisioning support checks. Add a simple check to verify thin provisioning is supported in the systems current LVM2 version. Also add a helper to create thin pools. Change-Id: I1ae3c168b148029a3085be827209f59bc68ca145 --- cinder/brick/local_dev/lvm.py | 45 ++++++++++++++++++++++++++++ cinder/tests/brick/test_brick_lvm.py | 18 +++++++++++ 2 files changed, 63 insertions(+) diff --git a/cinder/brick/local_dev/lvm.py b/cinder/brick/local_dev/lvm.py index f4122c28a..e01104427 100644 --- a/cinder/brick/local_dev/lvm.py +++ b/cinder/brick/local_dev/lvm.py @@ -120,6 +120,28 @@ class LVM(object): else: return [] + @staticmethod + def supports_thin_provisioning(): + """Static method to check for thin LVM support on a system. + + :returns: True if supported, False otherwise + + """ + cmd = ['vgs', '--version'] + (out, err) = putils.execute(*cmd, root_helper='sudo', run_as_root=True) + lines = out.split('\n') + + for line in lines: + if 'LVM version' in line: + version_list = line.split() + version = version_list[2] + if '(2)' in version: + version = version.replace('(2)', '') + version_tuple = tuple(map(int, version.split('.'))) + if version_tuple >= (2, 2, 95): + return True + return False + @staticmethod def get_all_volumes(vg_name=None): """Static method to get all LV's on a system. @@ -250,6 +272,29 @@ class LVM(object): return vg_list[0] + def create_thin_pool(self, name=None, size_str=0): + """Creates a thin provisioning pool for this VG. + + :param name: Name to use for pool, default is "-pool" + :param size_str: Size to allocate for pool, default is entire VG + + """ + + if not self.supports_thin_provisioning(): + LOG.error(_('Requested to setup thin provisioning, ' + 'however current LVM version does not ' + 'support it.')) + return None + + if name is None: + name = '%s-pool' % self.vg_name + + if size_str == 0: + self.update_volume_group_info() + size_str = self.vg_size + + self.create_volume(name, size_str, 'thin') + def create_volume(self, name, size_str, lv_type='default', mirror_count=0): """Creates a logical volume on the object's VG. diff --git a/cinder/tests/brick/test_brick_lvm.py b/cinder/tests/brick/test_brick_lvm.py index e418227ef..9d3ac6b23 100644 --- a/cinder/tests/brick/test_brick_lvm.py +++ b/cinder/tests/brick/test_brick_lvm.py @@ -46,12 +46,20 @@ class BrickLvmTestCase(test.TestCase): def failed_fake_execute(obj, *cmd, **kwargs): return ("\n", "fake-error") + def fake_pretend_lvm_version(obj, *cmd, **kwargs): + return (" LVM version: 2.03.00 (2012-03-06)\n", "") + + def fake_old_lvm_version(obj, *cmd, **kwargs): + return (" LVM version: 2.02.65(2) (2012-03-06)\n", "") + def fake_execute(obj, *cmd, **kwargs): cmd_string = ', '.join(cmd) data = "\n" if 'vgs, --noheadings, -o, name' == cmd_string: data = " fake-volumes\n" + if 'vgs, --version' in cmd_string: + data = " LVM version: 2.02.95(2) (2012-03-06)\n" elif 'vgs, --noheadings, -o uuid, fake-volumes' in cmd_string: data = " kVxztV-dKpG-Rz7E-xtKY-jeju-QsYU-SLG6Z1\n" elif 'vgs, --noheadings, -o, name,size,free,lv_count,uuid' in\ @@ -124,3 +132,13 @@ class BrickLvmTestCase(test.TestCase): self.stubs.Set(processutils, 'execute', self.fake_execute) self.assertEqual(self.vg.update_volume_group_info()['name'], 'fake-volumes') + + def test_thin_support(self): + self.stubs.Set(processutils, 'execute', self.fake_execute) + self.assertTrue(self.vg.supports_thin_provisioning()) + + self.stubs.Set(processutils, 'execute', self.fake_pretend_lvm_version) + self.assertTrue(self.vg.supports_thin_provisioning()) + + self.stubs.Set(processutils, 'execute', self.fake_old_lvm_version) + self.assertFalse(self.vg.supports_thin_provisioning()) -- 2.45.2