From ae6905b9f1ef97206ee3c8722cec3b26fc064f38 Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Sat, 28 Aug 2010 20:32:48 -0700 Subject: Refactored orm to support atomic actions --- nova/db/sqlalchemy/api.py | 305 ++++++++++++++++++++++++------------------- nova/db/sqlalchemy/models.py | 173 +++++++++++------------- 2 files changed, 249 insertions(+), 229 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index cba85ccb7..5295d1e38 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -17,16 +17,17 @@ # under the License. import math - import IPy from nova import db from nova import exception from nova import flags from nova.db.sqlalchemy import models +from nova.db.sqlalchemy import session FLAGS = flags.FLAGS + ################### @@ -55,18 +56,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: - raise db.NoMoreAddresses() - floating_ip_ref['project_id'] = project_id - session.add(floating_ip_ref) - session.commit() - return floating_ip_ref['str_id'] + with session.managed(auto_commit=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): @@ -91,11 +95,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) @@ -104,19 +110,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: - raise db.NoMoreAddresses() - fixed_ip_ref['allocated'] = True - session.add(fixed_ip_ref) - session.commit() - return fixed_ip_ref + with session.open(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_get_by_address(context, address): @@ -192,19 +202,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 session.managed() 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 session.managed() 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): @@ -280,24 +290,31 @@ def network_count(context): return models.Network.count() 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 session.managed() 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 session.managed() 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 session.managed() 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): @@ -309,37 +326,43 @@ def network_create(context, values): def network_create_fixed_ips(context, network_id, num_vpn_clients): - network_ref = network_get(context, network_id) - # NOTE(vish): should these be properties of the network as opposed - # to constants? - BOTTOM_RESERVED = 3 - TOP_RESERVED = 1 + num_vpn_clients - project_net = IPy.IP(network_ref['cidr']) - num_ips = len(project_net) - session = models.NovaBase.get_session() - for i in range(num_ips): - fixed_ip = models.FixedIp() - fixed_ip['ip_str'] = str(project_net[i]) - if i < BOTTOM_RESERVED or num_ips - i < TOP_RESERVED: - fixed_ip['reserved'] = True - fixed_ip['network'] = network_get(context, network_id) - session.add(fixed_ip) - session.commit() + with session.managed(auto_commit=False) as session: + network_ref = network_get(context, network_id) + # NOTE(vish): should these be properties of the network as opposed + # to constants? + BOTTOM_RESERVED = 3 + TOP_RESERVED = 1 + num_vpn_clients + project_net = IPy.IP(network_ref['cidr']) + num_ips = len(project_net) + + for i in range(num_ips): + fixed_ip = models.FixedIp() + fixed_ip['ip_str'] = str(project_net[i]) + if i < BOTTOM_RESERVED or num_ips - i < TOP_RESERVED: + fixed_ip['reserved'] = True + fixed_ip['network'] = network_get(context, network_id) + session.add(fixed_ip) + session.commit() def network_ensure_indexes(context, num_networks): - if models.NetworkIndex.count() == 0: - session = models.NovaBase.get_session() - for i in range(num_networks): - network_index = models.NetworkIndex() - network_index.index = i - session.add(network_index) - session.commit() + with session.managed(auto_commit=False) as session: + if models.NetworkIndex.count() == 0: + session = models.NovaBase.get_session() + for i in range(num_networks): + network_index = models.NetworkIndex() + network_index.index = i + session.add(network_index) + session.commit() def network_destroy(context, network_id): - network_ref = network_get(context, network_id) - network_ref.delete() + with session.managed(auto_commit=False) as session: + session.execute('update networks set deleted=1 where id=:id', + {'id': network_id}) + session.execute('update network_indexes set deleted=1 where network_id=:id', + {'id': network_id}) + session.commit() def network_get(context, network_id): @@ -347,18 +370,22 @@ def network_get(context, network_id): 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 session.managed() 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: - raise exception.NotFound('No network for bridge %s' % bridge) - return rv + with session.managed() 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_vpn_ip(context, network_id): @@ -378,15 +405,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: - raise db.NoMoreNetworks() - network_index['network'] = network_get(context, network_id) - session.add(network_index) - session.commit() - return network_index['index'] + with session.managed(auto_commit=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.add(network_index) + session.commit() + return network_index['index'] def network_set_cidr(context, network_id, cidr): @@ -402,21 +432,24 @@ def network_set_cidr(context, network_id, cidr): 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: - 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 session.managed(auto_commit=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): @@ -430,11 +463,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 session.managed() 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 ################### @@ -447,20 +483,24 @@ def queue_get_for(context, topic, physical_node_id): def volume_allocate_shelf_and_blade(context, volume_id): - db.volume_ensure_blades(context, - FLAGS.num_shelves, - FLAGS.blades_per_shelf) - 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: - 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 session.managed(auto_commit=False) as session: + db.volume_ensure_blades(context, + session, + FLAGS.num_shelves, + FLAGS.blades_per_shelf) + 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): @@ -495,15 +535,16 @@ def volume_detached(context, volume_id): # NOTE(vish): should this code go up a layer? -def volume_ensure_blades(context, num_shelves, blades_per_shelf): - if models.ExportDevice.count() >= num_shelves * blades_per_shelf: +def volume_ensure_blades(context, session, num_shelves, blades_per_shelf): + count = models.ExportDevice.count(session=session) + if count >= num_shelves * blades_per_shelf: return for shelf_id in xrange(num_shelves): for blade_id in xrange(blades_per_shelf): export_device = models.ExportDevice() export_device.shelf_id = shelf_id export_device.blade_id = blade_id - export_device.save() + export_device.save(session=session) def volume_get(context, volume_id): @@ -515,11 +556,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 session.managed() 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 36d6cf3ad..c3529f29c 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -25,6 +25,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 import session from nova import auth from nova import exception from nova import flags @@ -38,72 +39,61 @@ class NovaBase(object): __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 session.managed() as session: + return cls.all(session=session) @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 session.managed() as session: + return cls.count(session=session) @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 session.managed() as session: + return cls.find(obj_id, session=session) @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: - 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) - session.commit() + def save(self, session=None): + if session: + session.add(self) + else: + with session.managed() as s: + self.save(session=s) - def delete(self): - session = NovaBase.get_session() - session.delete(self) - session.commit() - - 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) @@ -118,7 +108,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)) @@ -158,13 +147,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)) @@ -173,25 +162,10 @@ class Daemon(Base, NovaBase): class Instance(Base, NovaBase): __tablename__ = 'instances' __prefix__ = 'i' - id = Column(Integer, primary_key=True) + id = Column(Integer, primary_key=True) user_id = Column(String(255)) #, ForeignKey('users.id'), nullable=False) project_id = Column(String(255)) #, ForeignKey('projects.id')) - - @property - def user(self): - return auth.manager.AuthManager().get_user(self.user_id) - - @property - def project(self): - return auth.manager.AuthManager().get_project(self.project_id) - - # TODO(vish): make this opaque somehow - @property - def name(self): - return self.str_id - - image_id = Column(Integer, ForeignKey('images.id'), nullable=True) kernel_id = Column(Integer, ForeignKey('images.id'), nullable=True) ramdisk_id = Column(Integer, ForeignKey('images.id'), nullable=True) @@ -214,13 +188,26 @@ class Instance(Base, NovaBase): reservation_id = Column(String(255)) mac_address = Column(String(255)) - def set_state(self, state_code, state_description=None): + @property + def user(self): + return auth.manager.AuthManager().get_user(self.user_id) + + @property + def project(self): + return auth.manager.AuthManager().get_project(self.project_id) + + # TODO(vish): make this opaque somehow + @property + def name(self): + return self.str_id + + def set_state(self, session, state_code, state_description=None): from nova.compute import power_state self.state = state_code if not state_description: state_description = power_state.name(state_code) self.state_description = state_description - self.save() + self.save(session) # ramdisk = relationship(Ramdisk, backref=backref('instances', order_by=id)) # kernel = relationship(Kernel, backref=backref('instances', order_by=id)) @@ -280,12 +267,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) @@ -305,12 +292,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) @@ -352,17 +339,9 @@ class NetworkIndex(Base, NovaBase): uselist=False)) - - -def create_session(engine=None): - return NovaBase.get_session() - if __name__ == '__main__': - engine = NovaBase.create_engine() - session = NovaBase.create_session(engine) - instance = Instance(image_id='as', ramdisk_id='AS', user_id='anthony') user = User(id='anthony') - session.add(instance) - session.commit() - + + with session.managed() as session: + session.add(instance) -- cgit From 5425a3252f6e91d842a891fbd93ee51f490bddce Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Sat, 28 Aug 2010 23:06:40 -0700 Subject: Making tests pass --- nova/db/sqlalchemy/__init__.py | 3 +++ nova/db/sqlalchemy/api.py | 58 ++++++++++++++++++++++-------------------- nova/db/sqlalchemy/models.py | 31 ++++++++++++++-------- 3 files changed, 54 insertions(+), 38 deletions(-) (limited to 'nova/db') 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 5295d1e38..0b6316221 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -23,7 +23,7 @@ from nova import db from nova import exception from nova import flags from nova.db.sqlalchemy import models -from nova.db.sqlalchemy import session +from nova.db.sqlalchemy.session import managed_session FLAGS = flags.FLAGS @@ -56,7 +56,7 @@ def daemon_update(context, daemon_id, values): def floating_ip_allocate_address(context, node_name, project_id): - with session.managed(auto_commit=False) as session: + 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) \ @@ -202,7 +202,7 @@ def instance_get_by_address(context, address): def instance_get_by_project(context, project_id): - with session.managed() as session: + with managed_session() as session: return session.query(models.Instance) \ .filter_by(project_id=project_id) \ .filter_by(deleted=False) \ @@ -210,7 +210,7 @@ def instance_get_by_project(context, project_id): def instance_get_by_reservation(context, reservation_id): - with session.managed() as session: + with managed_session() as session: return session.query(models.Instance) \ .filter_by(reservation_id=reservation_id) \ .filter_by(deleted=False) \ @@ -290,7 +290,7 @@ def network_count(context): return models.Network.count() def network_count_allocated_ips(context, network_id): - with session.managed() as session: + with managed_session() as session: return session.query(models.FixedIp) \ .filter_by(network_id=network_id) \ .filter_by(allocated=True) \ @@ -299,7 +299,7 @@ def network_count_allocated_ips(context, network_id): def network_count_available_ips(context, network_id): - with session.managed() as session: + with managed_session() as session: return session.query(models.FixedIp) \ .filter_by(network_id=network_id) \ .filter_by(allocated=False) \ @@ -309,7 +309,7 @@ def network_count_available_ips(context, network_id): def network_count_reserved_ips(context, network_id): - with session.managed() as session: + with managed_session() as session: return session.query(models.FixedIp) \ .filter_by(network_id=network_id) \ .filter_by(reserved=True) \ @@ -326,8 +326,8 @@ def network_create(context, values): def network_create_fixed_ips(context, network_id, num_vpn_clients): - with session.managed(auto_commit=False) as session: - network_ref = network_get(context, network_id) + with managed_session(autocommit=False) as session: + network_ref = network_get(context, network_id, session=session) # NOTE(vish): should these be properties of the network as opposed # to constants? BOTTOM_RESERVED = 3 @@ -340,15 +340,16 @@ def network_create_fixed_ips(context, network_id, num_vpn_clients): fixed_ip['ip_str'] = str(project_net[i]) if i < BOTTOM_RESERVED or num_ips - i < TOP_RESERVED: fixed_ip['reserved'] = True - fixed_ip['network'] = network_get(context, network_id) + fixed_ip['network'] = network_get(context, + network_id, + session=session) session.add(fixed_ip) session.commit() def network_ensure_indexes(context, num_networks): - with session.managed(auto_commit=False) as session: + with managed_session(autocommit=False) as session: if models.NetworkIndex.count() == 0: - session = models.NovaBase.get_session() for i in range(num_networks): network_index = models.NetworkIndex() network_index.index = i @@ -357,7 +358,7 @@ def network_ensure_indexes(context, num_networks): def network_destroy(context, network_id): - with session.managed(auto_commit=False) as session: + with managed_session(autocommit=False) as session: session.execute('update networks set deleted=1 where id=:id', {'id': network_id}) session.execute('update network_indexes set deleted=1 where network_id=:id', @@ -365,12 +366,12 @@ def network_destroy(context, 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): - with session.managed() as session: + with managed_session() as session: return session.query(models.FixedIp) \ .filter(models.FixedIp.instance_id != None) \ .filter_by(deleted=False) \ @@ -378,7 +379,7 @@ def network_get_associated_fixed_ips(context, network_id): def network_get_by_bridge(context, bridge): - with session.managed() as session: + with managed_session() as session: rv = session.query(models.Network) \ .filter_by(bridge=bridge) \ .filter_by(deleted=False) \ @@ -405,7 +406,7 @@ def network_get_host(context, network_id): def network_get_index(context, network_id): - with session.managed(auto_commit=False) as session: + with managed_session(autocommit=False) as session: network_index = session.query(models.NetworkIndex) \ .filter_by(network_id=None) \ .filter_by(deleted=False) \ @@ -413,7 +414,7 @@ def network_get_index(context, network_id): .first() if not network_index: raise db.NoMoreNetworks() - network_index['network'] = network_get(context, network_id) + network_index['network'] = network_get(context, network_id, session=session) session.add(network_index) session.commit() return network_index['index'] @@ -429,10 +430,11 @@ def network_set_cidr(context, network_id, cidr): network_ref['broadcast'] = str(project_net.broadcast()) network_ref['vpn_private_ip_str'] = str(project_net[2]) network_ref['dhcp_start'] = str(project_net[3]) + network_ref.save() def network_set_host(context, network_id, host_id): - with session.managed(auto_commit=False) as session: + with managed_session(autocommit=False) as session: network = session.query(models.Network) \ .filter_by(id=network_id) \ .filter_by(deleted=False) \ @@ -463,7 +465,7 @@ def network_update(context, network_id, values): def project_get_network(context, project_id): - with session.managed() as session: + with managed_session() as session: rv = session.query(models.Network) \ .filter_by(project_id=project_id) \ .filter_by(deleted=False) \ @@ -483,11 +485,11 @@ def queue_get_for(context, topic, physical_node_id): def volume_allocate_shelf_and_blade(context, volume_id): - with session.managed(auto_commit=False) as session: - db.volume_ensure_blades(context, - session, - FLAGS.num_shelves, - FLAGS.blades_per_shelf) + with managed_session(autocommit=False) as session: + volume_ensure_blades(context, + FLAGS.num_shelves, + FLAGS.blades_per_shelf, + session=session) export_device = session.query(models.ExportDevice) \ .filter_by(volume=None) \ .filter_by(deleted=False) \ @@ -535,7 +537,7 @@ def volume_detached(context, volume_id): # NOTE(vish): should this code go up a layer? -def volume_ensure_blades(context, session, num_shelves, blades_per_shelf): +def volume_ensure_blades(context, num_shelves, blades_per_shelf, session=None): count = models.ExportDevice.count(session=session) if count >= num_shelves * blades_per_shelf: return @@ -556,7 +558,7 @@ def volume_get_all(context): def volume_get_by_project(context, project_id): - with session.managed() as session: + with managed_session() as session: return session.query(models.Volume) \ .filter_by(project_id=project_id) \ .filter_by(deleted=False) \ diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index c3529f29c..040fa50cc 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -25,7 +25,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 import session +from nova.db.sqlalchemy.session import managed_session from nova import auth from nova import exception from nova import flags @@ -36,6 +36,7 @@ Base = declarative_base() class NovaBase(object): __table_args__ = {'mysql_engine':'InnoDB'} + __table_initialized__ = False __prefix__ = 'none' created_at = Column(DateTime) updated_at = Column(DateTime) @@ -48,7 +49,7 @@ class NovaBase(object): .filter_by(deleted=False) \ .all() else: - with session.managed() as session: + with managed_session() as session: return cls.all(session=session) @classmethod @@ -58,8 +59,8 @@ class NovaBase(object): .filter_by(deleted=False) \ .count() else: - with session.managed() as session: - return cls.count(session=session) + with managed_session() as s: + return cls.count(session=s) @classmethod def find(cls, obj_id, session=None): @@ -72,7 +73,7 @@ class NovaBase(object): except exc.NoResultFound: raise exception.NotFound("No model for id %s" % obj_id) else: - with session.managed() as session: + with managed_session() as session: return cls.find(obj_id, session=session) @classmethod @@ -87,8 +88,9 @@ class NovaBase(object): def save(self, session=None): if session: session.add(self) + session.flush() else: - with session.managed() as s: + with managed_session() as s: self.save(session=s) def delete(self, session=None): @@ -253,7 +255,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', @@ -280,7 +282,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')) @@ -336,12 +338,21 @@ 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)) + uselist=False)) + +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) if __name__ == '__main__': instance = Instance(image_id='as', ramdisk_id='AS', user_id='anthony') user = User(id='anthony') - with session.managed() as session: + with managed_session() as session: session.add(instance) -- cgit From 6012ea583426bf76979448e4262a24a6b8fb2f5d Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Sat, 28 Aug 2010 23:20:06 -0700 Subject: Making tests pass --- nova/db/sqlalchemy/models.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 040fa50cc..4fbe2cc5e 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -164,10 +164,25 @@ class Daemon(Base, NovaBase): class Instance(Base, NovaBase): __tablename__ = 'instances' __prefix__ = 'i' - id = Column(Integer, primary_key=True) + user_id = Column(String(255)) #, ForeignKey('users.id'), nullable=False) project_id = Column(String(255)) #, ForeignKey('projects.id')) + + @property + def user(self): + return auth.manager.AuthManager().get_user(self.user_id) + + @property + def project(self): + return auth.manager.AuthManager().get_project(self.project_id) + + # TODO(vish): make this opaque somehow + @property + def name(self): + return self.str_id + + image_id = Column(Integer, ForeignKey('images.id'), nullable=True) kernel_id = Column(Integer, ForeignKey('images.id'), nullable=True) ramdisk_id = Column(Integer, ForeignKey('images.id'), nullable=True) @@ -190,26 +205,13 @@ class Instance(Base, NovaBase): reservation_id = Column(String(255)) mac_address = Column(String(255)) - @property - def user(self): - return auth.manager.AuthManager().get_user(self.user_id) - - @property - def project(self): - return auth.manager.AuthManager().get_project(self.project_id) - - # TODO(vish): make this opaque somehow - @property - def name(self): - return self.str_id - - def set_state(self, session, state_code, state_description=None): + def set_state(self, state_code, state_description=None): from nova.compute import power_state self.state = state_code if not state_description: state_description = power_state.name(state_code) self.state_description = state_description - self.save(session) + self.save() # ramdisk = relationship(Ramdisk, backref=backref('instances', order_by=id)) # kernel = relationship(Kernel, backref=backref('instances', order_by=id)) -- cgit From db59c270cd4a3a3f32e73c2ab4bf8f8e1226dd66 Mon Sep 17 00:00:00 2001 From: Devin Carlen Date: Mon, 30 Aug 2010 10:51:54 -0700 Subject: Making tests pass --- nova/db/sqlalchemy/api.py | 11 ++++++++--- nova/db/sqlalchemy/models.py | 10 +++++----- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'nova/db') diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 0b6316221..3166d35cc 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -349,7 +349,8 @@ def network_create_fixed_ips(context, network_id, num_vpn_clients): def network_ensure_indexes(context, num_networks): with managed_session(autocommit=False) as session: - if models.NetworkIndex.count() == 0: + count = models.NetworkIndex.count(session=session) + if count == 0: for i in range(num_networks): network_index = models.NetworkIndex() network_index.index = i @@ -523,8 +524,12 @@ 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: + session.execute('update volumes set deleted=1 where id=:id', + {'id': volume_id}) + session.execute('update export_devices set deleted=1 where network_id=:id', + {'id': volume_id}) + session.commit() def volume_detached(context, volume_id): diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 4fbe2cc5e..10f909d95 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -49,8 +49,8 @@ class NovaBase(object): .filter_by(deleted=False) \ .all() else: - with managed_session() as session: - return cls.all(session=session) + with managed_session() as s: + return cls.all(session=s) @classmethod def count(cls, session=None): @@ -73,8 +73,8 @@ class NovaBase(object): except exc.NoResultFound: raise exception.NotFound("No model for id %s" % obj_id) else: - with managed_session() as session: - return cls.find(obj_id, session=session) + with managed_session() as s: + return cls.find(obj_id, session=s) @classmethod def find_by_str(cls, str_id, session=None): @@ -206,6 +206,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: @@ -345,7 +346,6 @@ class NetworkIndex(Base, NovaBase): 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) -- cgit