151 lines
4.6 KiB
Python
151 lines
4.6 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# Copyright 2010 United States Government as represented by the
|
|
# Administrator of the National Aeronautics and Space Administration.
|
|
# All Rights Reserved.
|
|
#
|
|
# 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.
|
|
"""
|
|
Implementation of SQLAlchemy backend
|
|
"""
|
|
|
|
import sys
|
|
from glance.common import db
|
|
from glance.common import exception
|
|
from glance.common import flags
|
|
from glance.common.db.sqlalchemy.session import get_session
|
|
from glance.registry.db.sqlalchemy import models
|
|
from sqlalchemy.orm import exc
|
|
|
|
#from sqlalchemy.orm import joinedload_all
|
|
# TODO(sirp): add back eager loading
|
|
from sqlalchemy.orm import joinedload
|
|
from sqlalchemy.sql import func
|
|
|
|
FLAGS = flags.FLAGS
|
|
|
|
|
|
# NOTE(vish): disabling docstring pylint because the docstrings are
|
|
# in the interface definition
|
|
# pylint: disable-msg=C0111
|
|
def _deleted(context):
|
|
"""Calculates whether to include deleted objects based on context.
|
|
|
|
Currently just looks for a flag called deleted in the context dict.
|
|
"""
|
|
if not hasattr(context, 'get'):
|
|
return False
|
|
return context.get('deleted', False)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def image_create(_context, values):
|
|
return _image_update(_context, values, None)
|
|
|
|
|
|
def image_destroy(_context, image_id):
|
|
session = get_session()
|
|
with session.begin():
|
|
image_ref = models.Image.find(image_id, session=session)
|
|
image_ref.delete(session=session)
|
|
|
|
|
|
def image_get(context, image_id):
|
|
session = get_session()
|
|
try:
|
|
return session.query(models.Image
|
|
).options(joinedload(models.Image.properties)
|
|
).filter_by(deleted=_deleted(context)
|
|
).filter_by(id=image_id
|
|
).one()
|
|
except exc.NoResultFound:
|
|
new_exc = exception.NotFound("No model for id %s" % image_id)
|
|
raise new_exc.__class__, new_exc, sys.exc_info()[2]
|
|
|
|
|
|
def image_get_all(context):
|
|
session = get_session()
|
|
return session.query(models.Image
|
|
).options(joinedload(models.Image.properties)
|
|
).filter_by(deleted=_deleted(context)
|
|
).all()
|
|
|
|
|
|
def image_get_all_public(context, public):
|
|
session = get_session()
|
|
return session.query(models.Image
|
|
).options(joinedload(models.Image.properties)
|
|
).filter_by(deleted=_deleted(context)
|
|
).filter_by(is_public=public
|
|
).all()
|
|
|
|
|
|
def image_get_by_str(context, str_id):
|
|
return models.Image.find_by_str(str_id, deleted=_deleted(context))
|
|
|
|
|
|
def image_update(_context, image_id, values):
|
|
return _image_update(_context, values, image_id)
|
|
|
|
|
|
###################
|
|
|
|
|
|
def image_property_create(_context, values):
|
|
_drop_protected_attrs(models.Image, values)
|
|
image_property_ref = models.ImageProperty()
|
|
image_property_ref.update(values)
|
|
image_property_ref.save()
|
|
return image_property_ref
|
|
|
|
|
|
def _drop_protected_attrs(model_class, values):
|
|
"""Removed protected attributes from values dictionary using the models
|
|
__protected_attributes__ field.
|
|
"""
|
|
for attr in model_class.__protected_attributes__:
|
|
if attr in values:
|
|
del values[attr]
|
|
|
|
|
|
def _image_update(_context, values, image_id):
|
|
"""Used internally by image_create and image_update
|
|
|
|
:param image_id: If None, create the image, otherwise, find and update it
|
|
"""
|
|
session = get_session()
|
|
with session.begin():
|
|
_drop_protected_attrs(models.Image, values)
|
|
|
|
values['size'] = int(values['size'])
|
|
values['is_public'] = bool(values.get('is_public', False))
|
|
properties = values.pop('properties', {})
|
|
|
|
if image_id:
|
|
image_ref = models.Image.find(image_id, session=session)
|
|
else:
|
|
image_ref = models.Image()
|
|
|
|
image_ref.update(values)
|
|
image_ref.save(session=session)
|
|
|
|
for key, value in properties.iteritems():
|
|
prop_values = {'image_id': image_ref.id,
|
|
'key': key,
|
|
'value': value}
|
|
image_property_create(_context, prop_values)
|
|
|
|
return image_get(_context, image_ref.id)
|