“The Volume class provides the abstraction layer required to perform all operations on an existing volume. Volume creation operations are carried out at the Backend level.
The base resource in storage is the volume, and to create one the cinderlib provides three different mechanisms, each one with a different method that will be called on the source of the new volume.
So we have:
Note
Cinder NFS backends will create an image and not a directory to store files, which falls in line with Cinder being a Block Storage provider and not filesystem provider like Manila is.
So assuming that we have an lvm variable holding an initialized Backend instance we could create a new 1GB volume quite easily:
print('Stats before creating the volume are:')
pprint(lvm.stats())
vol = lvm.create_volume(1)
print('Stats after creating the volume are:')
pprint(lvm.stats())
Now, if we have a volume that already contains data and we want to create a new volume that starts with the same contents we can use the source volume as the cloning source:
cloned_vol = vol.clone()
Some drivers support cloning to a bigger volume, so we could define the new size in the call and the driver would take care of extending the volume after cloning it, this is usually tightly linked to the extend operation support by the driver.
Cloning to a greater size would look like this:
new_size = vol.size + 1
cloned_bigger_volume = vol.clone(size=new_size)
Note
Cloning efficiency is directly linked to the storage backend in use, so it will not have the same performance in all backends. While some backends like the Ceph/RBD will be extremely efficient others may range from slow to being actually implemented as a dd operation performed by the driver attaching source and destination volumes.
vol = snap.create_volume()
Note
Just like with the cloning functionality, not all storage backends can efficiently handle creating a volume from a snapshot.
On volume creation we can pass additional parameters like a name or a description, but these will be irrelevant for the actual volume creation and will only be useful to us to easily identify our volumes or to store additional information.
Available fields with their types can be found in Cinder’s Volume OVO definition, but most of them are only relevant within the full Cinder service.
We can access these fields as if they were part of the cinderlib Volume instance, since the class will try to retrieve any non cinderlib Volume from Cinder’s internal OVO representation.
Some of the fields we could be interested in are:
Note
Cinderlib automatically generates a UUID for the id if one is not provided at volume creation time, but the caller can actually provide a specific id.
By default the id is limited to valid UUID and this is the only kind of ID that is guaranteed to work on all drivers. For drivers that support non UUID IDs we can instruct cinderlib to modify Cinder’s behavior and allow them. This is done on cinderlib initialization time passing non_uuid_ids=True.
Note
Cinderlib does not do scheduling on driver pools, so setting the extra_specs for a volume on drivers that expect the scheduler to select a specific pool using them will have the same behavior as in Cinder.
In that case the caller of Cinderlib is expected to go through the stats and check the pool that matches the criteria and pass it to the Backend’s create_volume method on the pool_name parameter.
Once we have created a Volume we can use its delete method to permanently remove it from the storage backend.
In Cinder there are safeguards to prevent a delete operation from completing if it has snapshots (unless the delete request comes with the cascade option set to true), but here in cinderlib we don’t, so it’s the callers responsibility to delete the snapshots.
Deleting a volume with snapshots doesn’t have a defined behavior for Cinder drivers, since it’s never meant to happen, so some storage backends delete the snapshots, other leave them as they were, and others will fail the request.
Example of creating and deleting a volume:
vol = lvm.create_volume(size=1)
vol.delete()
Attention
When deleting a volume that was the source of a cloning operation some backends cannot delete them (since they have copy-on-write clones) and they just keep them as a silent volume that will be deleted when its snapshot and clones are deleted.
Many storage backends and Cinder drivers support extending a volume to have more space and you can do this via the extend method present in your Volume instance.
If the Cinder driver doesn’t implement the extend operation it will raise a NotImplementedError.
The only parameter received by the extend method is the new size, and this must always be greater than the current value because cinderlib is not validating this at the moment.
Example of creating, extending, and deleting a volume:
vol = lvm.create_volume(size=1)
print('Vol %s has %s GBi' % (vol.id, vol.size))
vol.extend(2)
print('Extended vol %s has %s GBi' % (vol.id, vol.size))
vol.delete()
All other methods available in the Volume class will be explained in their relevant sections:
Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.