summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/Bcfg2/Server/models.py115
-rw-r--r--src/lib/Bcfg2/settings.py143
2 files changed, 123 insertions, 135 deletions
diff --git a/src/lib/Bcfg2/Server/models.py b/src/lib/Bcfg2/Server/models.py
index 370854881..51cc835dc 100644
--- a/src/lib/Bcfg2/Server/models.py
+++ b/src/lib/Bcfg2/Server/models.py
@@ -1,44 +1,64 @@
""" Django database models for all plugins """
import sys
-import copy
import logging
import Bcfg2.Options
import Bcfg2.Server.Plugins
from Bcfg2.Compat import walk_packages
-from django.db import models
LOGGER = logging.getLogger('Bcfg2.Server.models')
MODELS = []
-def load_models(plugins=None, cfile='/etc/bcfg2.conf', quiet=True):
+def _get_all_plugins():
+ rv = []
+ for submodule in walk_packages(path=Bcfg2.Server.Plugins.__path__,
+ prefix="Bcfg2.Server.Plugins."):
+ module = submodule[1].rsplit('.', 1)[-1]
+ if submodule[1] == "Bcfg2.Server.Plugins.%s" % module:
+ # we only include direct children of
+ # Bcfg2.Server.Plugins -- e.g., all_plugins should
+ # include Bcfg2.Server.Plugins.Cfg, but not
+ # Bcfg2.Server.Plugins.Cfg.CfgInfoXML
+ rv.append(module)
+ return rv
+
+
+_ALL_PLUGINS = _get_all_plugins()
+
+
+class _OptionContainer(object):
+ # we want to provide a different default plugin list --
+ # namely, _all_ plugins, so that the database is guaranteed to
+ # work, even if /etc/bcfg2.conf isn't set up properly
+ options = [
+ Bcfg2.Options.Option(
+ cf=('server', 'plugins'), type=Bcfg2.Options.Types.comma_list,
+ default=_ALL_PLUGINS, dest="models_plugins",
+ action=Bcfg2.Options.PluginsAction)]
+
+ @staticmethod
+ def options_parsed_hook():
+ # basic invocation to ensure that a default set of models is
+ # loaded, and thus that this module will always work.
+ load_models()
+
+Bcfg2.Options.get_parser().add_component(_OptionContainer)
+
+
+def load_models(plugins=None):
""" load models from plugins specified in the config """
+ # this has to be imported after options are parsed, because Django
+ # finalizes its settings as soon as it's loaded, which means that
+ # if we import this before Bcfg2.settings has been populated,
+ # Django gets a null configuration, and subsequent updates to
+ # Bcfg2.settings won't help.
+ from django.db import models
global MODELS
- if plugins is None:
- # we want to provide a different default plugin list --
- # namely, _all_ plugins, so that the database is guaranteed to
- # work, even if /etc/bcfg2.conf isn't set up properly
- plugin_opt = copy.deepcopy(Bcfg2.Options.SERVER_PLUGINS)
- all_plugins = []
- for submodule in walk_packages(path=Bcfg2.Server.Plugins.__path__,
- prefix="Bcfg2.Server.Plugins."):
- module = submodule[1].rsplit('.', 1)[-1]
- if submodule[1] == "Bcfg2.Server.Plugins.%s" % module:
- # we only include direct children of
- # Bcfg2.Server.Plugins -- e.g., all_plugins should
- # include Bcfg2.Server.Plugins.Cfg, but not
- # Bcfg2.Server.Plugins.Cfg.CfgInfoXML
- all_plugins.append(module)
- plugin_opt.default = all_plugins
-
- setup = Bcfg2.Options.get_option_parser()
- setup.add_option("plugins", plugin_opt)
- setup.add_option("configfile", Bcfg2.Options.CFILE)
- setup.reparse(argv=[Bcfg2.Options.CFILE.cmd, cfile])
- plugins = setup['plugins']
+ if not plugins:
+ plugins = Bcfg2.Options.setup.models_plugins
if MODELS:
# load_models() has been called once, so first unload all of
@@ -49,45 +69,22 @@ def load_models(plugins=None, cfile='/etc/bcfg2.conf', quiet=True):
delattr(sys.modules[__name__], model)
MODELS = []
- for plugin in plugins:
- try:
- mod = getattr(__import__("Bcfg2.Server.Plugins.%s" %
- plugin).Server.Plugins, plugin)
- except ImportError:
- try:
- err = sys.exc_info()[1]
- mod = __import__(plugin)
- except: # pylint: disable=W0702
- if plugins != plugin_opt.default:
- # only produce errors if the default plugin list
- # was not used -- i.e., if the config file was set
- # up. don't produce errors when trying to load
- # all plugins, IOW. the error from the first
- # attempt to import is probably more accurate than
- # the second attempt.
- LOGGER.error("Failed to load plugin %s: %s" % (plugin,
- err))
- continue
+ for mod in plugins:
for sym in dir(mod):
obj = getattr(mod, sym)
- if hasattr(obj, "__bases__") and models.Model in obj.__bases__:
+ if isinstance(obj, type) and issubclass(obj, models.Model):
setattr(sys.modules[__name__], sym, obj)
MODELS.append(sym)
-# basic invocation to ensure that a default set of models is loaded,
-# and thus that this module will always work.
-load_models(quiet=True)
-
-
-class InternalDatabaseVersion(models.Model):
- """ Object that tell us to which version the database is """
- version = models.IntegerField()
- updated = models.DateTimeField(auto_now_add=True)
+ class InternalDatabaseVersion(models.Model):
+ """ Object that tell us to which version the database is """
+ version = models.IntegerField()
+ updated = models.DateTimeField(auto_now_add=True)
- def __str__(self):
- return "version %d updated the %s" % (self.version,
+ def __str__(self):
+ return "version %d updated %s" % (self.version,
self.updated.isoformat())
- class Meta: # pylint: disable=C0111,W0232
- app_label = "reports"
- get_latest_by = "version"
+ class Meta: # pylint: disable=C0111,W0232
+ app_label = "reports"
+ get_latest_by = "version"
diff --git a/src/lib/Bcfg2/settings.py b/src/lib/Bcfg2/settings.py
index c06074845..a26330a79 100644
--- a/src/lib/Bcfg2/settings.py
+++ b/src/lib/Bcfg2/settings.py
@@ -1,7 +1,6 @@
""" Django settings for the Bcfg2 server """
import os
-import sys
import Bcfg2.Options
try:
@@ -17,7 +16,7 @@ try:
except ImportError:
HAS_SOUTH = False
-DATABASES = dict()
+DATABASES = dict(default=dict())
# Django < 1.2 compat
DATABASE_ENGINE = None
@@ -29,85 +28,13 @@ DATABASE_PORT = None
TIME_ZONE = None
-DEBUG = False
-TEMPLATE_DEBUG = DEBUG
+TEMPLATE_DEBUG = DEBUG = False
ALLOWED_HOSTS = ['*']
MEDIA_URL = '/site_media/'
-
-def _default_config():
- """ get the default config file. returns /etc/bcfg2-web.conf,
- UNLESS /etc/bcfg2.conf exists AND /etc/bcfg2-web.conf does not
- exist. """
- setup = Bcfg2.Options.get_option_parser()
- setup.add_option("configfile", Bcfg2.Options.CFILE)
- setup.add_option("web_configfile", Bcfg2.Options.WEB_CFILE)
- setup.reparse(argv=sys.argv[1:], do_getopt=False)
- if (not os.path.exists(setup['web_configfile']) and
- os.path.exists(setup['configfile'])):
- return setup['configfile']
- else:
- return setup['web_configfile']
-
-DEFAULT_CONFIG = _default_config()
-
-
-def read_config(cfile=DEFAULT_CONFIG, repo=None):
- """ read the config file and set django settings based on it """
- # pylint: disable=W0602,W0603
- global DATABASE_ENGINE, DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD, \
- DATABASE_HOST, DATABASE_PORT, DEBUG, TEMPLATE_DEBUG, TIME_ZONE, \
- MEDIA_URL
- # pylint: enable=W0602,W0603
-
- if not os.path.exists(cfile) and os.path.exists(DEFAULT_CONFIG):
- print("%s does not exist, using %s for database configuration" %
- (cfile, DEFAULT_CONFIG))
- cfile = DEFAULT_CONFIG
-
- # when setting a different config file, it has to be set in either
- # sys.argv or in the OptionSet() constructor AS WELL AS the argv
- # that's passed to setup.parse()
- argv = [Bcfg2.Options.CFILE.cmd, cfile,
- Bcfg2.Options.WEB_CFILE.cmd, cfile]
- setup = Bcfg2.Options.get_option_parser()
- setup.add_options(Bcfg2.Options.DATABASE_COMMON_OPTIONS)
- setup.add_option("repo", Bcfg2.Options.SERVER_REPOSITORY)
- setup.reparse(argv=argv)
-
- if repo is None:
- repo = setup['repo']
-
- DATABASES['default'] = \
- dict(ENGINE="django.db.backends.%s" % setup['db_engine'],
- NAME=setup['db_name'],
- USER=setup['db_user'],
- PASSWORD=setup['db_password'],
- HOST=setup['db_host'],
- PORT=setup['db_port'])
-
- # dropping the version check. This was added in 1.1.2
- TIME_ZONE = setup['time_zone']
-
- DEBUG = setup['django_debug']
- TEMPLATE_DEBUG = DEBUG
- if DEBUG:
- print("Warning: Setting web_debug to True causes extraordinary memory "
- "leaks. Only use this setting if you know what you're doing.")
-
- if setup['web_prefix']:
- MEDIA_URL = setup['web_prefix'].rstrip('/') + MEDIA_URL
- else:
- MEDIA_URL = '/site_media/'
-
-# initialize settings from /etc/bcfg2-web.conf or /etc/bcfg2.conf, or
-# set up basic defaults. this lets manage.py work in all cases
-read_config()
-
-ADMINS = (('Root', 'root'))
-MANAGERS = ADMINS
+MANAGERS = ADMINS = (('Root', 'root'))
# Language code for this installation. All choices can be found here:
# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
@@ -189,3 +116,67 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.media',
'django.core.context_processors.request'
)
+
+
+def read_config():
+ """ read the config file and set django settings based on it """
+ global DEBUG, TEMPLATE_DEBUG, TIME_ZONE, MEDIA_URL # pylint: disable=W0603
+
+ DATABASES['default'] = \
+ dict(ENGINE="django.db.backends.%s" % Bcfg2.Options.setup.db_engine,
+ NAME=Bcfg2.Options.setup.db_name,
+ USER=Bcfg2.Options.setup.db_user,
+ PASSWORD=Bcfg2.Options.setup.db_password,
+ HOST=Bcfg2.Options.setup.db_host,
+ PORT=Bcfg2.Options.setup.db_port)
+
+ TIME_ZONE = Bcfg2.Options.setup.timezone
+
+ TEMPLATE_DEBUG = DEBUG = Bcfg2.Options.setup.web_debug
+ if DEBUG:
+ print("Warning: Setting web_debug to True causes extraordinary memory "
+ "leaks. Only use this setting if you know what you're doing.")
+
+ if Bcfg2.Options.setup.web_prefix:
+ MEDIA_URL = Bcfg2.Options.setup.web_prefix.rstrip('/') + MEDIA_URL
+
+
+class _OptionContainer(object):
+ options = [
+ Bcfg2.Options.Common.repository,
+ Bcfg2.Options.PathOption(
+ '-W', '--web-config', cf=('reporting', 'config'),
+ default="/etc/bcfg2-web.conf",
+ action=Bcfg2.Options.ConfigFileAction,
+ help='Web interface configuration file'),
+ Bcfg2.Options.Option(
+ cf=('database', 'engine'), default='sqlite3',
+ help='Database engine', dest='db_engine'),
+ Bcfg2.Options.Option(
+ cf=('database', 'name'), default='<repository>/etc/bcfg2.sqlite',
+ help="Database name", dest="db_name"),
+ Bcfg2.Options.Option(
+ cf=('database', 'user'), help='Database username', dest='db_user'),
+ Bcfg2.Options.Option(
+ cf=('database', 'password'), help='Database password',
+ dest='db_password'),
+ Bcfg2.Options.Option(
+ cf=('database', 'host'), help='Database host', dest='db_host'),
+ Bcfg2.Options.Option(
+ cf=('database', 'port'), help='Database port', dest='db_port'),
+ Bcfg2.Options.Option(
+ cf=('reporting', 'timezone'), help='Django timezone'),
+ Bcfg2.Options.BooleanOption(
+ cf=('reporting', 'web_debug'), help='Django debug'),
+ Bcfg2.Options.Option(
+ cf=('reporting', 'web_prefix'), help='Web prefix')]
+
+ @staticmethod
+ def options_parsed_hook():
+ """ initialize settings from /etc/bcfg2-web.conf or
+ /etc/bcfg2.conf, or set up basic defaults. this lets
+ manage.py work in all cases """
+ read_config()
+
+
+Bcfg2.Options.get_parser().add_component(_OptionContainer)