def create(self, context, size, name, description, snapshot=None, volume_type=None, metadata=None, availability_zone=None): check_policy(context, 'create') if snapshot is not None: if snapshot['status'] != "available": msg = _("status must be available") raise exception.InvalidSnapshot(reason=msg) if not size: size = snapshot['volume_size'] snapshot_id = snapshot['id'] else: snapshot_id = None try: reservations = QUOTAS.reserve(context, volumes=1, gigabytes=size) except exception.OverQuota: pid = context.project_id LOG.warn(_("Quota exceeded for %(pid)s, tried to create" " %(size)sG volume") % locals()) raise exception.VolumeSizeTooLarge() if availability_zone is None: availability_zone = FLAGS.storage_availability_zone if volume_type is None: volume_type_id = None else: volume_type_id = volume_type.get('id', None) options = { 'size': size, 'user_id': context.user_id, 'project_id': context.project_id, 'snapshot_id': snapshot_id, 'availability_zone': availability_zone, 'status': "creating", 'attach_status': "detached", 'display_name': name, 'display_description': description, 'volume_type_id': volume_type_id, 'metadata': metadata, } volume = self.db.volume_create(context, options) rpc.cast(context, FLAGS.scheduler_topic, {"method": "create_volume", "args": {"topic": FLAGS.volume_topic, "volume_id": volume['id'], "snapshot_id": snapshot_id, "reservations": reservations}}) return volume
def create(self, context, size, name, description, snapshot=None, volume_type=None, metadata=None, availability_zone=None): check_policy(context, 'create') if snapshot is not None: if snapshot['status'] != "available": msg = _("status must be available") raise exception.InvalidSnapshot(reason=msg) if not size: size = snapshot['volume_size'] snapshot_id = snapshot['id'] else: snapshot_id = None def as_int(s): try: return int(s) except ValueError: return s # tolerate size as stringified int size = as_int(size) if not isinstance(size, int) or size <= 0: msg = ( _("Volume size '%s' must be an integer and greater than 0") % size) raise exception.InvalidInput(reason=msg) try: reservations = QUOTAS.reserve(context, volumes=1, gigabytes=size) except exception.OverQuota as e: overs = e.kwargs['overs'] usages = e.kwargs['usages'] quotas = e.kwargs['quotas'] def _consumed(name): return (usages[name]['reserved'] + usages[name]['in_use']) pid = context.project_id if 'gigabytes' in overs: consumed = _consumed('gigabytes') quota = quotas['gigabytes'] LOG.warn( _("Quota exceeded for %(pid)s, tried to create " "%(size)sG volume (%(consumed)dG of %(quota)dG " "already consumed)") % locals()) raise exception.VolumeSizeTooLarge() elif 'volumes' in overs: consumed = _consumed('volumes') LOG.warn( _("Quota exceeded for %(pid)s, tried to create " "volume (%(consumed)d volumes already consumed)") % locals()) raise exception.VolumeLimitExceeded(allowed=quotas['volumes']) if availability_zone is None: availability_zone = FLAGS.storage_availability_zone if volume_type is None: volume_type_id = None else: volume_type_id = volume_type.get('id', None) options = { 'size': size, 'user_id': context.user_id, 'project_id': context.project_id, 'snapshot_id': snapshot_id, 'availability_zone': availability_zone, 'status': "creating", 'attach_status': "detached", 'display_name': name, 'display_description': description, 'volume_type_id': volume_type_id, 'metadata': metadata, } volume = self.db.volume_create(context, options) self._cast_create_volume(context, volume['id'], snapshot_id, reservations) return volume