Merge "Add basic workflow of attach/detach to devref"
This commit is contained in:
commit
18229c4c68
171
doc/source/devref/attach_detach_conventions.rst
Normal file
171
doc/source/devref/attach_detach_conventions.rst
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
..
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
Volume Attach/Detach workflow
|
||||||
|
=============================
|
||||||
|
|
||||||
|
There are six API calls associated with attach/detach of volumes in Cinder
|
||||||
|
(3 calls for each operation). This can lead to some confusion for developers
|
||||||
|
trying to work on Cinder. The convention is actually quite simple, although
|
||||||
|
it may be difficult to decipher from the code.
|
||||||
|
|
||||||
|
|
||||||
|
Attach/Detach Operations are mulit-part commands
|
||||||
|
================================================
|
||||||
|
|
||||||
|
There are three things that happen in the workflow for an attach or detach call.
|
||||||
|
1. Update the status of the volume in the DB (ie attaching/detaching)
|
||||||
|
- For Attach, this is the cinder.volume.api.reserve method
|
||||||
|
- For Detach, the analagous call is cinder.volume.api.begin_detaching
|
||||||
|
|
||||||
|
2. Handle the connection operations that need to be done on the Volume
|
||||||
|
- For Attach, this is the cinder.volume.api.initialize_connection method
|
||||||
|
- For Detach, the analagous calls is cinder.volume.api.terminate_connection
|
||||||
|
|
||||||
|
3. Finalize the status of the volume and release the resource
|
||||||
|
- For attach, this is the cinder.volume.api.attach method
|
||||||
|
- For detach, the analagous call is cinder.volume.api.detach
|
||||||
|
|
||||||
|
Attach workflow
|
||||||
|
===============
|
||||||
|
|
||||||
|
reserve_volume(self, context, volume)
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
Probably the most simple call in to Cinder. This method simply checks that
|
||||||
|
the specified volume is in an “available” state and can be attached.
|
||||||
|
Any other state results in an Error response notifying Nova that the volume
|
||||||
|
is NOT available. The only valid state for this call to succeed is “available”.
|
||||||
|
|
||||||
|
NOTE: multi-attach will add "in-use" to the above acceptable states.
|
||||||
|
|
||||||
|
If the volume is in fact available, we immediately issue an update to the Cinder
|
||||||
|
database and mark the status of the volume to “attaching” thereby reserving the
|
||||||
|
volume so that it won’t be used by another API call anywhere else.
|
||||||
|
|
||||||
|
initialize_connection(self, context, volume, connector)
|
||||||
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
This is the only attach related API call that should be doing any significant
|
||||||
|
work. This method is responsible for building and returning all of the info
|
||||||
|
needed by the caller (Nova) to actually attach the specified volume to the
|
||||||
|
remote node. This method returns vital information to the caller that includes
|
||||||
|
things like CHAP credential, iqn and lun information. An example response is
|
||||||
|
shown here:
|
||||||
|
|
||||||
|
::
|
||||||
|
{‘driver_volume_type': ‘iscsi’, ‘data': {‘auth_password': ‘YZ2Hceyh7VySh5HY’,
|
||||||
|
‘target_discovered': False,
|
||||||
|
‘encrypted': False,
|
||||||
|
‘qos_specs': None,
|
||||||
|
‘target_iqn': ‘iqn.2010-10.org.openstack:volume-8b1ec3fe-8c5
|
||||||
|
‘target_portal': ‘11.0.0.8:3260′,
|
||||||
|
‘volume_id': ‘8b1ec3fe-8c57-45ca-a1cf-a481bfc8fce2′,
|
||||||
|
‘target_lun': 1,
|
||||||
|
‘access_mode': ‘rw’,
|
||||||
|
‘auth_username': ‘nE9PY8juynmmZ95F7Xb7′,
|
||||||
|
‘auth_method': ‘CHAP’}}``
|
||||||
|
|
||||||
|
In the process of building this data structure, the Cinder Volume Manager makes a number of
|
||||||
|
calls to the backend driver, and builds a volume_attachment entry in the database to store
|
||||||
|
the connection information passed in via the connector object.
|
||||||
|
|
||||||
|
driver.validate_connector
|
||||||
|
*************************
|
||||||
|
|
||||||
|
Simply verifies that the initiator data is included in the passed in
|
||||||
|
connector (there are some drivers that utilize pieces of this connector
|
||||||
|
data, but in the case of the reference, it just verifies it's there).
|
||||||
|
|
||||||
|
driver.create_export
|
||||||
|
********************
|
||||||
|
|
||||||
|
This is the target specific, persistent data associated with a volume.
|
||||||
|
This method is responsible for building an actual iSCSI target, and
|
||||||
|
providing the "location" and "auth" information which will be used to
|
||||||
|
form the response data in the parent request.
|
||||||
|
We call this infor the model_update and it's used to update vital target
|
||||||
|
information associated with the volume in the Cinder database.
|
||||||
|
|
||||||
|
driver.intialize_connection
|
||||||
|
***************************
|
||||||
|
|
||||||
|
Now that we've actually built a target and persisted the important
|
||||||
|
bits of information associated with it, we're ready to actually assign
|
||||||
|
the target to a volume and form the needed info to pass back out
|
||||||
|
to our caller. This is where we finally put everything together and
|
||||||
|
form the example data structure response shown earlier.
|
||||||
|
|
||||||
|
This method is sort of deceptive, it does a whole lot of formatting
|
||||||
|
of the data we've put together in the create_export call, but it doesn't
|
||||||
|
really offer any new info. It's completely dependent on the information
|
||||||
|
that was gathered in the create_export call and put into the database. At
|
||||||
|
this point, all we're doing is taking all the various entries from the database
|
||||||
|
and putting it together into the desired format/structure.
|
||||||
|
|
||||||
|
The key method call for updating and obtaining all of this info was
|
||||||
|
done by the create_export call. This formatted data is then passed
|
||||||
|
back up to the API and returned as the response back out to Nova.
|
||||||
|
|
||||||
|
At this point, we return attach info to the caller that provides everything
|
||||||
|
needed to make the remote iSCSI connection.
|
||||||
|
|
||||||
|
attach(self, context, volume, instance_uuid, host_name, mount_point, mode)
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
This is the last call that *should* be pretty simple. The intent is that this
|
||||||
|
is simply used to finalize the attach process. In other words, we simply
|
||||||
|
update the status on the Volume in the database, and provide a mechanism to
|
||||||
|
notify the driver that the attachment has completed succesfully.
|
||||||
|
|
||||||
|
There's some additional information that has been added to this finalize call
|
||||||
|
over time like instance_uuid, host_name etc. Some of these are only provided
|
||||||
|
during the actual attach call and may be desired for some drivers for one
|
||||||
|
reason or another.
|
||||||
|
|
||||||
|
|
||||||
|
Detach workflow
|
||||||
|
===============
|
||||||
|
|
||||||
|
begin_detaching(self, context, volume)
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Analagous to the Attach workflows ``reserve_volume`` method.
|
||||||
|
Performs a simple conditional update of Volume status to ``detaching``.
|
||||||
|
|
||||||
|
|
||||||
|
terminate_connection(self, context, volume, connector, force=False)
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Analagous to the Attach workflows ``initialize_connection`` method.
|
||||||
|
|
||||||
|
Used to send calls down to drivers/target-drivers to do any sort of cleanup
|
||||||
|
they might require.
|
||||||
|
|
||||||
|
For most this is a noop, as connections and **iscsi session management is the
|
||||||
|
responsibility of the initiator**. HOWEVER, there are a number of special
|
||||||
|
cases here, particularly for target-drivers like LIO that use
|
||||||
|
access-groups, in those cases they remove the initiator from the access
|
||||||
|
list during this call which effectively closes sessions from the target
|
||||||
|
side.
|
||||||
|
|
||||||
|
|
||||||
|
detach(self, context, volume, attachment_id)
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
The final update to the DB and yet another opportunity to pass something
|
||||||
|
down to the volume-driver. Initially a simple call-back that now has quite
|
||||||
|
a bit of cruft built up in the volume-manager.
|
||||||
|
|
||||||
|
For drivers like LVM this again is a noop and just updates the db entry to
|
||||||
|
mark things as complete and set the volume to available again.
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user