No longer import db_api while parsing db __init__.

The db_api field of reddwarf/db/__init__.py was grabbed by importing a
module using utils.import_object. The imported module was always the
sqlalchemy api module, which is nested under the file that imports it,
which caused import errors in multiple contexts. This commit changes
every use of db_api to call a function to load it first, which seems
to fix these problems.

Change-Id: I9515efe02831b521d7f14674e0a2913e476b207d
Fixes: bug #1080706
This commit is contained in:
Tim Simpson 2012-11-19 09:18:55 -06:00
parent f300b17621
commit 9a5d82bf90
11 changed files with 60 additions and 42 deletions

View File

@ -36,7 +36,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version from reddwarf import version
from reddwarf.common import config from reddwarf.common import config
from reddwarf.common import wsgi from reddwarf.common import wsgi
from reddwarf.db import db_api from reddwarf.db import get_db_api
def create_options(parser): def create_options(parser):
@ -62,7 +62,7 @@ if __name__ == '__main__':
try: try:
config.Config.load_paste_config('reddwarf', options, args) config.Config.load_paste_config('reddwarf', options, args)
conf, app = config.Config.load_paste_app('reddwarf', options, args) conf, app = config.Config.load_paste_app('reddwarf', options, args)
db_api.configure_db(conf) get_db_api().configure_db(conf)
server = wsgi.Server() server = wsgi.Server()
server.start(app, int(options.get('port') or conf['bind_port']), server.start(app, int(options.get('port') or conf['bind_port']),
conf['bind_host']) conf['bind_host'])

View File

@ -40,7 +40,7 @@ from reddwarf import version
from reddwarf.common import config from reddwarf.common import config
from reddwarf.common import service from reddwarf.common import service
# TODO(hub-cap): find out why the db api isint being imported properly # TODO(hub-cap): find out why the db api isint being imported properly
from reddwarf.db import db_api from reddwarf.db import get_db_api
if __name__ == '__main__': if __name__ == '__main__':
@ -61,7 +61,7 @@ if __name__ == '__main__':
# that is injected into the VM # that is injected into the VM
config.Config.append_to_config_values('reddwarf-guestagent', config.Config.append_to_config_values('reddwarf-guestagent',
{'config_file': '/etc/guest_info'}, None) {'config_file': '/etc/guest_info'}, None)
db_api.configure_db(conf) get_db_api().configure_db(conf)
server = service.Service.create(binary='reddwarf-guestagent', server = service.Service.create(binary='reddwarf-guestagent',
host=config.Config.get('guest_id')) host=config.Config.get('guest_id'))
service.serve(server) service.serve(server)

View File

@ -36,7 +36,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version from reddwarf import version
from reddwarf.common import config from reddwarf.common import config
from reddwarf.common import utils from reddwarf.common import utils
from reddwarf.db import db_api from reddwarf.db import get_db_api
from reddwarf.instance import models as instance_models from reddwarf.instance import models as instance_models
@ -57,24 +57,25 @@ def create_options(parser):
class Commands(object): class Commands(object):
def __init__(self, conf): def __init__(self, conf):
self.db_api = get_db_api()
self.conf = conf self.conf = conf
def db_sync(self): def db_sync(self):
db_api.db_sync(self.conf, repo_path=None) self.db_api.db_sync(self.conf, repo_path=None)
def db_upgrade(self, version=None, repo_path=None): def db_upgrade(self, version=None, repo_path=None):
db_api.db_upgrade(self.conf, version, repo_path=None) self.db_api.db_upgrade(self.conf, version, repo_path=None)
def db_downgrade(self, version, repo_path=None): def db_downgrade(self, version, repo_path=None):
db_api.db_downgrade(self.conf, version, repo_path=None) self.db_api.db_downgrade(self.conf, version, repo_path=None)
def execute(self, command_name, *args): def execute(self, command_name, *args):
if self.has(command_name): if self.has(command_name):
return getattr(self, command_name)(*args) return getattr(self, command_name)(*args)
def image_update(self, service_name, image_id): def image_update(self, service_name, image_id):
db_api.configure_db(self.conf) self.db_api.configure_db(self.conf)
image = db_api.find_by(instance_models.ServiceImage, image = self.db_api.find_by(instance_models.ServiceImage,
service_name=service_name) service_name=service_name)
if image is None: if image is None:
# Create a new one # Create a new one
@ -82,13 +83,13 @@ class Commands(object):
image.id = utils.generate_uuid() image.id = utils.generate_uuid()
image.service_name = service_name image.service_name = service_name
image.image_id = image_id image.image_id = image_id
db_api.save(image) self.db_api.save(image)
def db_wipe(self, repo_path, service_name, image_id): def db_wipe(self, repo_path, service_name, image_id):
"""Drops the database and recreates it.""" """Drops the database and recreates it."""
from reddwarf.instance import models from reddwarf.instance import models
from reddwarf.db.sqlalchemy import session from reddwarf.db.sqlalchemy import session
db_api.drop_db(self.conf) self.db_api.drop_db(self.conf)
self.db_sync() self.db_sync()
# Sets up database engine, so the next line will work... # Sets up database engine, so the next line will work...
session.configure_db(self.conf) session.configure_db(self.conf)

View File

@ -39,7 +39,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version from reddwarf import version
from reddwarf.common import config from reddwarf.common import config
from reddwarf.common import service from reddwarf.common import service
from reddwarf.db import db_api from reddwarf.db import get_db_api
if __name__ == '__main__': if __name__ == '__main__':
@ -52,7 +52,7 @@ if __name__ == '__main__':
try: try:
conf, app = config.Config.load_paste_app('reddwarf-taskmanager', conf, app = config.Config.load_paste_app('reddwarf-taskmanager',
options, args) options, args)
db_api.configure_db(conf) get_db_api().configure_db(conf)
server = service.Service.create(binary='reddwarf-taskmanager', server = service.Service.create(binary='reddwarf-taskmanager',
manager='reddwarf.taskmanager.manager.TaskManager', manager='reddwarf.taskmanager.manager.TaskManager',

View File

@ -36,7 +36,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version from reddwarf import version
from reddwarf.common import config from reddwarf.common import config
from reddwarf.common import wsgi from reddwarf.common import wsgi
from reddwarf.db import db_api from reddwarf.db import get_db_api
def create_options(parser): def create_options(parser):
@ -75,7 +75,7 @@ if __name__ == '__main__':
(options, args) = config.parse_options(oparser) (options, args) = config.parse_options(oparser)
config.Config.load_paste_config('reddwarf', options, args) config.Config.load_paste_config('reddwarf', options, args)
conf, app = config.Config.load_paste_app('reddwarf', options, args) conf, app = config.Config.load_paste_app('reddwarf', options, args)
db_api.configure_db(conf) get_db_api().configure_db(conf)
port = int(options.get('port') or conf['bind_port']) port = int(options.get('port') or conf['bind_port'])
if options['fork']: if options['fork']:
pid = os.fork() pid = os.fork()

View File

@ -39,7 +39,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version from reddwarf import version
from reddwarf.common import config from reddwarf.common import config
from reddwarf.common import service from reddwarf.common import service
from reddwarf.db import db_api from reddwarf.db import get_db_api
if __name__ == '__main__': if __name__ == '__main__':
@ -52,7 +52,7 @@ if __name__ == '__main__':
try: try:
conf, app = config.Config.load_paste_app('reddwarf-taskmanager', conf, app = config.Config.load_paste_app('reddwarf-taskmanager',
options, args) options, args)
db_api.configure_db(conf) get_db_api().configure_db(conf)
server = service.Service.create(binary='reddwarf-taskmanager') server = service.Service.create(binary='reddwarf-taskmanager')
service.serve(server) service.serve(server)
service.wait() service.wait()

View File

@ -21,9 +21,12 @@ from reddwarf.common import utils
from reddwarf.common import config from reddwarf.common import config
db_api = utils.import_object( db_api_opt = config.Config.get("db_api_implementation",
config.Config.get("db_api_implementation", "reddwarf.db.sqlalchemy.api")
"reddwarf.db.sqlalchemy.api"))
def get_db_api():
return utils.import_object(db_api_opt)
class Query(object): class Query(object):
@ -38,25 +41,29 @@ class Query(object):
self._query_func = query_func self._query_func = query_func
self._model = model self._model = model
self._conditions = conditions self._conditions = conditions
self.db_api = get_db_api()
def all(self): def all(self):
return db_api.list(self._query_func, self._model, **self._conditions) return self.db_api.list(self._query_func, self._model,
**self._conditions)
def count(self): def count(self):
return db_api.count(self._query_func, self._model, **self._conditions) return self.db_api.count(self._query_func, self._model,
**self._conditions)
def __iter__(self): def __iter__(self):
return iter(self.all()) return iter(self.all())
def update(self, **values): def update(self, **values):
db_api.update_all(self._query_func, self._model, self._conditions, self.db_api.update_all(self._query_func, self._model, self._conditions,
values) values)
def delete(self): def delete(self):
db_api.delete_all(self._query_func, self._model, **self._conditions) self.db_api.delete_all(self._query_func, self._model,
**self._conditions)
def limit(self, limit=200, marker=None, marker_column=None): def limit(self, limit=200, marker=None, marker_column=None):
return db_api.find_all_by_limit( return self.db_api.find_all_by_limit(
self._query_func, self._query_func,
self._model, self._model,
self._conditions, self._conditions,
@ -75,7 +82,7 @@ class Queryable(object):
def __getattr__(self, item): def __getattr__(self, item):
return lambda model, **conditions: Query( return lambda model, **conditions: Query(
model, query_func=getattr(db_api, item), **conditions) model, query_func=getattr(get_db_api(), item), **conditions)
db_query = Queryable() db_query = Queryable()

View File

@ -14,7 +14,8 @@
import logging import logging
from reddwarf import db from reddwarf.db import get_db_api
from reddwarf.db import db_query
from reddwarf.common import exception from reddwarf.common import exception
from reddwarf.common import models from reddwarf.common import models
from reddwarf.common import pagination from reddwarf.common import pagination
@ -36,19 +37,23 @@ class DatabaseModelBase(models.ModelBase):
raise exception.InvalidModelError(errors=instance.errors) raise exception.InvalidModelError(errors=instance.errors)
return instance return instance
@property
def db_api(self):
return get_db_api()
def save(self): def save(self):
if not self.is_valid(): if not self.is_valid():
raise exception.InvalidModelError(errors=self.errors) raise exception.InvalidModelError(errors=self.errors)
self['updated'] = utils.utcnow() self['updated'] = utils.utcnow()
LOG.debug(_("Saving %s: %s") % LOG.debug(_("Saving %s: %s") %
(self.__class__.__name__, self.__dict__)) (self.__class__.__name__, self.__dict__))
return db.db_api.save(self) return self.db_api.save(self)
def delete(self): def delete(self):
self['updated'] = utils.utcnow() self['updated'] = utils.utcnow()
LOG.debug(_("Deleting %s: %s") % LOG.debug(_("Deleting %s: %s") %
(self.__class__.__name__, self.__dict__)) (self.__class__.__name__, self.__dict__))
return db.db_api.delete(self) return self.db_api.delete(self)
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.merge_attributes(kwargs) self.merge_attributes(kwargs)
@ -70,11 +75,11 @@ class DatabaseModelBase(models.ModelBase):
@classmethod @classmethod
def get_by(cls, **kwargs): def get_by(cls, **kwargs):
return db.db_api.find_by(cls, **cls._process_conditions(kwargs)) return get_db_api().find_by(cls, **cls._process_conditions(kwargs))
@classmethod @classmethod
def find_all(cls, **kwargs): def find_all(cls, **kwargs):
return db.db_query.find_all(cls, **cls._process_conditions(kwargs)) return db_query.find_all(cls, **cls._process_conditions(kwargs))
@classmethod @classmethod
def _process_conditions(cls, raw_conditions): def _process_conditions(cls, raw_conditions):

View File

@ -21,11 +21,10 @@ Model classes that extend the instances functionality for MySQL instances.
import logging import logging
from reddwarf import db
from reddwarf.common import config from reddwarf.common import config
from reddwarf.common import exception from reddwarf.common import exception
from reddwarf.common import utils from reddwarf.common import utils
from reddwarf.db import get_db_api
from reddwarf.instance import models as base_models from reddwarf.instance import models as base_models
from reddwarf.guestagent.db import models as guest_models from reddwarf.guestagent.db import models as guest_models
from reddwarf.common.remote import create_guest_client from reddwarf.common.remote import create_guest_client
@ -121,11 +120,11 @@ class RootHistory(object):
def save(self): def save(self):
LOG.debug(_("Saving %s: %s") % (self.__class__.__name__, LOG.debug(_("Saving %s: %s") % (self.__class__.__name__,
self.__dict__)) self.__dict__))
return db.db_api.save(self) return get_db_api().save(self)
@classmethod @classmethod
def load(cls, context, instance_id): def load(cls, context, instance_id):
history = db.db_api.find_by(cls, id=instance_id) history = get_db_api().find_by(cls, id=instance_id)
return history return history
@classmethod @classmethod

View File

@ -151,7 +151,8 @@ def import_class(import_str):
__import__(mod_str) __import__(mod_str)
return getattr(sys.modules[mod_str], class_str) return getattr(sys.modules[mod_str], class_str)
except (ImportError, ValueError, AttributeError): except (ImportError, ValueError, AttributeError):
raise exception.NotFound('Class %s cannot be found' % class_str) raise exception.NotFound('Class from %s import %s cannot be found'
% (mod_str, class_str))
def import_object(import_str): def import_object(import_str):
@ -159,8 +160,11 @@ def import_object(import_str):
try: try:
__import__(import_str) __import__(import_str)
return sys.modules[import_str] return sys.modules[import_str]
except ImportError: except ImportError as ie:
return import_class(import_str) try:
return import_class(import_str)
except exception.NotFound:
raise ie
def isotime(at=None): def isotime(at=None):

View File

@ -30,11 +30,12 @@ def add_support_for_localization():
def initialize_reddwarf(config_file): def initialize_reddwarf(config_file):
# The test version of poll_until doesn't utilize LoopingCall. # The test version of poll_until doesn't utilize LoopingCall.
import optparse import optparse
from reddwarf.db import db_api from reddwarf.db import get_db_api
from reddwarf.common import config as rd_config from reddwarf.common import config as rd_config
from reddwarf.common import wsgi from reddwarf.common import wsgi
from reddwarf import version from reddwarf import version
db_api = get_db_api()
def create_options(parser): def create_options(parser):
parser.add_option('-p', '--port', dest="port", metavar="PORT", parser.add_option('-p', '--port', dest="port", metavar="PORT",
@ -62,9 +63,10 @@ def initialize_reddwarf(config_file):
def initialize_database(rd_conf): def initialize_database(rd_conf):
from reddwarf.db import db_api from reddwarf.db import get_db_api
from reddwarf.instance import models from reddwarf.instance import models
from reddwarf.db.sqlalchemy import session from reddwarf.db.sqlalchemy import session
db_api = get_db_api()
db_api.drop_db(rd_conf) # Destroys the database, if it exists. db_api.drop_db(rd_conf) # Destroys the database, if it exists.
db_api.db_sync(rd_conf) db_api.db_sync(rd_conf)
session.configure_db(rd_conf) session.configure_db(rd_conf)