Drivers

Cinder exposes an API to users to interact with different storage backend solutions. The following are standards across all drivers for Cinder services to properly interact with a driver.

Basic attributes

There are some basic attributes that all drivers classes should have:

  • VERSION: Driver version in string format. No naming convention is imposed, although semantic versioning is recommended.

  • CI_WIKI_NAME: Must be the exact name of the ThirdPartySystems wiki page. This is used by our tooling system to associate jobs to drivers and track their CI reporting status correctly.

The tooling system will also use the name and docstring of the driver class.

Configuration options

Each driver requires different configuration options set in the cinder.conf file to operate, and due to the complexities of the Object Oriented programming mechanisms (inheritance, composition, overwriting, etc.) once your driver defines its parameters in the code Cinder has no automated way of telling which configuration options are relevant to your driver.

In order to assist operators and installation tools we recommend reporting the relevant options:

  • For operators: In the documentation under doc/source/configuration/block-storage.

  • For operators and installers: Through the get_driver_options static method returning that returns a list of all the Oslo Config parameters.

Minimum Features

Minimum features are enforced to avoid having a grid of what features are supported by which drivers and which releases. Cinder Core requires that all drivers implement the following minimum features.

Core Functionality

  • Volume Create/Delete

  • Volume Attach/Detach

  • Snapshot Create/Delete

  • Create Volume from Snapshot

  • Get Volume Stats

  • Copy Image to Volume

  • Copy Volume to Image

  • Clone Volume

  • Extend Volume

Security Requirements

  • Drivers must delete volumes in a way where volumes deleted from the backend will not leak data into new volumes when they are created. Cinder operates in multi-tenant environments and this is critical to ensure data safety.

  • Drivers should support secure TLS/SSL communication between the cinder volume service and the backend as configured by the “driver_ssl_cert_verify” and “driver_ssl_cert_path” options in cinder.conf.

  • Drivers should use standard Python libraries to handle encryption-related functionality, and not contain custom implementations of encryption code.

Volume Stats

Volume stats are used by the different schedulers for the drivers to provide a report on their current state of the backend. The following should be provided by a driver.

  • driver_version

  • free_capacity_gb

  • storage_protocol

  • total_capacity_gb

  • vendor_name

  • volume_backend_name

NOTE: If the driver is unable to provide a value for free_capacity_gb or total_capacity_gb, keywords can be provided instead. Please use ‘unknown’ if the backend cannot report the value or ‘infinite’ if the backend has no upper limit. But, it is recommended to report real values as the Cinder scheduler assigns lowest weight to any storage backend reporting ‘unknown’ or ‘infinite’.

NOTE: By default, Cinder assumes that the driver supports attached volume extending. If it doesn’t, it should report ‘online_extend_support=False’. Otherwise the scheduler will attempt to perform the operation, and may leave the volume in ‘error_extending’ state.

Value of storage_protocol is a single string representing the transport protocol used by the storage. Existing protocols are present in cinder.common.constants and should be used by drivers instead of string literals.

Variant values only exist for older drivers that were already reporting those values. New drivers must use non variant versions.

The storage_protocol can be used by operators using the cinder get-pools --detail command, by volume types in their extra specs, and by the filter and goodness functions.

We must not mistake the value of the storage_protocol with the identifier of the os-brick connector, which is returned by the initialize_connection driver method in the driver_volume_type dictionary key. In some cases they may have the same value, but they are different things.

Feature Enforcement

All concrete driver implementations should use the cinder.interface.volumedriver decorator on the driver class:

@interface.volumedriver
class LVMVolumeDriver(driver.VolumeDriver):

This will register the driver and allow automated compliance tests to run against and verify the compliance of the driver against the required interface to support the Core Functionality listed above.

Running tox -e compliance will verify all registered drivers comply to this interface. This can be used during development to perform self checks along the way. Any missing method calls will be identified by the compliance tests.

The details for the required volume driver interfaces can be found in the cinder/interface/volume_*_driver.py source.

New Driver Review Checklist

There are some common issues caught during the review of new driver patches that can easily be avoided. New driver maintainers should review the New Driver Review Checklist for some things to watch out for.

Driver Development Documentations

The LVM driver is our reference for all new driver implementations. The information below can provide additional documentation for the methods that volume drivers need to implement.

Volume ID

Drivers should always get a volume’s ID using the name_id attribute instead of the id attribute.

A Cinder volume may have two different UUIDs, a user facing one, and one the driver should use.

When a volume is created these two are the same, but when doing a generic migration (create new volume, then copying data) they will be different if we were unable to rename the new volume in the final migration steps.

So the volume will have been created using the new volume’s UUID and the driver will have to look for it using that UUID, but the user on the other hand will keep referencing the volume with the original UUID.

Base Driver Interface

The methods documented below are the minimum required interface for a volume driver to support. All methods from this interface must be implemented in order to be an official Cinder volume driver.

Core backend volume driver interface.

All backend drivers should support this interface as a bare minimum, but some methods (marked as optional in their description) can rely on the default implementation.

class VolumeDriverCore

Core backend driver required interface.

check_for_setup_error()

Validate there are no issues with the driver configuration.

Called after do_setup(). Driver initialization can occur there or in this call, but must be complete by the time this returns.

If this method raises an exception, the driver will be left in an “uninitialized” state by the volume manager, which means that it will not be sent requests for volume operations.

This method typically checks things like whether the configured credentials can be used to log in the storage backend, and whether any external dependencies are present and working.

Raises:

VolumeBackendAPIException – in case of setup error.

clone_image(context, volume, image_location, image_meta, image_service)

Create a volume efficiently from an existing image.

Drivers that, always or under some circumstances, can efficiently create a volume from a Glance image can implement this method to be given a chance to try to do the volume creation as efficiently as possible.

If the driver cannot do it efficiently on a specific call it can return (None, False) to let Cinder try other mechanisms.

This method is optional and most drivers won’t need to implement it and can leverage the default driver implementation that returns (None, False) to indicate that this optimization is not possible on this driver.

Examples where drivers can do this optimization:

  • When images are stored on the same storage system and the driver can locate them and efficiently create a volume. For example the RBD driver can efficiently create a volume if the image is stored on the same Ceph cluster and the image format is raw. Another example is the GPFS driver.

  • When volumes are locally accessible and accessing them that way is more efficient than going through the remote connection mechanism. For example in the GPFS driver if the cloning feature doesn’t work it will copy the file without using os-brick to connect to the volume.

Parameters:
  • context – Security/policy info for the request.

  • volume – The volume to create, as an OVO instance. Drivers should use attributes to access its values instead of using the dictionary compatibility interface it provides.

  • image_location – Tuple with (direct_url, locations) from the image metadata fields. direct_url, when present, is a string whose format depends on the image service’s external storage in use. Any, or both, tuple positions can be None, depending on the image service configuration. locations, when present, is a list of dictionaries where the value of the url key contains the direct urls (including the one from direct_url).

  • image_meta – Dictionary containing information about the image, including basic attributes and custom properties. Some transformations have been applied, such as converting timestamps (from created_at, updated_at, and deleted_at) to datetimes, and deserializing JSON values from block_device_mapping and mappings keys if present. Base properties, as per the image’s schema, will be stored on the base dictionary and the rest will be stored under the properties key. An important field to check in this method is the disk_format (e.g. raw, qcow2).

  • image_service – The image service to use (GlanceImageService instance). Can fetch image data directly using it.

Returns:

Tuple of (model_update, boolean) where the boolean specifies whether the clone occurred.

copy_image_to_volume(context, volume, image_service, image_id, disable_sparse=False)

Fetch the image from image_service and write it to the volume.

Parameters:
  • context – Security/policy info for the request.

  • volume – The volume to create.

  • image_service – The image service to use.

  • image_id – The image identifier.

  • disable_sparse – Enable or disable sparse copy. Default=False.

Returns:

Model updates.

copy_volume_to_image(context, volume, image_service, image_meta)

Copy the volume to the specified image.

Parameters:
  • context – Security/policy info for the request.

  • volume – The volume to copy.

  • image_service – The image service to use.

  • image_meta – Information about the image.

Returns:

Model updates.

create_snapshot(snapshot)

Creates a snapshot.

Parameters:

snapshot – Information for the snapshot to be created.

create_volume(volume)

Create a new volume on the backend.

This method is responsible only for storage allocation on the backend. It should not export a LUN or actually make this storage available for use, this is done in a later call.

TODO(smcginnis): Add example data structure of volume object.

Parameters:

volume – Volume object containing specifics to create.

Returns:

(Optional) dict of database updates for the new volume.

Raises:

VolumeBackendAPIException – if creation failed.

create_volume_from_snapshot(volume, snapshot)

Creates a volume from a snapshot.

If volume_type extra specs includes ‘replication: <is> True’ the driver needs to create a volume replica (secondary), and setup replication between the newly created volume and the secondary volume.

An optional larger size for the new volume can be specified. Drivers should check this value and create or expand the new volume to match.

Parameters:
  • volume – The volume to be created.

  • snapshot – The snapshot from which to create the volume.

Returns:

A dict of database updates for the new volume.

delete_snapshot(snapshot)

Deletes a snapshot.

Parameters:

snapshot – The snapshot to delete.

delete_volume(volume)

Delete a volume from the backend.

If the driver can talk to the backend and detects that the volume is no longer present, this call should succeed and allow Cinder to complete the process of deleting the volume.

It is imperative that this operation ensures that the data from the deleted volume cannot leak into new volumes when they are created, as new volumes are likely to belong to a different tenant/project.

Parameters:

volume – The volume to delete.

Raises:

VolumeIsBusy – if the volume is still attached or has snapshots. VolumeBackendAPIException on error.

do_setup(context)

Any initialization the volume driver needs to do while starting.

Called once by the manager after the driver is loaded. Can be used to set up clients, check licenses, set up protocol specific helpers, etc.

Parameters:

context – The admin context.

extend_volume(volume, new_size)

Extend the size of a volume.

Parameters:
  • volume – The volume to extend.

  • new_size – The new desired size of the volume.

Note that if the volume backend doesn’t support extending an in-use volume, the driver should report online_extend_support=False.

get_volume_stats(refresh=False)

Collects volume backend stats.

The get_volume_stats method is used by the volume manager to collect information from the driver instance related to information about the driver, available and used space, and driver/backend capabilities.

stats are stored in ‘self._stats’ field, which could be updated in ‘_update_volume_stats’ method.

It returns a dict with the following required fields:

  • volume_backend_name

    This is an identifier for the backend taken from cinder.conf. Useful when using multi-backend.

  • vendor_name

    Vendor/author of the driver who serves as the contact for the driver’s development and support.

  • driver_version

    The driver version is logged at cinder-volume startup and is useful for tying volume service logs to a specific release of the code. There are currently no rules for how or when this is updated, but it tends to follow typical major.minor.revision ideas.

  • storage_protocol

    The protocol used to connect to the storage, this should be a short string such as: “iSCSI”, “FC”, “NFS”, “ceph”, etc. Available protocols are present in cinder.common.constants and they must be used instead of string literals. Variant values only exist for older drivers that were already reporting those values. New drivers must use non variant versions. In some cases this may be the same value as the driver_volume_type returned by the initialize_connection method, but they are not the same thing, since this one is meant to be used by the scheduler, while the latter is the os-brick connector identifier used in the factory method.

  • total_capacity_gb

    The total capacity in gigabytes (GiB) of the storage backend being used to store Cinder volumes. Use keyword ‘unknown’ if the backend cannot report the value or ‘infinite’ if there is no upper limit. But, it is recommended to report real values as the Cinder scheduler assigns lowest weight to any storage backend reporting ‘unknown’ or ‘infinite’.

  • free_capacity_gb

    The free capacity in gigabytes (GiB). Use keyword ‘unknown’ if the backend cannot report the value or ‘infinite’ if there is no upper limit. But, it is recommended to report real values as the Cinder scheduler assigns lowest weight to any storage backend reporting ‘unknown’ or ‘infinite’.

And the following optional fields:

  • reserved_percentage (integer)

    Percentage of backend capacity which is not used by the scheduler.

  • location_info (string)

    Driver-specific information used by the driver and storage backend to correlate Cinder volumes and backend LUNs/files.

  • QoS_support (Boolean)

    Whether the backend supports quality of service.

  • provisioned_capacity_gb

    The total provisioned capacity on the storage backend, in gigabytes (GiB), including space consumed by any user other than Cinder itself.

  • max_over_subscription_ratio

    The maximum amount a backend can be over subscribed.

  • thin_provisioning_support (Boolean)

    Whether the backend is capable of allocating thinly provisioned volumes.

  • thick_provisioning_support (Boolean)

    Whether the backend is capable of allocating thick provisioned volumes. (Typically True.)

  • total_volumes (integer)

    Total number of volumes on the storage backend. This can be used in custom driver filter functions.

  • filter_function (string)

    A custom function used by the scheduler to determine whether a volume should be allocated to this backend or not. Example:

    capabilities.total_volumes < 10

  • goodness_function (string)

    Similar to filter_function, but used to weigh multiple volume backends. Example:

    capabilities.capacity_utilization < 0.6 ? 100 : 25

  • multiattach (Boolean)

    Whether the backend supports multiattach or not. Defaults to False.

  • sparse_copy_volume (Boolean)

    Whether copies performed by the volume manager for operations such as migration should attempt to preserve sparseness.

  • online_extend_support (Boolean)

    Whether the backend supports in-use volume extend or not. Defaults to True.

The returned dict may also contain a list, “pools”, which has a similar dict for each pool being used with the backend.

Parameters:

refresh – Whether to discard any cached values and force a full refresh of stats.

Returns:

dict of appropriate values (see above).

initialize_connection(volume, connector, initiator_data=None)

Allow connection to connector and return connection info.

Parameters:
  • volume – The volume to be attached.

  • connector – Dictionary containing information about what is being connected to.

  • initiator_data – (Optional) A dictionary of driver_initiator_data objects with key-value pairs that have been saved for this initiator by a driver in previous initialize_connection calls.

Returns:

A dictionary of connection information. This can optionally include a “initiator_updates” field.

The “initiator_updates” field must be a dictionary containing a “set_values” and/or “remove_values” field. The “set_values” field must be a dictionary of key-value pairs to be set/updated in the db. The “remove_values” field must be a list of keys, previously set with “set_values”, that will be deleted from the db.

May be called multiple times to get connection information after a volume has already been attached.

terminate_connection(volume, connector)

Remove access to a volume.

Note: If connector is None, then all connections to the volume should be terminated.

Parameters:
  • volume – The volume to remove.

  • connector – The Dictionary containing information about the connection. This is optional when doing a force-detach and can be None.

Manage/Unmanage Support

An optional feature a volume backend can support is the ability to manage existing volumes or unmanage volumes - keep the volume on the storage backend but no longer manage it through Cinder.

To support this functionality, volume drivers must implement these methods:

Manage/unmanage existing volume driver interface.

class VolumeListManageableDriver

Interface to support listing manageable snapshots and volumes.

get_manageable_snapshots(cinder_snapshots, marker, limit, offset, sort_keys, sort_dirs)

List snapshots on the backend available for management by Cinder.

Returns a list of dictionaries, each specifying a snapshot in the host, with the following keys:

  • reference (dictionary): The reference for a snapshot, which can be passed to “manage_existing_snapshot”.

  • size (int): The size of the snapshot according to the storage backend, rounded up to the nearest GB.

  • safe_to_manage (boolean): Whether or not this snapshot is safe to manage according to the storage backend. For example, is the snapshot in use or invalid for any reason.

  • reason_not_safe (string): If safe_to_manage is False, the reason why.

  • cinder_id (string): If already managed, provide the Cinder ID.

  • extra_info (string): Any extra information to return to the user

  • source_reference (string): Similar to “reference”, but for the snapshot’s source volume.

Parameters:
  • cinder_snapshots – A list of snapshots in this host that Cinder currently manages, used to determine if a snapshot is manageable or not.

  • marker – The last item of the previous page; we return the next results after this value (after sorting)

  • limit – Maximum number of items to return

  • offset – Number of items to skip after marker

  • sort_keys – List of keys to sort results by (valid keys are ‘identifier’ and ‘size’)

  • sort_dirs – List of directions to sort by, corresponding to sort_keys (valid directions are ‘asc’ and ‘desc’)

get_manageable_volumes(cinder_volumes, marker, limit, offset, sort_keys, sort_dirs)

List volumes on the backend available for management by Cinder.

Returns a list of dictionaries, each specifying a volume in the host, with the following keys:

  • reference (dictionary): The reference for a volume, which can be passed to “manage_existing”.

  • size (int): The size of the volume according to the storage backend, rounded up to the nearest GB.

  • safe_to_manage (boolean): Whether or not this volume is safe to manage according to the storage backend. For example, is the volume in use or invalid for any reason.

  • reason_not_safe (string): If safe_to_manage is False, the reason why.

  • cinder_id (string): If already managed, provide the Cinder ID.

  • extra_info (string): Any extra information to return to the user

Parameters:
  • cinder_volumes – A list of volumes in this host that Cinder currently manages, used to determine if a volume is manageable or not.

  • marker – The last item of the previous page; we return the next results after this value (after sorting)

  • limit – Maximum number of items to return

  • offset – Number of items to skip after marker

  • sort_keys – List of keys to sort results by (valid keys are ‘identifier’ and ‘size’)

  • sort_dirs – List of directions to sort by, corresponding to sort_keys (valid directions are ‘asc’ and ‘desc’)

class VolumeManagementDriver

Interface for drivers that support managing existing volumes.

manage_existing(volume, existing_ref)

Brings an existing backend storage object under Cinder management.

existing_ref is passed straight through from the API request’s manage_existing_ref value, and it is up to the driver how this should be interpreted. It should be sufficient to identify a storage object that the driver should somehow associate with the newly-created cinder volume structure.

There are two ways to do this:

  1. Rename the backend storage object so that it matches the, volume[‘name’] which is how drivers traditionally map between a cinder volume and the associated backend storage object.

  2. Place some metadata on the volume, or somewhere in the backend, that allows other driver requests (e.g. delete, clone, attach, detach…) to locate the backend storage object when required.

If the existing_ref doesn’t make sense, or doesn’t refer to an existing backend storage object, raise a ManageExistingInvalidReference exception.

The volume may have a volume_type, and the driver can inspect that and compare against the properties of the referenced backend storage object. If they are incompatible, raise a ManageExistingVolumeTypeMismatch, specifying a reason for the failure.

Parameters:
  • volume – Cinder volume to manage

  • existing_ref – Dictionary with keys ‘source-id’, ‘source-name’ with driver-specific values to identify a backend storage object.

Raises:
manage_existing_get_size(volume, existing_ref)

Return size of volume to be managed by manage_existing.

When calculating the size, round up to the next GB.

Parameters:
  • volume – Cinder volume to manage

  • existing_ref – Dictionary with keys ‘source-id’, ‘source-name’ with driver-specific values to identify a backend storage object.

Raises:

ManageExistingInvalidReference – If the existing_ref doesn’t make sense, or doesn’t refer to an existing backend storage object.

unmanage(volume)

Removes the specified volume from Cinder management.

Does not delete the underlying backend storage object.

For most drivers, this will not need to do anything. However, some drivers might use this call as an opportunity to clean up any Cinder-specific configuration that they have associated with the backend storage object.

Parameters:

volume – Cinder volume to unmanage

Manage/Unmanage Snapshot Support

In addition to the ability to manage and unmanage volumes, Cinder backend drivers may also support managing and unmanaging volume snapshots. These additional methods must be implemented to support these operations.

Manage/unmanage existing volume snapshots driver interface.

class VolumeSnapshotManagementDriver

Interface for drivers that support managing existing snapshots.

manage_existing_snapshot(snapshot, existing_ref)

Brings an existing backend storage object under Cinder management.

existing_ref is passed straight through from the API request’s manage_existing_ref value, and it is up to the driver how this should be interpreted. It should be sufficient to identify a storage object that the driver should somehow associate with the newly-created cinder snapshot structure.

There are two ways to do this:

  1. Rename the backend storage object so that it matches the snapshot[‘name’] which is how drivers traditionally map between a cinder snapshot and the associated backend storage object.

  2. Place some metadata on the snapshot, or somewhere in the backend, that allows other driver requests (e.g. delete) to locate the backend storage object when required.

Parameters:
  • snapshot – The snapshot to manage.

  • existing_ref – Dictionary with keys ‘source-id’, ‘source-name’ with driver-specific values to identify a backend storage object.

Raises:

ManageExistingInvalidReference – If the existing_ref doesn’t make sense, or doesn’t refer to an existing backend storage object.

manage_existing_snapshot_get_size(snapshot, existing_ref)

Return size of snapshot to be managed by manage_existing.

When calculating the size, round up to the next GB.

Parameters:
  • snapshot – The snapshot to manage.

  • existing_ref – Dictionary with keys ‘source-id’, ‘source-name’ with driver-specific values to identify a backend storage object.

Raises:

ManageExistingInvalidReference – If the existing_ref doesn’t make sense, or doesn’t refer to an existing backend storage object.

unmanage_snapshot(snapshot)

Removes the specified snapshot from Cinder management.

Does not delete the underlying backend storage object.

For most drivers, this will not need to do anything. However, some drivers might use this call as an opportunity to clean up any Cinder-specific configuration that they have associated with the backend storage object.

Parameters:

snapshot – The snapshot to unmanage.

Volume Consistency Groups

Some storage backends support the ability to group volumes and create write consistent snapshots across the group. In order to support these operations, the following interface must be implemented by the driver.

Consistency group volume driver interface.

class VolumeConsistencyGroupDriver

Interface for drivers that support consistency groups.

create_cgsnapshot(context, cgsnapshot, snapshots)

Creates a cgsnapshot.

Parameters:
  • context – the context of the caller.

  • cgsnapshot – the dictionary of the cgsnapshot to be created.

  • snapshots – a list of snapshot dictionaries in the cgsnapshot.

Returns:

model_update, snapshots_model_update

param snapshots is retrieved directly from the db. It is a list of cinder.db.sqlalchemy.models.Snapshot to be precise. It cannot be assigned to snapshots_model_update. snapshots_model_update is a list of dictionaries. It has to be built by the driver. An entry will be in this format: {‘id’: xxx, ‘status’: xxx, ……}. model_update will be in this format: {‘status’: xxx, ……}.

The driver should populate snapshots_model_update and model_update and return them.

The manager will check snapshots_model_update and update db accordingly for each snapshot. If the driver successfully deleted some snapshots but failed to delete others, it should set statuses of the snapshots accordingly so that the manager can update db correctly.

If the status in any entry of snapshots_model_update is ‘error’, the status in model_update will be set to the same if it is not already ‘error’.

If the status in model_update is ‘error’, the manager will raise an exception and the status of cgsnapshot will be set to ‘error’ in the db. If snapshots_model_update is not returned by the driver, the manager will set the status of every snapshot to ‘error’ in the except block.

If the driver raises an exception during the operation, it will be caught by the try-except block in the manager and the statuses of cgsnapshot and all snapshots will be set to ‘error’.

For a successful operation, the driver can either build the model_update and snapshots_model_update and return them or return None, None. The statuses of cgsnapshot and all snapshots will be set to ‘available’ at the end of the manager function.

create_consistencygroup(context, group)

Creates a consistencygroup.

Parameters:
  • context – the context of the caller.

  • group – the dictionary of the consistency group to be created.

Returns:

model_update

model_update will be in this format: {‘status’: xxx, ……}.

If the status in model_update is ‘error’, the manager will throw an exception and it will be caught in the try-except block in the manager. If the driver throws an exception, the manager will also catch it in the try-except block. The group status in the db will be changed to ‘error’.

For a successful operation, the driver can either build the model_update and return it or return None. The group status will be set to ‘available’.

create_consistencygroup_from_src(context, group, volumes, cgsnapshot=None, snapshots=None, source_cg=None, source_vols=None)

Creates a consistencygroup from source.

Parameters:
  • context – the context of the caller.

  • group – the dictionary of the consistency group to be created.

  • volumes – a list of volume dictionaries in the group.

  • cgsnapshot – the dictionary of the cgsnapshot as source.

  • snapshots – a list of snapshot dictionaries in the cgsnapshot.

  • source_cg – the dictionary of a consistency group as source.

  • source_vols – a list of volume dictionaries in the source_cg.

Returns:

model_update, volumes_model_update

The source can be cgsnapshot or a source cg.

param volumes is retrieved directly from the db. It is a list of cinder.db.sqlalchemy.models.Volume to be precise. It cannot be assigned to volumes_model_update. volumes_model_update is a list of dictionaries. It has to be built by the driver. An entry will be in this format: {‘id’: xxx, ‘status’: xxx, ……}. model_update will be in this format: {‘status’: xxx, ……}.

To be consistent with other volume operations, the manager will assume the operation is successful if no exception is thrown by the driver. For a successful operation, the driver can either build the model_update and volumes_model_update and return them or return None, None.

delete_cgsnapshot(context, cgsnapshot, snapshots)

Deletes a cgsnapshot.

Parameters:
  • context – the context of the caller.

  • cgsnapshot – the dictionary of the cgsnapshot to be deleted.

  • snapshots – a list of snapshot dictionaries in the cgsnapshot.

Returns:

model_update, snapshots_model_update

param snapshots is retrieved directly from the db. It is a list of cinder.db.sqlalchemy.models.Snapshot to be precise. It cannot be assigned to snapshots_model_update. snapshots_model_update is a list of dictionaries. It has to be built by the driver. An entry will be in this format: {‘id’: xxx, ‘status’: xxx, ……}. model_update will be in this format: {‘status’: xxx, ……}.

The driver should populate snapshots_model_update and model_update and return them.

The manager will check snapshots_model_update and update db accordingly for each snapshot. If the driver successfully deleted some snapshots but failed to delete others, it should set statuses of the snapshots accordingly so that the manager can update db correctly.

If the status in any entry of snapshots_model_update is ‘error_deleting’ or ‘error’, the status in model_update will be set to the same if it is not already ‘error_deleting’ or ‘error’.

If the status in model_update is ‘error_deleting’ or ‘error’, the manager will raise an exception and the status of cgsnapshot will be set to ‘error’ in the db. If snapshots_model_update is not returned by the driver, the manager will set the status of every snapshot to ‘error’ in the except block.

If the driver raises an exception during the operation, it will be caught by the try-except block in the manager and the statuses of cgsnapshot and all snapshots will be set to ‘error’.

For a successful operation, the driver can either build the model_update and snapshots_model_update and return them or return None, None. The statuses of cgsnapshot and all snapshots will be set to ‘deleted’ after the manager deletes them from db.

delete_consistencygroup(context, group, volumes)

Deletes a consistency group.

Parameters:
  • context – the context of the caller.

  • group – the dictionary of the consistency group to be deleted.

  • volumes – a list of volume dictionaries in the group.

Returns:

model_update, volumes_model_update

param volumes is retrieved directly from the db. It is a list of cinder.db.sqlalchemy.models.Volume to be precise. It cannot be assigned to volumes_model_update. volumes_model_update is a list of dictionaries. It has to be built by the driver. An entry will be in this format: {‘id’: xxx, ‘status’: xxx, ……}. model_update will be in this format: {‘status’: xxx, ……}.

The driver should populate volumes_model_update and model_update and return them.

The manager will check volumes_model_update and update db accordingly for each volume. If the driver successfully deleted some volumes but failed to delete others, it should set statuses of the volumes accordingly so that the manager can update db correctly.

If the status in any entry of volumes_model_update is ‘error_deleting’ or ‘error’, the status in model_update will be set to the same if it is not already ‘error_deleting’ or ‘error’.

If the status in model_update is ‘error_deleting’ or ‘error’, the manager will raise an exception and the status of the group will be set to ‘error’ in the db. If volumes_model_update is not returned by the driver, the manager will set the status of every volume in the group to ‘error’ in the except block.

If the driver raises an exception during the operation, it will be caught by the try-except block in the manager. The statuses of the group and all volumes in it will be set to ‘error’.

For a successful operation, the driver can either build the model_update and volumes_model_update and return them or return None, None. The statuses of the group and all volumes will be set to ‘deleted’ after the manager deletes them from db.

update_consistencygroup(context, group, add_volumes=None, remove_volumes=None)

Updates a consistency group.

Parameters:
  • context – the context of the caller.

  • group – the dictionary of the consistency group to be updated.

  • add_volumes – a list of volume dictionaries to be added.

  • remove_volumes – a list of volume dictionaries to be removed.

Returns:

model_update, add_volumes_update, remove_volumes_update

model_update is a dictionary that the driver wants the manager to update upon a successful return. If None is returned, the manager will set the status to ‘available’.

add_volumes_update and remove_volumes_update are lists of dictionaries that the driver wants the manager to update upon a successful return. Note that each entry requires a {‘id’: xxx} so that the correct volume entry can be updated. If None is returned, the volume will remain its original status. Also note that you cannot directly assign add_volumes to add_volumes_update as add_volumes is a list of cinder.db.sqlalchemy.models.Volume objects and cannot be used for db update directly. Same with remove_volumes.

If the driver throws an exception, the status of the group as well as those of the volumes to be added/removed will be set to ‘error’.

Generic Volume Groups

The generic volume groups feature provides the ability to manage a group of volumes together. Because this feature is implemented at the manager level, every driver gets this feature by default. If a driver wants to override the default behavior to support additional functionalities such as consistent group snapshot, the following interface must be implemented by the driver. Once every driver supporting volume consistency groups has added the consistent group snapshot capability to generic volume groups, we no longer need the volume consistency groups interface listed above.

Generic volume group volume driver interface.

class VolumeGroupDriver

Interface for drivers that support groups.

create_group(context, group)

Creates a group.

Parameters:
  • context – the context of the caller.

  • group – the Group object to be created.

Returns:

model_update

model_update will be in this format: {‘status’: xxx, ……}.

If the status in model_update is ‘error’, the manager will throw an exception and it will be caught in the try-except block in the manager. If the driver throws an exception, the manager will also catch it in the try-except block. The group status in the db will be changed to ‘error’.

For a successful operation, the driver can either build the model_update and return it or return None. The group status will be set to ‘available’.

create_group_from_src(context, group, volumes, group_snapshot=None, snapshots=None, source_group=None, source_vols=None)

Creates a group from source.

Parameters:
  • context – the context of the caller.

  • group – the Group object to be created.

  • volumes – a list of Volume objects in the group.

  • group_snapshot – the GroupSnapshot object as source.

  • snapshots – a list of Snapshot objects in the group_snapshot.

  • source_group – a Group object as source.

  • source_vols – a list of Volume objects in the source_group.

Returns:

model_update, volumes_model_update

The source can be group_snapshot or a source group.

param volumes is a list of objects retrieved from the db. It cannot be assigned to volumes_model_update. volumes_model_update is a list of dictionaries. It has to be built by the driver. An entry will be in this format: {‘id’: xxx, ‘status’: xxx, ……}. model_update will be in this format: {‘status’: xxx, ……}.

To be consistent with other volume operations, the manager will assume the operation is successful if no exception is thrown by the driver. For a successful operation, the driver can either build the model_update and volumes_model_update and return them or return None, None.

create_group_snapshot(context, group_snapshot, snapshots)

Creates a group_snapshot.

Parameters:
  • context – the context of the caller.

  • group_snapshot – the GroupSnapshot object to be created.

  • snapshots – a list of Snapshot objects in the group_snapshot.

Returns:

model_update, snapshots_model_update

param snapshots is a list of Snapshot objects. It cannot be assigned to snapshots_model_update. snapshots_model_update is a list of dictionaries. It has to be built by the driver. An entry will be in this format: {‘id’: xxx, ‘status’: xxx, ……}. model_update will be in this format: {‘status’: xxx, ……}.

The driver should populate snapshots_model_update and model_update and return them.

The manager will check snapshots_model_update and update db accordingly for each snapshot. If the driver successfully deleted some snapshots but failed to delete others, it should set statuses of the snapshots accordingly so that the manager can update db correctly.

If the status in any entry of snapshots_model_update is ‘error’, the status in model_update will be set to the same if it is not already ‘error’.

If the status in model_update is ‘error’, the manager will raise an exception and the status of group_snapshot will be set to ‘error’ in the db. If snapshots_model_update is not returned by the driver, the manager will set the status of every snapshot to ‘error’ in the except block.

If the driver raises an exception during the operation, it will be caught by the try-except block in the manager and the statuses of group_snapshot and all snapshots will be set to ‘error’.

For a successful operation, the driver can either build the model_update and snapshots_model_update and return them or return None, None. The statuses of group_snapshot and all snapshots will be set to ‘available’ at the end of the manager function.

delete_group(context, group, volumes)

Deletes a group.

Parameters:
  • context – the context of the caller.

  • group – the Group object to be deleted.

  • volumes – a list of Volume objects in the group.

Returns:

model_update, volumes_model_update

param volumes is a list of objects retrieved from the db. It cannot be assigned to volumes_model_update. volumes_model_update is a list of dictionaries. It has to be built by the driver. An entry will be in this format: {‘id’: xxx, ‘status’: xxx, ……}. model_update will be in this format: {‘status’: xxx, ……}.

The driver should populate volumes_model_update and model_update and return them.

The manager will check volumes_model_update and update db accordingly for each volume. If the driver successfully deleted some volumes but failed to delete others, it should set statuses of the volumes accordingly so that the manager can update db correctly.

If the status in any entry of volumes_model_update is ‘error_deleting’ or ‘error’, the status in model_update will be set to the same if it is not already ‘error_deleting’ or ‘error’.

If the status in model_update is ‘error_deleting’ or ‘error’, the manager will raise an exception and the status of the group will be set to ‘error’ in the db. If volumes_model_update is not returned by the driver, the manager will set the status of every volume in the group to ‘error’ in the except block.

If the driver raises an exception during the operation, it will be caught by the try-except block in the manager. The statuses of the group and all volumes in it will be set to ‘error’.

For a successful operation, the driver can either build the model_update and volumes_model_update and return them or return None, None. The statuses of the group and all volumes will be set to ‘deleted’ after the manager deletes them from db.

delete_group_snapshot(context, group_snapshot, snapshots)

Deletes a group_snapshot.

Parameters:
  • context – the context of the caller.

  • group_snapshot – the GroupSnapshot object to be deleted.

  • snapshots – a list of Snapshot objects in the group_snapshot.

Returns:

model_update, snapshots_model_update

param snapshots is a list of objects. It cannot be assigned to snapshots_model_update. snapshots_model_update is a list of of dictionaries. It has to be built by the driver. An entry will be in this format: {‘id’: xxx, ‘status’: xxx, ……}. model_update will be in this format: {‘status’: xxx, ……}.

The driver should populate snapshots_model_update and model_update and return them.

The manager will check snapshots_model_update and update db accordingly for each snapshot. If the driver successfully deleted some snapshots but failed to delete others, it should set statuses of the snapshots accordingly so that the manager can update db correctly.

If the status in any entry of snapshots_model_update is ‘error_deleting’ or ‘error’, the status in model_update will be set to the same if it is not already ‘error_deleting’ or ‘error’.

If the status in model_update is ‘error_deleting’ or ‘error’, the manager will raise an exception and the status of group_snapshot will be set to ‘error’ in the db. If snapshots_model_update is not returned by the driver, the manager will set the status of every snapshot to ‘error’ in the except block.

If the driver raises an exception during the operation, it will be caught by the try-except block in the manager and the statuses of group_snapshot and all snapshots will be set to ‘error’.

For a successful operation, the driver can either build the model_update and snapshots_model_update and return them or return None, None. The statuses of group_snapshot and all snapshots will be set to ‘deleted’ after the manager deletes them from db.

update_group(context, group, add_volumes=None, remove_volumes=None)

Updates a group.

Parameters:
  • context – the context of the caller.

  • group – the Group object to be updated.

  • add_volumes – a list of Volume objects to be added.

  • remove_volumes – a list of Volume objects to be removed.

Returns:

model_update, add_volumes_update, remove_volumes_update

model_update is a dictionary that the driver wants the manager to update upon a successful return. If None is returned, the manager will set the status to ‘available’.

add_volumes_update and remove_volumes_update are lists of dictionaries that the driver wants the manager to update upon a successful return. Note that each entry requires a {‘id’: xxx} so that the correct volume entry can be updated. If None is returned, the volume will remain its original status. Also note that you cannot directly assign add_volumes to add_volumes_update as add_volumes is a list of volume objects and cannot be used for db update directly. Same with remove_volumes.

If the driver throws an exception, the status of the group as well as those of the volumes to be added/removed will be set to ‘error’.

Revert To Snapshot

Some storage backends support the ability to revert a volume to the last snapshot. To support snapshot revert, the following interface must be implemented by the driver.

Revert to snapshot capable volume driver interface.

class VolumeSnapshotRevertDriver

Interface for drivers that support revert to snapshot.

revert_to_snapshot(context, volume, snapshot)

Revert volume to snapshot.

Note: the revert process should not change the volume’s current size, that means if the driver shrank the volume during the process, it should extend the volume internally.

Parameters:
  • context – the context of the caller.

  • volume – The volume to be reverted.

  • snapshot – The snapshot used for reverting.