def model_query(context, *args, **kwargs): """Query helper that accounts for context's `read_deleted` field. :param context: context to query under :param session: if present, the session to use :param read_deleted: if present, overrides context's read_deleted field. :param project_only: if present and context is user-type, then restrict query to match the context's project_id. """ session = kwargs.get('session') or get_session() read_deleted = kwargs.get('read_deleted') or context.read_deleted project_only = kwargs.get('project_only') query = session.query(*args) if read_deleted == 'no': query = query.filter_by(deleted=False) elif read_deleted == 'yes': pass # omit the filter to include deleted and active elif read_deleted == 'only': query = query.filter_by(deleted=True) else: raise Exception( _("Unrecognized read_deleted value '%s'") % read_deleted) if project_only and is_user_context(context): query = query.filter_by(project_id=context.project_id) return query
def volume_metadata_update(context, volume_id, metadata, delete): session = get_session() # Set existing metadata to deleted if delete argument is True if delete: original_metadata = volume_metadata_get(context, volume_id) for meta_key, meta_value in original_metadata.iteritems(): if meta_key not in metadata: meta_ref = volume_metadata_get_item(context, volume_id, meta_key, session) meta_ref.update({'deleted': True}) meta_ref.save(session=session) meta_ref = None # Now update all existing items with new values, or create new meta objects for meta_key, meta_value in metadata.iteritems(): # update the value whether it exists or not item = {"value": meta_value} try: meta_ref = volume_metadata_get_item(context, volume_id, meta_key, session) except exception.VolumeMetadataNotFound, e: meta_ref = models.VolumeMetadata() item.update({"key": meta_key, "volume_id": volume_id}) meta_ref.update(item) meta_ref.save(session=session)
def migration_update(context, id, values): session = get_session() with session.begin(): migration = migration_get(context, id, session=session) migration.update(values) migration.save(session=session) return migration
def quota_class_update(context, class_name, resource, limit): session = get_session() with session.begin(): quota_class_ref = quota_class_get(context, class_name, resource, session=session) quota_class_ref.hard_limit = limit quota_class_ref.save(session=session)
def volume_type_create(context, values): """Create a new instance type. In order to pass in extra specs, the values dict should contain a 'extra_specs' key/value pair: {'extra_specs' : {'k1': 'v1', 'k2': 'v2', ...}} """ session = get_session() with session.begin(): try: volume_type_get_by_name(context, values['name'], session) raise exception.VolumeTypeExists(name=values['name']) except exception.VolumeTypeNotFoundByName: pass try: specs = values.get('extra_specs') values['extra_specs'] = _metadata_refs(values.get('extra_specs'), models.VolumeTypeExtraSpecs) volume_type_ref = models.VolumeTypes() volume_type_ref.update(values) volume_type_ref.save() except Exception, e: raise exception.DBError(e) return volume_type_ref
def aggregate_metadata_add(context, aggregate_id, metadata, set_delete=False): session = get_session() if set_delete: original_metadata = aggregate_metadata_get(context, aggregate_id) for meta_key, meta_value in original_metadata.iteritems(): if meta_key not in metadata: meta_ref = aggregate_metadata_get_item(context, aggregate_id, meta_key, session) meta_ref.update({'deleted': True}) meta_ref.save(session=session) meta_ref = None for meta_key, meta_value in metadata.iteritems(): item = {"value": meta_value} try: meta_ref = aggregate_metadata_get_item(context, aggregate_id, meta_key, session) if meta_ref.deleted: item.update({'deleted': False, 'deleted_at': None}) except exception.AggregateMetadataNotFound: meta_ref = models.AggregateMetadata() item.update({"key": meta_key, "aggregate_id": aggregate_id}) meta_ref.update(item) meta_ref.save(session=session) return metadata
def snapshot_destroy(context, snapshot_id): session = get_session() with session.begin(): session.query(models.Snapshot).\ filter_by(id=snapshot_id).\ update({'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')})
def volume_detached(context, volume_id): session = get_session() with session.begin(): volume_ref = volume_get(context, volume_id, session=session) volume_ref['status'] = 'available' volume_ref['mountpoint'] = None volume_ref['attach_status'] = 'detached' volume_ref['instance_uuid'] = None volume_ref.save(session=session)
def sm_backend_conf_delete(context, sm_backend_id): # FIXME(sirp): for consistency, shouldn't this just mark as deleted with # `purge` actually deleting the record? session = get_session() with session.begin(): model_query(context, models.SMBackendConf, session=session, read_deleted="yes").\ filter_by(id=sm_backend_id).\ delete()
def volume_attached(context, volume_id, instance_id, mountpoint): session = get_session() with session.begin(): volume_ref = volume_get(context, volume_id, session=session) volume_ref['status'] = 'in-use' volume_ref['mountpoint'] = mountpoint volume_ref['attach_status'] = 'attached' volume_ref['instance_id'] = instance_id volume_ref.save(session=session)
def snapshot_create(context, values): snapshot_ref = models.Snapshot() if not values.get('id'): values['id'] = str(utils.gen_uuid()) snapshot_ref.update(values) session = get_session() with session.begin(): snapshot_ref.save(session=session) return snapshot_ref
def quota_class_destroy_all_by_name(context, class_name): session = get_session() with session.begin(): quota_classes = model_query(context, models.QuotaClass, session=session, read_deleted="no").\ filter_by(class_name=class_name).\ all() for quota_class_ref in quota_classes: quota_class_ref.delete(session=session)
def quota_destroy_all_by_project(context, project_id): session = get_session() with session.begin(): quotas = model_query(context, models.Quota, session=session, read_deleted="no").\ filter_by(project_id=project_id).\ all() for quota_ref in quotas: quota_ref.delete(session=session)
def volume_attached(context, volume_id, instance_uuid, mountpoint): if not utils.is_uuid_like(instance_uuid): raise exception.InvalidUUID(instance_uuid) session = get_session() with session.begin(): volume_ref = volume_get(context, volume_id, session=session) volume_ref['status'] = 'in-use' volume_ref['mountpoint'] = mountpoint volume_ref['attach_status'] = 'attached' volume_ref['instance_uuid'] = instance_uuid volume_ref.save(session=session)
def save(self, session=None): """Save this object.""" if not session: session = get_session() session.add(self) try: session.flush() except IntegrityError, e: if str(e).endswith('is not unique'): raise exception.Duplicate(str(e)) else: raise
def volume_update(context, volume_id, values): session = get_session() metadata = values.get('metadata') if metadata is not None: volume_metadata_update(context, volume_id, values.pop('metadata'), delete=True) with session.begin(): volume_ref = volume_get(context, volume_id, session=session) volume_ref.update(values) volume_ref.save(session=session)
def volume_create(context, values): values['volume_metadata'] = _metadata_refs(values.get('metadata'), models.VolumeMetadata) volume_ref = models.Volume() if not values.get('id'): values['id'] = str(utils.gen_uuid()) volume_ref.update(values) session = get_session() with session.begin(): volume_ref.save(session=session) return volume_ref
def volume_type_extra_specs_update_or_create(context, volume_type_id, specs): session = get_session() spec_ref = None for key, value in specs.iteritems(): try: spec_ref = volume_type_extra_specs_get_item( context, volume_type_id, key, session) except exception.VolumeTypeExtraSpecsNotFound, e: spec_ref = models.VolumeTypeExtraSpecs() spec_ref.update({"key": key, "value": value, "volume_type_id": volume_type_id, "deleted": 0}) spec_ref.save(session=session)
def volume_get_active_by_window(context, begin, end=None, project_id=None): """Return volumes that were active during window.""" session = get_session() query = session.query(models.Volume) query = query.filter(or_(models.Volume.deleted_at == None, models.Volume.deleted_at > begin)) if end: query = query.filter(models.Volume.created_at < end) if project_id: query = query.filter_by(project_id=project_id) return query.all()
def service_get_all_volume_sorted(context): session = get_session() with session.begin(): topic = FLAGS.volume_topic label = 'volume_gigabytes' subq = model_query(context, models.Volume.host, func.sum(models.Volume.size).label(label), session=session, read_deleted="no").\ group_by(models.Volume.host).\ subquery() return _service_get_all_topic_subquery(context, session, topic, subq, label)
def sm_backend_conf_update(context, sm_backend_id, values): session = get_session() with session.begin(): backend_conf = model_query(context, models.SMBackendConf, session=session, read_deleted="yes").\ filter_by(id=sm_backend_id).\ first() if not backend_conf: raise exception.NotFound( _("No backend config with id %(sm_backend_id)s") % locals()) backend_conf.update(values) backend_conf.save(session=session) return backend_conf
def volume_type_destroy(context, name): session = get_session() with session.begin(): volume_type_ref = volume_type_get_by_name(context, name, session=session) volume_type_id = volume_type_ref['id'] session.query(models.VolumeTypes).\ filter_by(id=volume_type_id).\ update({'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')}) session.query(models.VolumeTypeExtraSpecs).\ filter_by(volume_type_id=volume_type_id).\ update({'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')})
def volume_destroy(context, volume_id): session = get_session() with session.begin(): session.query(models.Volume).\ filter_by(id=volume_id).\ update({'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')}) session.query(models.IscsiTarget).\ filter_by(volume_id=volume_id).\ update({'volume_id': None}) session.query(models.VolumeMetadata).\ filter_by(volume_id=volume_id).\ update({'deleted': True, 'deleted_at': timeutils.utcnow(), 'updated_at': literal_column('updated_at')})
def quota_usage_update(context, project_id, resource, in_use, reserved, until_refresh, session=None): def do_update(session): quota_usage_ref = quota_usage_get(context, project_id, resource, session=session) quota_usage_ref.in_use = in_use quota_usage_ref.reserved = reserved quota_usage_ref.until_refresh = until_refresh quota_usage_ref.save(session=session) if session: # Assume caller started a transaction do_update(session) else: session = get_session() with session.begin(): do_update(session)
def volume_allocate_iscsi_target(context, volume_id, host): session = get_session() with session.begin(): iscsi_target_ref = model_query(context, models.IscsiTarget, session=session, read_deleted="no").\ filter_by(volume=None).\ filter_by(host=host).\ with_lockmode('update').\ first() # NOTE(vish): if with_lockmode isn't supported, as in sqlite, # then this has concurrency issues if not iscsi_target_ref: raise db.NoMoreTargets() iscsi_target_ref.volume_id = volume_id session.add(iscsi_target_ref) return iscsi_target_ref.target_num
def aggregate_update(context, aggregate_id, values): session = get_session() aggregate = _aggregate_get_query(context, models.Aggregate, models.Aggregate.id, aggregate_id, session=session).first() if aggregate: metadata = values.get('metadata') if metadata is not None: aggregate_metadata_add(context, aggregate_id, values.pop('metadata'), set_delete=True) with session.begin(): aggregate.update(values) aggregate.save(session=session) values['metadata'] = metadata return aggregate else: raise exception.AggregateNotFound(aggregate_id=aggregate_id)
def volume_create(context, values): values['volume_metadata'] = _metadata_refs(values.get('metadata'), models.VolumeMetadata) volume_ref = models.Volume() if not values.get('id'): values['id'] = str(utils.gen_uuid()) volume_ref.update(values) session = get_session() with session.begin(): volume_ref.save(session=session) meta = volume_metadata_get(context, volume_ref.id) volume_ref.metadata = meta result = model_query(context, models.Volume, read_deleted="no").\ options(joinedload('volume_metadata')).\ filter_by(id=volume_ref['id']).first() if not result: raise exception.VolumeNotFound(volume_id=volume_ref['id']) return result
def aggregate_create(context, values, metadata=None): session = get_session() aggregate = _aggregate_get_query(context, models.Aggregate, models.Aggregate.name, values['name'], session=session, read_deleted='yes').first() values.setdefault('operational_state', aggregate_states.CREATED) if not aggregate: aggregate = models.Aggregate() aggregate.update(values) aggregate.save(session=session) elif aggregate.deleted: values['deleted'] = False values['deleted_at'] = None aggregate.update(values) aggregate.save(session=session) else: raise exception.AggregateNameExists(aggregate_name=values['name']) if metadata: aggregate_metadata_add(context, aggregate.id, metadata) return aggregate
def aggregate_host_add(context, aggregate_id, host): session = get_session() host_ref = _aggregate_get_query(context, models.AggregateHost, models.AggregateHost.aggregate_id, aggregate_id, session=session, read_deleted='yes').\ filter_by(host=host).first() if not host_ref: try: host_ref = models.AggregateHost() values = {"host": host, "aggregate_id": aggregate_id, } host_ref.update(values) host_ref.save(session=session) except exception.DBError: raise exception.AggregateHostConflict(host=host) elif host_ref.deleted: host_ref.update({'deleted': False, 'deleted_at': None}) host_ref.save(session=session) else: raise exception.AggregateHostExists(host=host, aggregate_id=aggregate_id) return host_ref
def test_get_all_volume_types(self): """Ensures that all volume types can be retrieved""" session = sql_session.get_session() total_volume_types = session.query(models.VolumeTypes).count() vol_types = volume_types.get_all_types(self.ctxt) self.assertEqual(total_volume_types, len(vol_types))