From abd3475fe7e162760424188b7d1b7bdca88091ac Mon Sep 17 00:00:00 2001 From: Eric Harney Date: Wed, 6 Feb 2013 10:25:51 -0500 Subject: [PATCH] Create a RemoteFsDriver class This class holds common functions for drivers similar to NFS. Change-Id: I83d89c971fd0153df7702e2803bed66df1a759f6 --- cinder/tests/test_nfs.py | 91 +++++++++++++++++++++++++++ cinder/volume/drivers/nfs.py | 118 ++++++++++++++++++++--------------- 2 files changed, 157 insertions(+), 52 deletions(-) diff --git a/cinder/tests/test_nfs.py b/cinder/tests/test_nfs.py index c3e98c3a2..2f16f79f9 100644 --- a/cinder/tests/test_nfs.py +++ b/cinder/tests/test_nfs.py @@ -43,6 +43,97 @@ class DumbVolume(object): return self.fields[item] +class RemoteFsDriverTestCase(test.TestCase): + TEST_EXPORT = '1.2.3.4/export1' + TEST_FILE_NAME = 'test.txt' + + def setUp(self): + self._driver = nfs.RemoteFsDriver() + self._mox = mox_lib.Mox() + pass + + def tearDown(self): + self._mox.UnsetStubs() + + def test_create_sparsed_file(self): + (mox, drv) = self._mox, self._driver + + mox.StubOutWithMock(drv, '_execute') + drv._execute('truncate', '-s', '1G', '/path', run_as_root=True).\ + AndReturn("") + + mox.ReplayAll() + + drv._create_sparsed_file('/path', 1) + + mox.VerifyAll() + + def test_create_regular_file(self): + (mox, drv) = self._mox, self._driver + + mox.StubOutWithMock(drv, '_execute') + drv._execute('dd', 'if=/dev/zero', 'of=/path', 'bs=1M', 'count=1024', + run_as_root=True) + + mox.ReplayAll() + + drv._create_regular_file('/path', 1) + + mox.VerifyAll() + + def test_set_rw_permissions_for_all(self): + (mox, drv) = self._mox, self._driver + + mox.StubOutWithMock(drv, '_execute') + drv._execute('chmod', 'ugo+rw', '/path', run_as_root=True) + + mox.ReplayAll() + + drv._set_rw_permissions_for_all('/path') + + mox.VerifyAll() + + def test_path_exists_should_return_true(self): + """_path_exists should return True if stat returns 0.""" + mox = self._mox + drv = self._driver + + mox.StubOutWithMock(drv, '_execute') + drv._execute('stat', self.TEST_FILE_NAME, run_as_root=True) + + mox.ReplayAll() + + self.assertTrue(drv._path_exists(self.TEST_FILE_NAME)) + + mox.VerifyAll() + + def test_path_exists_should_return_false(self): + """_path_exists should return True if stat doesn't return 0.""" + mox = self._mox + drv = self._driver + + mox.StubOutWithMock(drv, '_execute') + drv._execute( + 'stat', + self.TEST_FILE_NAME, run_as_root=True).\ + AndRaise(ProcessExecutionError( + stderr="stat: cannot stat `test.txt': No such file " + "or directory")) + + mox.ReplayAll() + + self.assertFalse(drv._path_exists(self.TEST_FILE_NAME)) + + mox.VerifyAll() + + def test_get_hash_str(self): + """_get_hash_str should calculation correct value.""" + drv = self._driver + + self.assertEqual('4d664fd43b6ff86d80a4ea969c07b3b9', + drv._get_hash_str(self.TEST_EXPORT)) + + class NfsDriverTestCase(test.TestCase): """Test case for NFS driver.""" diff --git a/cinder/volume/drivers/nfs.py b/cinder/volume/drivers/nfs.py index ebf157582..dead3ef45 100755 --- a/cinder/volume/drivers/nfs.py +++ b/cinder/volume/drivers/nfs.py @@ -52,7 +52,72 @@ FLAGS = flags.FLAGS FLAGS.register_opts(volume_opts) -class NfsDriver(driver.VolumeDriver): +class RemoteFsDriver(driver.VolumeDriver): + """Common base for drivers that work like NFS.""" + + def check_for_setup_error(self): + """Just to override parent behavior.""" + pass + + def create_volume(self, volume): + raise NotImplementedError() + + def delete_volume(self, volume): + raise NotImplementedError() + + def ensure_export(self, ctx, volume): + raise NotImplementedError() + + def _create_sparsed_file(self, path, size): + """Creates file with 0 disk usage.""" + self._execute('truncate', '-s', '%sG' % size, + path, run_as_root=True) + + def _create_regular_file(self, path, size): + """Creates regular file of given size. Takes a lot of time for large + files.""" + KB = 1024 + MB = KB * 1024 + GB = MB * 1024 + + block_size_mb = 1 + block_count = size * GB / (block_size_mb * MB) + + self._execute('dd', 'if=/dev/zero', 'of=%s' % path, + 'bs=%dM' % block_size_mb, + 'count=%d' % block_count, + run_as_root=True) + + def _set_rw_permissions_for_all(self, path): + """Sets 666 permissions for the path.""" + self._execute('chmod', 'ugo+rw', path, run_as_root=True) + + def local_path(self, volume): + """Get volume path (mounted locally fs path) for given volume + :param volume: volume reference + """ + nfs_share = volume['provider_location'] + return os.path.join(self._get_mount_point_for_share(nfs_share), + volume['name']) + + def _path_exists(self, path): + """Check for existence of given path.""" + try: + self._execute('stat', path, run_as_root=True) + return True + except exception.ProcessExecutionError as exc: + if 'No such file or directory' in exc.stderr: + return False + else: + raise + + def _get_hash_str(self, base_str): + """returns string that represents hash of base_str + (in a hex format).""" + return hashlib.md5(base_str).hexdigest() + + +class NfsDriver(RemoteFsDriver): """NFS based cinder driver. Creates file on NFS share for using it as block device on hypervisor.""" @@ -79,10 +144,6 @@ class NfsDriver(driver.VolumeDriver): else: raise - def check_for_setup_error(self): - """Just to override parent behavior""" - pass - def create_cloned_volume(self, volume, src_vref): raise NotImplementedError() @@ -146,38 +207,6 @@ class NfsDriver(driver.VolumeDriver): """Disallow connection from connector""" pass - def local_path(self, volume): - """Get volume path (mounted locally fs path) for given volume - :param volume: volume reference - """ - nfs_share = volume['provider_location'] - return os.path.join(self._get_mount_point_for_share(nfs_share), - volume['name']) - - def _create_sparsed_file(self, path, size): - """Creates file with 0 disk usage""" - self._execute('truncate', '-s', '%sG' % size, - path, run_as_root=True) - - def _create_regular_file(self, path, size): - """Creates regular file of given size. Takes a lot of time for large - files""" - KB = 1024 - MB = KB * 1024 - GB = MB * 1024 - - block_size_mb = 1 - block_count = size * GB / (block_size_mb * MB) - - self._execute('dd', 'if=/dev/zero', 'of=%s' % path, - 'bs=%dM' % block_size_mb, - 'count=%d' % block_count, - run_as_root=True) - - def _set_rw_permissions_for_all(self, path): - """Sets 666 permissions for the path""" - self._execute('chmod', 'ugo+rw', path, run_as_root=True) - def _do_create_volume(self, volume): """Create a volume on given nfs_share :param volume: volume reference @@ -288,18 +317,3 @@ class NfsDriver(driver.VolumeDriver): LOG.warn(_("%s is already mounted"), nfs_share) else: raise - - def _path_exists(self, path): - """Check given path """ - try: - self._execute('stat', path, run_as_root=True) - return True - except exception.ProcessExecutionError as exc: - if 'No such file or directory' in exc.stderr: - return False - else: - raise - - def _get_hash_str(self, base_str): - """returns string that represents hash of base_str (in a hex format)""" - return hashlib.md5(base_str).hexdigest() -- 2.45.2