diff options
| author | Vishvananda Ishaya <vishvananda@yahoo.com> | 2010-08-30 11:27:31 -0700 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@yahoo.com> | 2010-08-30 11:27:31 -0700 |
| commit | fd039eef503eaa65d0b0415b56ef4c975aabdd2d (patch) | |
| tree | cecd760c8238470e7df232033b592e98a44722a2 /nova/db | |
| parent | 40899259205561b43791f1540ec3f9100a4869d1 (diff) | |
| parent | db59c270cd4a3a3f32e73c2ab4bf8f8e1226dd66 (diff) | |
| download | nova-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__.py | 3 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 264 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 164 |
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) |
