1. 程式人生 > >Openstack Cinder原始碼分析-建立Volume(三)

Openstack Cinder原始碼分析-建立Volume(三)

上文已經分析到,請求最終通過RPC到了cinder-scheduler中

cinder-scheduler通過taskflow管理了2個任務(cinder/scheduler/flows/create_volume.py):

ExtractSchedulerSpecTask

該任務主要是封裝引數給下一任務,無revert函式

def _populate_request_spec(self, volume, snapshot_id, image_id, backup_id):
    # Create the full request spec using the volume object.
    #
    # NOTE(dulek): At this point, a volume can be deleted before it gets
    # scheduled.  If a delete API call is made, the volume gets instantly
    # delete and scheduling will fail when it tries to update the DB entry
    # (with the host) in ScheduleCreateVolumeTask below.
    volume_type_id = volume.volume_type_id
    vol_type = volume.volume_type
    return {
        'volume_id': volume.id,
        'snapshot_id': snapshot_id,
        'image_id': image_id,
        'backup_id': backup_id,
        'volume_properties': {
            'size': utils.as_int(volume.size, quiet=False),
            'availability_zone': volume.availability_zone,
            'volume_type_id': volume_type_id,
        },
        'volume_type': list(dict(vol_type).items()),
    }

def execute(self, context, request_spec, volume, snapshot_id,
            image_id, backup_id):
    # For RPC version < 1.2 backward compatibility
    if request_spec is None:
        request_spec = self._populate_request_spec(volume,
                                                   snapshot_id, image_id,
                                                   backup_id)
    return {
        'request_spec': request_spec,
    }

ScheduleCreateVolumeTask(重要)

def execute(self, context, request_spec, filter_properties, volume):
    try:
        self.driver_api.schedule_create_volume(context, request_spec,
                                               filter_properties)
    except Exception as e:
        self.message_api.create(
            context,
            message_field.Action.SCHEDULE_ALLOCATE_VOLUME,
            resource_uuid=request_spec['volume_id'],
            exception=e)
        # An error happened, notify on the scheduler queue and log that
        # this happened and set the volume to errored out and reraise the
        # error *if* exception caught isn't NoValidBackend. Otherwise *do
        # not* reraise (since what's the point?)
        with excutils.save_and_reraise_exception(
                reraise=not isinstance(e, exception.NoValidBackend)):
            try:
                self._handle_failure(context, request_spec, e)
            finally:
                common.error_out(volume, reason=e)

注:scheduler_driver是在啟動時初始化,預設driver管理類是在配置檔案中進行配置:

scheduler_driver_opt = cfg.StrOpt('scheduler_driver',
                                  default='cinder.scheduler.filter_scheduler.'
                                          'FilterScheduler',
                                  help='Default scheduler driver to use')

class SchedulerManager(manager.CleanableManager, manager.Manager):
    """Chooses a host to create volumes."""

    RPC_API_VERSION = scheduler_rpcapi.SchedulerAPI.RPC_API_VERSION

    target = messaging.Target(version=RPC_API_VERSION)

    def __init__(self, scheduler_driver=None, service_name=None,
                 *args, **kwargs):
        if not scheduler_driver:
            scheduler_driver = CONF.scheduler_driver
        self.driver = importutils.import_object(scheduler_driver)

self.driver_api.schedule_create_volume的入口類:cinder/scheduler/filter_scheduler.py