Support pool-aware drivers
This patch adds pool support to cinderlib. The Backend class now has the property `pool_names` with available pools in the driver. When creating a volume we can specify `pool_name` to use a specific pool. Pool is stored as part of the `host` field in volumes. The `host` field now follows Cinder's naming "host@backend#pool".
This commit is contained in:
parent
09abcf4df4
commit
c491c71f47
|
@ -13,6 +13,7 @@ History
|
|||
|
||||
- Provide better message when device is not available.
|
||||
- Backend name stored in host instead of in the AZ (backward incompatible).
|
||||
- Support multi-pool drivers.
|
||||
|
||||
0.2.2 (2018-07-24)
|
||||
------------------
|
||||
|
|
|
@ -76,6 +76,14 @@ class Backend(object):
|
|||
self.driver.set_initialized()
|
||||
self._driver_cfg = driver_cfg
|
||||
self._volumes = None
|
||||
# init_capabilities already calls get_volume_stats with refresh=True
|
||||
# so we can call it without refresh to get pool names.
|
||||
self._pool_names = tuple(pool['pool_name']
|
||||
for pool in self.get_volume_stats()['pools'])
|
||||
|
||||
@property
|
||||
def pool_names(self):
|
||||
return self._pool_names
|
||||
|
||||
def __repr__(self):
|
||||
return '<cinderlib.Backend %s>' % self.id
|
||||
|
|
|
@ -275,17 +275,16 @@ class Volume(NamedObject):
|
|||
|
||||
_ignore_keys = ('id', CONNECTIONS_OVO_FIELD, 'snapshots')
|
||||
|
||||
def __init__(self, backend_or_vol, **kwargs):
|
||||
def __init__(self, backend_or_vol, pool_name=None, **kwargs):
|
||||
# Accept backend name for convenience
|
||||
if isinstance(backend_or_vol, six.string_types):
|
||||
kwargs.setdefault('host',
|
||||
'%s@%s' % (CONFIGURED_HOST, backend_or_vol))
|
||||
backend_name = backend_or_vol
|
||||
backend_or_vol = self._get_backend(backend_or_vol)
|
||||
elif isinstance(backend_or_vol, self.backend_class):
|
||||
kwargs.setdefault('host',
|
||||
'%s@%s' % (CONFIGURED_HOST, backend_or_vol.id))
|
||||
# Accept a volume as additional source data
|
||||
backend_name = backend_or_vol.id
|
||||
elif isinstance(backend_or_vol, Volume):
|
||||
backend_name, pool = backend_or_vol._ovo.host.split('#')
|
||||
pool_name = pool_name or pool
|
||||
for key in backend_or_vol._ovo.fields:
|
||||
if (backend_or_vol._ovo.obj_attr_is_set(key) and
|
||||
key not in self._ignore_keys):
|
||||
|
@ -307,6 +306,13 @@ class Volume(NamedObject):
|
|||
self._populate_data()
|
||||
self.local_attach = None
|
||||
|
||||
# If we overwrote the host, then we ignore pool_name and don't set a
|
||||
# default value or copy the one from the source either.
|
||||
if 'host' not in kwargs and '__ovo' not in kwargs:
|
||||
pool_name = pool_name or backend_or_vol.pool_names[0]
|
||||
self._ovo.host = ('%s@%s#%s' %
|
||||
(CONFIGURED_HOST, backend_name, pool_name))
|
||||
|
||||
if qos_specs or extra_specs:
|
||||
if qos_specs:
|
||||
qos_specs = cinder_objs.QualityOfServiceSpecs(
|
||||
|
|
|
@ -253,4 +253,9 @@ relevant sections:
|
|||
|
||||
- `global_setup` has been covered in the :doc:`initialization` section.
|
||||
|
||||
- `pool_names` tuple with all the pools available in the driver. Non pool
|
||||
aware drivers will have only 1 pool and use the name of the backend as its
|
||||
name. Pool aware drivers may report multiple values, which can be passed to
|
||||
the `create_volume` method in the `pool_name` parameter.
|
||||
|
||||
.. _OpenStack's Cinder volume driver configuration documentation: https://docs.openstack.org/cinder/latest/configuration/block-storage/volume-drivers.html
|
||||
|
|
|
@ -109,9 +109,15 @@ Some of the fields we could be interested in are:
|
|||
|
||||
- `host`: Used to store the backend name information together with the host
|
||||
name where cinderlib is running. This information is stored as a string in
|
||||
the form of *host@backend*. This is an optional parameter, and passing it to
|
||||
`create_volume` will override default value. Issues will arise if parameter
|
||||
doesn't contain correct information.
|
||||
the form of *host@backend#pool*. This is an optional parameter, and passing
|
||||
it to `create_volume` will override default value, allowing us caller to
|
||||
request a specific pool for multi-pool backends, though we recommend using
|
||||
the `pool_name` parameter instead. Issues will arise if parameter doesn't
|
||||
contain correct information.
|
||||
|
||||
- `pool_name`: Pool name to use when creating the volume. Default is to use
|
||||
the first or only pool. To know possible values for a backend use the
|
||||
`pool_names` property on the *Backend* instance.
|
||||
|
||||
- `size`: Volume size in GBi.
|
||||
|
||||
|
|
|
@ -24,3 +24,4 @@ class FakeBackend(cinderlib.Backend):
|
|||
cinderlib.Backend.backends[driver_name] = self
|
||||
self._driver_cfg = {'volume_backend_name': driver_name}
|
||||
self.driver = mock.Mock()
|
||||
self._pool_names = (driver_name,)
|
||||
|
|
Loading…
Reference in New Issue