cinder volume
备注:
为方便源码阅读, 列出的部分的源码将被省略, 如需要阅读完整代码, 建议在官网进行下载
cinder实现相对比较简单
基本结构:
- api --> volume API --> db
- api --> volume API --> rpc --> volume manager --> drivers
API 入口
目前cinder 已经更新到v3版本, 因此源码阅读的时候, api入口从v3开始
volume卷 api定义在 cinder/api/v3/volumes.py
class VolumeController(volumes_v2.VolumeController):
"""The Volumes API controller for the OpenStack API V3."""
v3继承v2的功能
目前v3已经更新了v2版本的create
源码如下
@wsgi.response(202)
def create(self, req, body):
"""Creates a new volume.
:param req: the request
:param body: the request body
:returns: dict -- the new volume dictionary
:raises: HTTPNotFound, HTTPBadRequest
"""
self.assert_valid_body(body, 'volume')
LOG.debug('Create volume request body: %s', body)
context = req.environ['cinder.context']
# 获取并校验参数
req_version = req.api_version_request
# Remove group_id from body if max version is less than 3.13.
....
volume = body['volume']
kwargs = {}
self.validate_name_and_description(volume)
# NOTE(thingee): v2 API allows name instead of display_name
if 'name' in volume:
volume['display_name'] = volume.pop('name')
# NOTE(thingee): v2 API allows description instead of
# display_description
if 'description' in volume:
volume['display_description'] = volume.pop('description')
# image镜像进行创建
if 'image_id' in volume:
volume['imageRef'] = volume.pop('image_id')
# volume 类型
req_volume_type = volume.get('volume_type', None)
if req_volume_type:
# Not found exception will be handled at the wsgi level
if not uuidutils.is_uuid_like(req_volume_type):
kwargs['volume_type'] = (
volume_types.get_volume_type_by_name(
context, req_volume_type))
else:
kwargs['volume_type'] = volume_types.get_volume_type(
context, req_volume_type)
kwargs['metadata'] = volume.get('metadata', None)
# 从快照创建
snapshot_id = volume.get('snapshot_id')
if snapshot_id is not None:
# Not found exception will be handled at the wsgi level
kwargs['snapshot'] = self.volume_api.get_snapshot(context,
snapshot_id)
else:
kwargs['snapshot'] = None
source_volid = volume.get('source_volid')
if source_volid is not None:
# Not found exception will be handled at the wsgi level
kwargs['source_volume'] = (
self.volume_api.get_volume(context,
source_volid))
else:
kwargs['source_volume'] = None
source_replica = volume.get('source_replica')
if source_replica is not None:
# Not found exception will be handled at the wsgi level
src_vol = self.volume_api.get_volume(context,
source_replica)
if src_vol['replication_status'] == 'disabled':
explanation = _('source volume id:%s is not'
' replicated') % source_replica
raise exc.HTTPBadRequest(explanation=explanation)
kwargs['source_replica'] = src_vol
else:
kwargs['source_replica'] = None
consistencygroup_id = volume.get('consistencygroup_id')
if consistencygroup_id is not None:
# Not found exception will be handled at the wsgi level
kwargs['consistencygroup'] = (
self.consistencygroup_api.get(context,
consistencygroup_id))
else:
kwargs['consistencygroup'] = None
# Get group_id if volume is in a group.
group_id = volume.get('group_id')
if group_id is not None:
try:
kwargs['group'] = self.group_api.get(context, group_id)
except exception.GroupNotFound as error:
raise exc.HTTPNotFound(explanation=error.msg)
size = volume.get('size', None)
if size is None and kwargs['snapshot'] is not None:
size = kwargs['snapshot']['volume_size']
elif size is None and kwargs['source_volume'] is not None:
size = kwargs['source_volume']['size']
elif size is None and kwargs['source_replica'] is not None:
size = kwargs['source_replica']['size']
LOG.info(_LI("Create volume of %s GB"), size)
if self.ext_mgr.is_loaded('os-image-create'):
image_ref = volume.get('imageRef')
if image_ref is not None:
image_uuid = self._image_uuid_from_ref(image_ref, context)
kwargs['image_id'] = image_uuid
kwargs['availability_zone'] = volume.get('availability_zone', None)
# 指定调度参数
kwargs['scheduler_hints'] = volume.get('scheduler_hints', None)
multiattach = volume.get('multiattach', False)
kwargs['multiattach'] = multiattach
# API 创建volume卷
new_volume = self.volume_api.create(context,
size,
volume.get('display_name'),
volume.get('display_description'),
**kwargs)
retval = self._view_builder.deta