]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Factorize code between nfs.py and glusterfs.py
authorFrederic Lepied <frederic.lepied@enovance.com>
Tue, 23 Jul 2013 18:20:27 +0000 (11:20 -0700)
committerFrederic Lepied <frederic.lepied@enovance.com>
Thu, 1 Aug 2013 14:04:42 +0000 (10:04 -0400)
Suppressed most duplicated code between nfs.py and glusterfs.py.

Change-Id: I8a25aa6e3b8947a1d8e75dc611fac217e3009c41
Fixes: bug #1204213
cinder/volume/drivers/glusterfs.py
cinder/volume/drivers/nfs.py

index 3dea75f13f12df61852218d61f695b620c67fecb..ea79fc8c46ab4351ab43cfcdba5c5ca67e497671 100644 (file)
@@ -52,6 +52,11 @@ class GlusterfsDriver(nfs.RemoteFsDriver):
     as block device on hypervisor.
     """
 
+    driver_volume_type = 'glusterfs'
+    driver_prefix = 'glusterfs'
+    volume_backend_name = 'GlusterFS'
+    version = VERSION
+
     def __init__(self, *args, **kwargs):
         super(GlusterfsDriver, self).__init__(*args, **kwargs)
         self.configuration.append_config_values(volume_opts)
@@ -87,96 +92,6 @@ class GlusterfsDriver(nfs.RemoteFsDriver):
         """Just to override parent behavior."""
         pass
 
-    def create_cloned_volume(self, volume, src_vref):
-        raise NotImplementedError()
-
-    def create_volume(self, volume):
-        """Creates a volume."""
-
-        self._ensure_shares_mounted()
-
-        volume['provider_location'] = self._find_share(volume['size'])
-
-        LOG.info(_('casted to %s') % volume['provider_location'])
-
-        self._do_create_volume(volume)
-
-        return {'provider_location': volume['provider_location']}
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume."""
-
-        if not volume['provider_location']:
-            LOG.warn(_('Volume %s does not have provider_location specified, '
-                     'skipping'), volume['name'])
-            return
-
-        self._ensure_share_mounted(volume['provider_location'])
-
-        mounted_path = self.local_path(volume)
-
-        self._execute('rm', '-f', mounted_path, run_as_root=True)
-
-    def ensure_export(self, ctx, volume):
-        """Synchronously recreates an export for a logical volume."""
-        self._ensure_share_mounted(volume['provider_location'])
-
-    def create_export(self, ctx, volume):
-        """Exports the volume. Can optionally return a Dictionary of changes
-        to the volume object to be persisted.
-        """
-        pass
-
-    def remove_export(self, ctx, volume):
-        """Removes an export for a logical volume."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Allow connection to connector and return connection info."""
-        data = {'export': volume['provider_location'],
-                'name': volume['name']}
-        if volume['provider_location'] in self.shares:
-            data['options'] = self.shares[volume['provider_location']]
-        return {
-            'driver_volume_type': 'glusterfs',
-            'data': data
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Disallow connection from connector."""
-        pass
-
-    def _do_create_volume(self, volume):
-        """Create a volume on given glusterfs_share.
-        :param volume: volume reference
-        """
-        volume_path = self.local_path(volume)
-        volume_size = volume['size']
-
-        if self.configuration.glusterfs_sparsed_volumes:
-            self._create_sparsed_file(volume_path, volume_size)
-        else:
-            self._create_regular_file(volume_path, volume_size)
-
-        self._set_rw_permissions_for_all(volume_path)
-
-    def _ensure_shares_mounted(self):
-        """Look for GlusterFS shares in the flags and try to mount them
-           locally.
-        """
-        self._mounted_shares = []
-
-        self._load_shares_config(self.configuration.glusterfs_shares_config)
-
-        for share in self.shares.keys():
-            try:
-                self._ensure_share_mounted(share)
-                self._mounted_shares.append(share)
-            except Exception as exc:
-                LOG.warning(_('Exception during mounting %s') % (exc,))
-
-        LOG.debug('Available shares %s' % str(self._mounted_shares))
-
     def _ensure_share_mounted(self, glusterfs_share):
         """Mount GlusterFS share.
         :param glusterfs_share: string
@@ -238,6 +153,10 @@ class GlusterfsDriver(nfs.RemoteFsDriver):
 
         return available, size
 
+    def _get_capacity_info(self, glusterfs_share):
+        available, size = self._get_available_capacity(glusterfs_share)
+        return size, available, size - available
+
     def _mount_glusterfs(self, glusterfs_share, mount_path, ensure=False):
         """Mount GlusterFS share to mount path."""
         self._execute('mkdir', '-p', mount_path)
@@ -247,45 +166,4 @@ class GlusterfsDriver(nfs.RemoteFsDriver):
         if self.shares.get(glusterfs_share) is not None:
             command.extend(self.shares[glusterfs_share].split())
 
-        try:
-            self._execute(*command, run_as_root=True)
-        except exception.ProcessExecutionError as exc:
-            if ensure and 'already mounted' in exc.stderr:
-                LOG.warn(_("%s is already mounted"), glusterfs_share)
-            else:
-                raise
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume stats.
-
-        If 'refresh' is True, update the stats first.
-        """
-        if refresh or not self._stats:
-            self._update_volume_stats()
-
-        return self._stats
-
-    def _update_volume_stats(self):
-        """Retrieve stats info from volume group."""
-
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data['volume_backend_name'] = backend_name or 'GlusterFS'
-        data['vendor_name'] = 'Open Source'
-        data['driver_version'] = VERSION
-        data['storage_protocol'] = 'glusterfs'
-
-        self._ensure_shares_mounted()
-
-        global_capacity = 0
-        global_free = 0
-        for nfs_share in self._mounted_shares:
-            free, capacity = self._get_available_capacity(nfs_share)
-            global_capacity += capacity
-            global_free += free
-
-        data['total_capacity_gb'] = global_capacity / 1024.0 ** 3
-        data['free_capacity_gb'] = global_free / 1024.0 ** 3
-        data['reserved_percentage'] = 0
-        data['QoS_support'] = False
-        self._stats = data
+        self._do_mount(command, ensure, glusterfs_share)
index b851c4eb87ddc955202f5ba223d34c7750daede2..cf4803100db5caccbaf29a3e6af755a9cd28bfaf 100644 (file)
@@ -70,11 +70,103 @@ class RemoteFsDriver(driver.VolumeDriver):
         """Just to override parent behavior."""
         pass
 
+    def initialize_connection(self, volume, connector):
+        """Allow connection to connector and return connection info.
+
+        :param volume: volume reference
+        :param connector: connector reference
+        """
+        data = {'export': volume['provider_location'],
+                'name': volume['name']}
+        if volume['provider_location'] in self.shares:
+            data['options'] = self.shares[volume['provider_location']]
+        return {
+            'driver_volume_type': self.driver_volume_type,
+            'data': data
+        }
+
     def create_volume(self, volume):
+        """Creates a volume.
+
+        :param volume: volume reference
+        """
+        self._ensure_shares_mounted()
+
+        volume['provider_location'] = self._find_share(volume['size'])
+
+        LOG.info(_('casted to %s') % volume['provider_location'])
+
+        self._do_create_volume(volume)
+
+        return {'provider_location': volume['provider_location']}
+
+    def _do_create_volume(self, volume):
+        """Create a volume on given remote share.
+
+        :param volume: volume reference
+        """
+        volume_path = self.local_path(volume)
+        volume_size = volume['size']
+
+        if getattr(self.configuration,
+                   self.driver_prefix + '_sparsed_volumes'):
+            self._create_sparsed_file(volume_path, volume_size)
+        else:
+            self._create_regular_file(volume_path, volume_size)
+
+        self._set_rw_permissions_for_all(volume_path)
+
+    def _ensure_shares_mounted(self):
+        """Look for remote shares in the flags and tries to mount them
+        locally.
+        """
+        self._mounted_shares = []
+
+        self._load_shares_config(getattr(self.configuration,
+                                         self.driver_prefix +
+                                         '_shares_config'))
+
+        for share in self.shares.keys():
+            try:
+                self._ensure_share_mounted(share)
+                self._mounted_shares.append(share)
+            except Exception as exc:
+                LOG.warning(_('Exception during mounting %s') % (exc,))
+
+        LOG.debug('Available shares %s' % str(self._mounted_shares))
+
+    def create_cloned_volume(self, volume, src_vref):
         raise NotImplementedError()
 
     def delete_volume(self, volume):
-        raise NotImplementedError()
+        """Deletes a logical volume.
+
+        :param volume: volume reference
+        """
+        if not volume['provider_location']:
+            LOG.warn(_('Volume %s does not have provider_location specified, '
+                     'skipping'), volume['name'])
+            return
+
+        self._ensure_share_mounted(volume['provider_location'])
+
+        mounted_path = self.local_path(volume)
+
+        self._execute('rm', '-f', mounted_path, run_as_root=True)
+
+    def ensure_export(self, ctx, volume):
+        """Synchronously recreates an export for a logical volume."""
+        self._ensure_share_mounted(volume['provider_location'])
+
+    def create_export(self, ctx, volume):
+        """Exports the volume. Can optionally return a Dictionary of changes
+        to the volume object to be persisted.
+        """
+        pass
+
+    def remove_export(self, ctx, volume):
+        """Removes an export for a logical volume."""
+        pass
 
     def delete_snapshot(self, snapshot):
         """Do nothing for this driver, but allow manager to handle deletion
@@ -82,9 +174,6 @@ class RemoteFsDriver(driver.VolumeDriver):
         """
         pass
 
-    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,
@@ -185,11 +274,80 @@ class RemoteFsDriver(driver.VolumeDriver):
     def _get_mount_point_for_share(self, path):
         raise NotImplementedError()
 
+    def terminate_connection(self, volume, connector, **kwargs):
+        """Disallow connection from connector."""
+        pass
+
+    def get_volume_stats(self, refresh=False):
+        """Get volume stats.
+
+        If 'refresh' is True, update the stats first.
+        """
+        if refresh or not self._stats:
+            self._update_volume_stats()
+
+        return self._stats
+
+    def _update_volume_stats(self):
+        """Retrieve stats info from volume group."""
+
+        data = {}
+        backend_name = self.configuration.safe_get('volume_backend_name')
+        data['volume_backend_name'] = backend_name or self.volume_backend_name
+        data['vendor_name'] = 'Open Source'
+        data['driver_version'] = self.version
+        data['storage_protocol'] = self.driver_volume_type
+
+        self._ensure_shares_mounted()
+
+        global_capacity = 0
+        global_free = 0
+        for share in self._mounted_shares:
+            capacity, free, used = self._get_capacity_info(share)
+            global_capacity += capacity
+            global_free += free
+
+        data['total_capacity_gb'] = global_capacity / float(units.GiB)
+        data['free_capacity_gb'] = global_free / float(units.GiB)
+        data['reserved_percentage'] = 0
+        data['QoS_support'] = False
+        self._stats = data
+
+    def _do_mount(self, cmd, ensure, share):
+        """Finalize mount command.
+
+        :param cmd: command to do the actual mount
+        :param ensure: boolean to allow remounting a share with a warning
+        :param share: description of the share for error reporting
+        """
+        try:
+            self._execute(*cmd, run_as_root=True)
+        except exception.ProcessExecutionError as exc:
+            if ensure and 'already mounted' in exc.stderr:
+                LOG.warn(_("%s is already mounted"), share)
+            else:
+                raise
+
+    def _get_capacity_info(self, nfs_share):
+        raise NotImplementedError()
+
+    def _find_share(self, volume_size_in_gib):
+        raise NotImplementedError()
+
+    def _ensure_share_mounted(self, nfs_share):
+        raise NotImplementedError()
+
 
 class NfsDriver(RemoteFsDriver):
     """NFS based cinder driver. Creates file on NFS share for using it
     as block device on hypervisor.
     """
+
+    driver_volume_type = 'nfs'
+    driver_prefix = 'nfs'
+    volume_backend_name = 'Generic_NFS'
+    version = VERSION
+
     def __init__(self, *args, **kwargs):
         super(NfsDriver, self).__init__(*args, **kwargs)
         self.configuration.append_config_values(volume_opts)
@@ -233,94 +391,6 @@ class NfsDriver(RemoteFsDriver):
             else:
                 raise
 
-    def create_cloned_volume(self, volume, src_vref):
-        raise NotImplementedError()
-
-    def create_volume(self, volume):
-        """Creates a volume"""
-
-        self._ensure_shares_mounted()
-
-        volume['provider_location'] = self._find_share(volume['size'])
-
-        LOG.info(_('casted to %s') % volume['provider_location'])
-
-        self._do_create_volume(volume)
-
-        return {'provider_location': volume['provider_location']}
-
-    def delete_volume(self, volume):
-        """Deletes a logical volume."""
-
-        if not volume['provider_location']:
-            LOG.warn(_('Volume %s does not have provider_location specified, '
-                     'skipping'), volume['name'])
-            return
-
-        self._ensure_share_mounted(volume['provider_location'])
-
-        mounted_path = self.local_path(volume)
-
-        self._execute('rm', '-f', mounted_path, run_as_root=True)
-
-    def ensure_export(self, ctx, volume):
-        """Synchronously recreates an export for a logical volume."""
-        self._ensure_share_mounted(volume['provider_location'])
-
-    def create_export(self, ctx, volume):
-        """Exports the volume. Can optionally return a Dictionary of changes
-        to the volume object to be persisted.
-        """
-        pass
-
-    def remove_export(self, ctx, volume):
-        """Removes an export for a logical volume."""
-        pass
-
-    def initialize_connection(self, volume, connector):
-        """Allow connection to connector and return connection info."""
-        data = {'export': volume['provider_location'],
-                'name': volume['name']}
-        if volume['provider_location'] in self.shares:
-            data['options'] = self.shares[volume['provider_location']]
-        return {
-            'driver_volume_type': 'nfs',
-            'data': data
-        }
-
-    def terminate_connection(self, volume, connector, **kwargs):
-        """Disallow connection from connector."""
-        pass
-
-    def _do_create_volume(self, volume):
-        """Create a volume on given nfs_share.
-        :param volume: volume reference
-        """
-        volume_path = self.local_path(volume)
-        volume_size = volume['size']
-
-        if self.configuration.nfs_sparsed_volumes:
-            self._create_sparsed_file(volume_path, volume_size)
-        else:
-            self._create_regular_file(volume_path, volume_size)
-
-        self._set_rw_permissions_for_all(volume_path)
-
-    def _ensure_shares_mounted(self):
-        """Look for NFS shares in the flags and tries to mount them locally."""
-        self._mounted_shares = []
-
-        self._load_shares_config(self.configuration.nfs_shares_config)
-
-        for share in self.shares.keys():
-            try:
-                self._ensure_share_mounted(share)
-                self._mounted_shares.append(share)
-            except Exception as exc:
-                LOG.warning(_('Exception during mounting %s') % (exc,))
-
-        LOG.debug('Available shares %s' % str(self._mounted_shares))
-
     def _ensure_share_mounted(self, nfs_share):
         mount_path = self._get_mount_point_for_share(nfs_share)
         self._mount_nfs(nfs_share, mount_path, ensure=True)
@@ -427,45 +497,4 @@ class NfsDriver(RemoteFsDriver):
             nfs_cmd.extend(self.shares[nfs_share].split())
         nfs_cmd.extend([nfs_share, mount_path])
 
-        try:
-            self._execute(*nfs_cmd, run_as_root=True)
-        except exception.ProcessExecutionError as exc:
-            if ensure and 'already mounted' in exc.stderr:
-                LOG.warn(_("%s is already mounted"), nfs_share)
-            else:
-                raise
-
-    def get_volume_stats(self, refresh=False):
-        """Get volume stats.
-
-        If 'refresh' is True, run update the stats first.
-        """
-        if refresh or not self._stats:
-            self._update_volume_stats()
-
-        return self._stats
-
-    def _update_volume_stats(self):
-        """Retrieve stats info from volume group."""
-
-        data = {}
-        backend_name = self.configuration.safe_get('volume_backend_name')
-        data["volume_backend_name"] = backend_name or 'Generic_NFS'
-        data["vendor_name"] = 'Open Source'
-        data["driver_version"] = VERSION
-        data["storage_protocol"] = 'nfs'
-
-        self._ensure_shares_mounted()
-
-        global_capacity = 0
-        global_free = 0
-        for nfs_share in self._mounted_shares:
-            capacity, free, allocated = self._get_capacity_info(nfs_share)
-            global_capacity += capacity
-            global_free += free
-
-        data['total_capacity_gb'] = global_capacity / float(units.GiB)
-        data['free_capacity_gb'] = global_free / float(units.GiB)
-        data['reserved_percentage'] = 0
-        data['QoS_support'] = False
-        self._stats = data
+        self._do_mount(nfs_cmd, ensure, nfs_share)