summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@yahoo.com>2010-08-30 11:27:31 -0700
committerVishvananda Ishaya <vishvananda@yahoo.com>2010-08-30 11:27:31 -0700
commitfd039eef503eaa65d0b0415b56ef4c975aabdd2d (patch)
treececd760c8238470e7df232033b592e98a44722a2 /nova/db
parent40899259205561b43791f1540ec3f9100a4869d1 (diff)
parentdb59c270cd4a3a3f32e73c2ab4bf8f8e1226dd66 (diff)
downloadnova-fd039eef503eaa65d0b0415b56ef4c975aabdd2d.tar.gz
nova-fd039eef503eaa65d0b0415b56ef4c975aabdd2d.tar.xz
nova-fd039eef503eaa65d0b0415b56ef4c975aabdd2d.zip
merged devin's sqlalchemy changes
Diffstat (limited to 'nova/db')
-rw-r--r--nova/db/sqlalchemy/__init__.py3
-rw-r--r--nova/db/sqlalchemy/api.py264
-rw-r--r--nova/db/sqlalchemy/models.py164
3 files changed, 224 insertions, 207 deletions
diff --git a/nova/db/sqlalchemy/__init__.py b/nova/db/sqlalchemy/__init__.py
index e69de29bb..e94f99486 100644
--- a/nova/db/sqlalchemy/__init__.py
+++ b/nova/db/sqlalchemy/__init__.py
@@ -0,0 +1,3 @@
+from models import register_models
+
+register_models() \ No newline at end of file
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index d7a107ba8..cef77cc50 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -20,9 +20,11 @@ from nova import db
from nova import exception
from nova import flags
from nova.db.sqlalchemy import models
+from nova.db.sqlalchemy.session import managed_session
FLAGS = flags.FLAGS
+
###################
@@ -51,19 +53,21 @@ def daemon_update(context, daemon_id, values):
def floating_ip_allocate_address(context, node_name, project_id):
- session = models.NovaBase.get_session()
- query = session.query(models.FloatingIp).filter_by(node_name=node_name)
- query = query.filter_by(fixed_ip_id=None).with_lockmode("update")
- floating_ip_ref = query.first()
- # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
- # then this has concurrency issues
- if not floating_ip_ref:
- session.rollback()
- raise db.NoMoreAddresses()
- floating_ip_ref['project_id'] = project_id
- session.add(floating_ip_ref)
- session.commit()
- return floating_ip_ref['str_id']
+ with managed_session(autocommit=False) as session:
+ floating_ip_ref = session.query(models.FloatingIp) \
+ .filter_by(node_name=node_name) \
+ .filter_by(fixed_ip_id=None) \
+ .filter_by(deleted=False) \
+ .with_lockmode('update') \
+ .first()
+ # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
+ # then this has concurrency issues
+ if not floating_ip_ref:
+ raise db.NoMoreAddresses()
+ floating_ip_ref['project_id'] = project_id
+ session.add(floating_ip_ref)
+ session.commit()
+ return floating_ip_ref['str_id']
def floating_ip_create(context, address, host):
@@ -88,11 +92,13 @@ def floating_ip_disassociate(context, address):
floating_ip_ref.save()
return fixed_ip_address
+
def floating_ip_deallocate(context, address):
floating_ip_ref = db.floating_ip_get_by_address(context, address)
floating_ip_ref['project_id'] = None
floating_ip_ref.save()
+
def floating_ip_get_by_address(context, address):
return models.FloatingIp.find_by_str(address)
@@ -101,20 +107,23 @@ def floating_ip_get_by_address(context, address):
def fixed_ip_allocate(context, network_id):
- session = models.NovaBase.get_session()
- query = session.query(models.FixedIp).filter_by(network_id=network_id)
- query = query.filter_by(reserved=False).filter_by(allocated=False)
- query = query.filter_by(leased=False).with_lockmode("update")
- fixed_ip_ref = query.first()
- # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
- # then this has concurrency issues
- if not fixed_ip_ref:
- session.rollback()
- raise db.NoMoreAddresses()
- fixed_ip_ref['allocated'] = True
- session.add(fixed_ip_ref)
- session.commit()
- return fixed_ip_ref['str_id']
+ with managed_session(autocommit=False) as session:
+ fixed_ip_ref = session.query(models.FixedIp) \
+ .filter_by(network_id=network_id) \
+ .filter_by(reserved=False) \
+ .filter_by(allocated=False) \
+ .filter_by(leased=False) \
+ .filter_by(deleted=False) \
+ .with_lockmode('update') \
+ .first()
+ # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
+ # then this has concurrency issues
+ if not fixed_ip_ref:
+ raise db.NoMoreAddresses()
+ fixed_ip_ref['allocated'] = True
+ session.add(fixed_ip_ref)
+ session.commit()
+ return fixed_ip_ref
def fixed_ip_create(context, network_id, address, reserved=False):
@@ -191,19 +200,19 @@ def instance_get_by_address(context, address):
def instance_get_by_project(context, project_id):
- session = models.NovaBase.get_session()
- query = session.query(models.Instance)
- results = query.filter_by(project_id=project_id).all()
- session.commit()
- return results
+ with managed_session() as session:
+ return session.query(models.Instance) \
+ .filter_by(project_id=project_id) \
+ .filter_by(deleted=False) \
+ .all()
def instance_get_by_reservation(context, reservation_id):
- session = models.NovaBase.get_session()
- query = session.query(models.Instance)
- results = query.filter_by(reservation_id=reservation_id).all()
- session.commit()
- return results
+ with managed_session() as session:
+ return session.query(models.Instance) \
+ .filter_by(reservation_id=reservation_id) \
+ .filter_by(deleted=False) \
+ .all()
def instance_get_by_str(context, str_id):
@@ -257,24 +266,31 @@ def network_count(context):
def network_count_allocated_ips(context, network_id):
- session = models.NovaBase.get_session()
- query = session.query(models.FixedIp).filter_by(network_id=network_id)
- query = query.filter_by(allocated=True)
- return query.count()
+ with managed_session() as session:
+ return session.query(models.FixedIp) \
+ .filter_by(network_id=network_id) \
+ .filter_by(allocated=True) \
+ .filter_by(deleted=False) \
+ .count()
def network_count_available_ips(context, network_id):
- session = models.NovaBase.get_session()
- query = session.query(models.FixedIp).filter_by(network_id=network_id)
- query = query.filter_by(allocated=False).filter_by(reserved=False)
- return query.count()
+ with managed_session() as session:
+ return session.query(models.FixedIp) \
+ .filter_by(network_id=network_id) \
+ .filter_by(allocated=False) \
+ .filter_by(reserved=False) \
+ .filter_by(deleted=False) \
+ .count()
def network_count_reserved_ips(context, network_id):
- session = models.NovaBase.get_session()
- query = session.query(models.FixedIp).filter_by(network_id=network_id)
- query = query.filter_by(reserved=True)
- return query.count()
+ with managed_session() as session:
+ return session.query(models.FixedIp) \
+ .filter_by(network_id=network_id) \
+ .filter_by(reserved=True) \
+ .filter_by(deleted=False) \
+ .count()
def network_create(context, values):
@@ -283,33 +299,41 @@ def network_create(context, values):
network_ref[key] = value
network_ref.save()
return network_ref
+ return network_ref.id
def network_destroy(context, network_id):
- network_ref = network_get(context, network_id)
- network_ref.delete()
+ with managed_session(autocommit=False) as session:
+ # TODO(vish): do we have to use sql here?
+ session.execute('update networks set deleted=1 where id=:id',
+ {'id': network_id})
+ session.execute('update network_indexes set network_id=NULL where network_id=:id',
+ {'id': network_id})
+ session.commit()
-def network_get(context, network_id):
- return models.Network.find(network_id)
+def network_get(context, network_id, session=None):
+ return models.Network.find(network_id, session=session)
def network_get_associated_fixed_ips(context, network_id):
- session = models.NovaBase.get_session()
- query = session.query(models.FixedIp)
- fixed_ips = query.filter(models.FixedIp.instance_id != None).all()
- session.commit()
- return fixed_ips
+ with managed_session() as session:
+ return session.query(models.FixedIp) \
+ .filter(models.FixedIp.instance_id != None) \
+ .filter_by(deleted=False) \
+ .all()
+
def network_get_by_bridge(context, bridge):
- session = models.NovaBase.get_session()
- rv = session.query(models.Network).filter_by(bridge=bridge).first()
- if not rv:
- session.rollback()
- raise exception.NotFound('No network for bridge %s' % bridge)
- session.commit()
- return rv
+ with managed_session() as session:
+ rv = session.query(models.Network) \
+ .filter_by(bridge=bridge) \
+ .filter_by(deleted=False) \
+ .first()
+ if not rv:
+ raise exception.NotFound('No network for bridge %s' % bridge)
+ return rv
def network_get_host(context, network_id):
@@ -318,16 +342,18 @@ def network_get_host(context, network_id):
def network_get_index(context, network_id):
- session = models.NovaBase.get_session()
- query = session.query(models.NetworkIndex).filter_by(network_id=None)
- network_index = query.with_lockmode("update").first()
- if not network_index:
- session.rollback()
- raise db.NoMoreNetworks()
- network_index['network'] = network_get(context, network_id)
- session.add(network_index)
- session.commit()
- return network_index['index']
+ with managed_session(autocommit=False) as session:
+ network_index = session.query(models.NetworkIndex) \
+ .filter_by(network_id=None) \
+ .filter_by(deleted=False) \
+ .with_lockmode('update') \
+ .first()
+ if not network_index:
+ raise db.NoMoreNetworks()
+ network_index['network'] = network_get(context, network_id, session=session)
+ session.add(network_index)
+ session.commit()
+ return network_index['index']
def network_index_count(context):
@@ -342,22 +368,24 @@ def network_index_create(context, values):
def network_set_host(context, network_id, host_id):
- session = models.NovaBase.get_session()
- query = session.query(models.Network).filter_by(id=network_id)
- network = query.with_lockmode("update").first()
- if not network:
- session.rollback()
- raise exception.NotFound("Couldn't find network with %s" %
- network_id)
- # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
- # then this has concurrency issues
- if network.node_name:
+ with managed_session(autocommit=False) as session:
+ network = session.query(models.Network) \
+ .filter_by(id=network_id) \
+ .filter_by(deleted=False) \
+ .with_lockmode('update') \
+ .first()
+ if not network:
+ raise exception.NotFound("Couldn't find network with %s" %
+ network_id)
+ # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
+ # then this has concurrency issues
+ if network.node_name:
+ session.commit()
+ return network['node_name']
+ network['node_name'] = host_id
+ session.add(network)
session.commit()
return network['node_name']
- network['node_name'] = host_id
- session.add(network)
- session.commit()
- return network['node_name']
def network_update(context, network_id, values):
@@ -371,11 +399,14 @@ def network_update(context, network_id, values):
def project_get_network(context, project_id):
- session = models.create_session()
- rv = session.query(models.Network).filter_by(project_id=project_id).first()
- if not rv:
- raise exception.NotFound('No network for project: %s' % project_id)
- return rv
+ with managed_session() as session:
+ rv = session.query(models.Network) \
+ .filter_by(project_id=project_id) \
+ .filter_by(deleted=False) \
+ .first()
+ if not rv:
+ raise exception.NotFound('No network for project: %s' % project_id)
+ return rv
###################
@@ -403,18 +434,20 @@ def export_device_create(context, values):
def volume_allocate_shelf_and_blade(context, volume_id):
- session = models.NovaBase.get_session()
- query = session.query(models.ExportDevice).filter_by(volume=None)
- export_device = query.with_lockmode("update").first()
- # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
- # then this has concurrency issues
- if not export_device:
- session.rollback()
- raise db.NoMoreBlades()
- export_device.volume_id = volume_id
- session.add(export_device)
- session.commit()
- return (export_device.shelf_id, export_device.blade_id)
+ with managed_session(autocommit=False) as session:
+ export_device = session.query(models.ExportDevice) \
+ .filter_by(volume=None) \
+ .filter_by(deleted=False) \
+ .with_lockmode('update') \
+ .first()
+ # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
+ # then this has concurrency issues
+ if not export_device:
+ raise db.NoMoreBlades()
+ export_device.volume_id = volume_id
+ session.add(export_device)
+ session.commit()
+ return (export_device.shelf_id, export_device.blade_id)
def volume_attached(context, volume_id, instance_id, mountpoint):
@@ -435,8 +468,13 @@ def volume_create(context, values):
def volume_destroy(context, volume_id):
- volume_ref = volume_get(context, volume_id)
- volume_ref.delete()
+ with managed_session(autocommit=False) as session:
+ # TODO(vish): do we have to use sql here?
+ session.execute('update volumes set deleted=1 where id=:id',
+ {'id': volume_id})
+ session.execute('update export_devices set volume_id=NULL where network_id=:id',
+ {'id': volume_id})
+ session.commit()
def volume_detached(context, volume_id):
@@ -457,11 +495,11 @@ def volume_get_all(context):
def volume_get_by_project(context, project_id):
- session = models.NovaBase.get_session()
- query = session.query(models.Volume)
- results = query.filter_by(project_id=project_id).all()
- session.commit()
- return results
+ with managed_session() as session:
+ return session.query(models.Volume) \
+ .filter_by(project_id=project_id) \
+ .filter_by(deleted=False) \
+ .all()
def volume_get_by_str(context, str_id):
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index 2f0ce5d83..b7031eec0 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -27,6 +27,7 @@ from sqlalchemy import Table, Column, Integer, String
from sqlalchemy import MetaData, ForeignKey, DateTime, Boolean, Text
from sqlalchemy.ext.declarative import declarative_base
+from nova.db.sqlalchemy.session import managed_session
from nova import auth
from nova import exception
from nova import flags
@@ -37,84 +38,66 @@ Base = declarative_base()
class NovaBase(object):
__table_args__ = {'mysql_engine':'InnoDB'}
+ __table_initialized__ = False
__prefix__ = 'none'
created_at = Column(DateTime)
updated_at = Column(DateTime)
+ deleted = Column(Boolean, default=False)
- _session = None
- _engine = None
@classmethod
- def create_engine(cls):
- if NovaBase._engine is not None:
- return NovaBase._engine
- from sqlalchemy import create_engine
- NovaBase._engine = create_engine(FLAGS.sql_connection, echo=False)
- Base.metadata.create_all(NovaBase._engine)
- return NovaBase._engine
+ def all(cls, session=None):
+ if session:
+ return session.query(cls) \
+ .filter_by(deleted=False) \
+ .all()
+ else:
+ with managed_session() as s:
+ return cls.all(session=s)
@classmethod
- def get_session(cls):
- from sqlalchemy.orm import sessionmaker
- if NovaBase._session == None:
- NovaBase.create_engine()
- NovaBase._session = sessionmaker(bind=NovaBase._engine)()
- return NovaBase._session
+ def count(cls, session=None):
+ if session:
+ return session.query(cls) \
+ .filter_by(deleted=False) \
+ .count()
+ else:
+ with managed_session() as s:
+ return cls.count(session=s)
@classmethod
- def all(cls):
- session = NovaBase.get_session()
- result = session.query(cls).all()
- session.commit()
- return result
+ def find(cls, obj_id, session=None):
+ if session:
+ try:
+ return session.query(cls) \
+ .filter_by(id=obj_id) \
+ .filter_by(deleted=False) \
+ .one()
+ except exc.NoResultFound:
+ raise exception.NotFound("No model for id %s" % obj_id)
+ else:
+ with managed_session() as s:
+ return cls.find(obj_id, session=s)
@classmethod
- def count(cls):
- session = NovaBase.get_session()
- result = session.query(cls).count()
- session.commit()
- return result
-
- @classmethod
- def find(cls, obj_id):
- session = NovaBase.get_session()
- try:
- result = session.query(cls).filter_by(id=obj_id).one()
- session.commit()
- return result
- except exc.NoResultFound:
- session.rollback()
- raise exception.NotFound("No model for id %s" % obj_id)
-
- @classmethod
- def find_by_str(cls, str_id):
+ def find_by_str(cls, str_id, session=None):
id = int(str_id.rpartition('-')[2])
- return cls.find(id)
+ return cls.find(id, session=session)
@property
def str_id(self):
return "%s-%s" % (self.__prefix__, self.id)
- def save(self):
- session = NovaBase.get_session()
- session.add(self)
- try:
- session.commit()
- except exc.OperationalError:
- logging.exception("Error trying to save %s", self)
- session.rollback()
-
- def delete(self):
- session = NovaBase.get_session()
- session.delete(self)
- try:
- session.commit()
- except exc.OperationalError:
- logging.exception("Error trying to delete %s", self)
- session.rollback()
+ def save(self, session=None):
+ if session:
+ session.add(self)
+ session.flush()
+ else:
+ with managed_session() as s:
+ self.save(session=s)
- def refresh(self):
- session = NovaBase.get_session()
- session.refresh(self)
+ def delete(self, session=None):
+ self.deleted = True
+ self.save(session=session)
def __setitem__(self, key, value):
setattr(self, key, value)
@@ -129,7 +112,6 @@ class Image(Base, NovaBase):
id = Column(Integer, primary_key=True)
user_id = Column(String(255))#, ForeignKey('users.id'), nullable=False)
project_id = Column(String(255))#, ForeignKey('projects.id'), nullable=False)
-
image_type = Column(String(255))
public = Column(Boolean, default=False)
state = Column(String(255))
@@ -169,13 +151,13 @@ class Daemon(Base, NovaBase):
report_count = Column(Integer, nullable=False, default=0)
@classmethod
- def find_by_args(cls, node_name, binary):
- session = NovaBase.get_session()
+ def find_by_args(cls, session, node_name, binary):
try:
- query = session.query(cls).filter_by(node_name=node_name)
- result = query.filter_by(binary=binary).one()
- session.commit()
- return result
+ return session.query(cls) \
+ .filter_by(node_name=node_name) \
+ .filter_by(binary=binary) \
+ .filter_by(deleted=False) \
+ .one()
except exc.NoResultFound:
raise exception.NotFound("No model for %s, %s" % (node_name,
binary))
@@ -226,6 +208,7 @@ class Instance(Base, NovaBase):
mac_address = Column(String(255))
def set_state(self, state_code, state_description=None):
+ # TODO(devcamcar): Move this out of models and into api
from nova.compute import power_state
self.state = state_code
if not state_description:
@@ -277,7 +260,7 @@ class ExportDevice(Base, NovaBase):
class FixedIp(Base, NovaBase):
__tablename__ = 'fixed_ips'
id = Column(Integer, primary_key=True)
- ip_str = Column(String(255), unique=True)
+ ip_str = Column(String(255))
network_id = Column(Integer, ForeignKey('networks.id'), nullable=False)
instance_id = Column(Integer, ForeignKey('instances.id'), nullable=True)
instance = relationship(Instance, backref=backref('fixed_ip',
@@ -291,12 +274,12 @@ class FixedIp(Base, NovaBase):
return self.ip_str
@classmethod
- def find_by_str(cls, str_id):
- session = NovaBase.get_session()
+ def find_by_str(cls, session, str_id):
try:
- result = session.query(cls).filter_by(ip_str=str_id).one()
- session.commit()
- return result
+ return session.query(cls) \
+ .filter_by(ip_str=str_id) \
+ .filter_by(deleted=False) \
+ .one()
except exc.NoResultFound:
raise exception.NotFound("No model for ip str %s" % str_id)
@@ -304,7 +287,7 @@ class FixedIp(Base, NovaBase):
class FloatingIp(Base, NovaBase):
__tablename__ = 'floating_ips'
id = Column(Integer, primary_key=True)
- ip_str = Column(String(255), unique=True)
+ ip_str = Column(String(255))
fixed_ip_id = Column(Integer, ForeignKey('fixed_ips.id'), nullable=True)
fixed_ip = relationship(FixedIp, backref=backref('floating_ips'))
@@ -316,12 +299,12 @@ class FloatingIp(Base, NovaBase):
return self.ip_str
@classmethod
- def find_by_str(cls, str_id):
- session = NovaBase.get_session()
+ def find_by_str(cls, session, str_id):
try:
- result = session.query(cls).filter_by(ip_str=str_id).one()
- session.commit()
- return result
+ return session.query(cls) \
+ .filter_by(ip_str=str_id) \
+ .filter_by(deleted=False) \
+ .one()
except exc.NoResultFound:
raise exception.NotFound("No model for ip str %s" % str_id)
@@ -359,20 +342,13 @@ class NetworkIndex(Base, NovaBase):
index = Column(Integer)
network_id = Column(Integer, ForeignKey('networks.id'), nullable=True)
network = relationship(Network, backref=backref('network_index',
- uselist=False))
-
-
-
-
-def create_session(engine=None):
- return NovaBase.get_session()
-
-if __name__ == '__main__':
- engine = NovaBase.create_engine()
- session = NovaBase.create_session(engine)
+ uselist=False))
- instance = Instance(image_id='as', ramdisk_id='AS', user_id='anthony')
- user = User(id='anthony')
- session.add(instance)
- session.commit()
+def register_models():
+ from sqlalchemy import create_engine
+ models = (Image, PhysicalNode, Daemon, Instance, Volume, ExportDevice,
+ FixedIp, FloatingIp, Network, NetworkIndex)
+ engine = create_engine(FLAGS.sql_connection, echo=False)
+ for model in models:
+ model.metadata.create_all(engine)