123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import os
- import os.path
-
-
- ##@brief basename of multisite process conf folder
- #@todo find a better place to declare it
- SERVER_CONFD = 'server_conf.d' #Should be accessible elsewhere
- ##@brief basename of lodelsites site conf folder
- #@todo find a better place to declare it
- LODELSITES_CONFD = 'lodelsites.conf.d' #Should be accessible elsewhere
-
- ##@brief A cache allowing a fast application exposure
- #
- #This dict contains reference on interface module of each handled site in
- #order to quickly call the application (PEP 3333) function of concerned site
- FAST_APP_EXPOSAL_CACHE = dict()
-
- try:
- from lodel.context import LodelContext
- except ImportError:
- LODEL_BASE_DIR = os.path.dirname(
- os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- from lodel.context import LodelContext, ContextError
-
-
- import lodel.buildconf
-
- ##@brief Stores the main function of a multisite loader
-
- ##@brief Function designed to bootstrap a multisite runner
- #
- #Handles lodelsites site loading, handled site list fecth & load
- #@note called at end of file
- #
- #@todo evaluate if it is safe to assume that lodelsites_datapath = os.getcwd()
- #@todo get rid of hardcoded stuff (like shortname fieldname)
- #@todo use the dyncode getter when it will be available (replaced by
- #the string SUPERDYNCODE_ACCESSOR.Lodelsite for the moment)
- #@return lodelsites instance name
- def main():
- #Set current context to reserved loader context
- from lodel import bootstrap
- bootstrap.bootstrap('__loader__')
- LodelContext.expose_modules(globals(), {
- 'lodel.settings': ['Settings']})
- lodelsites_name = Settings.sitename
- del(globals()['Settings'])
-
- #bootstraping the lodelsites instance
- LodelContext.new(lodelsites_name)
- LodelContext.set(lodelsites_name)
- #in lodelsites context
- LodelContext.expose_modules(globals(), {
- 'lodel.settings.settings': [('Settings', 'settings_loader')],
- 'lodel.plugins.multisite.confspecs': 'multisite_confspecs',
- 'lodel.plugins.multisite.confspecs': 'multisite_confspecs'})
-
- settings_loader(lodel.buildconf.LODELSITE_CONFDIR,
- multisite_confspecs.LODEL2_CONFSPECS, True)
- del(globals()['settings_loader'])
- LodelContext.expose_modules(globals(), {
- 'lodel.settings': ['Settings']})
-
- LodelContext.expose_dyncode(globals())
-
- LodelContext.expose_modules(globals(), {
- 'lodel.logger': 'logger',
- 'lodel.plugin.hooks': ['LodelHook'],
- 'lodel.plugin': ['Plugin']})
- Plugin.load_all()
- LodelHook.call_hook('lodel2_bootstraped', '__main__', None)
-
- lodelsite_leo = leapi_dyncode.Lodelsite #hardcoded leo name
- LodelContext.expose_modules(globals(), {
- 'lodel.leapi.query': ['LeGetQuery'],
- })
- #the line bellow you will find another harcoded thing : the shortname
- #fieldname for a lodelsite
- handled_sites = LeGetQuery(lodelsite_leo, query_filters = [],
- field_list = ['shortname']).execute()
- #Now that we have the handled sitenames list we can go back to
- #loader context and clean it
- if handled_sites is not None:
- LodelContext.set(None)
- for mname in ['LeGetQuery', 'Settings', 'LodelHook', 'Plugin', 'logger']:
- del(globals()[mname])
- #Loading handled sites
- for handled_sitename in [s['shortname'] for s in handled_sites]:
- datapath = os.path.join(lodelsites_datapath, handled_sitename)
- site_load(datapath) #using default conf.d configuration dirname
- else:
- logger.warning("No handled sites !")
- LodelContext.set(None)
- return lodelsites_name
-
-
- ##@brief Load a site
- #
- #Apply a common (as MONOSITE) loading process to a site :
- #1. Conf preload
- #2. Plugins preload
- #3. Conf loading
- #4. starting plugins & hooks
- #@warning At this point we need a uniq identifier for the site (using it
- #as key for contexts & FAST_APP_EXPOSAL_CACHE). To achieve this we use
- #the data_path basename. It should works for handled sites and for the
- #lodelsites instance
- #@param data_path str : path to the datas directory (containing the confdir)
- #@param confdir_basename str : the basename of the site confdir
- #@param lodelsites_instance bool : if true we are loading the lodelsites
- #instance of the multisite (allow to load the good confspecs)
- #
- #@todo For now the interface plugin name for sites is hardcoded (set to
- #webui). It HAS TO be loaded from settings. But it is a bit complicated,
- #we have to get the plugin's module name abstracted from context :
- #lodel.something but if we ask directly to Plugin class the module name
- #it will return something like : lodelsites.sitename.something...
- #
- #@todo there is a quick & dirty workarround with comments saying that it
- #avoid context escape via hooks. We have to understand why and how and then
- #replace the workarround by a real solution !
- def site_load(data_path, confdir_basename = 'conf.d', lodelsites_instance = False):
- #args check
- if confdir_basename != os.path.basename(confdir_basename):
- LodelFatalError('Bad argument given to site_load(). This really \
- sux !')
- #Determining uniq sitename from data_path
- data_path = data_path.rstrip('/') #else basename returns ''
- ctx_name = os.path.basename(data_path)
- #Immediately switching to the context
- LodelContext.new(ctx_name)
- LodelContext.set(ctx_name)
- os.chdir(data_path) #Now the confdir is ./$condir_basename
- #Loading settings for current site
- LodelContext.expose_modules(globals(), {
- 'lodel.settings.settings': [('Settings', 'settings_preloader')]})
- if settings_preloader.started():
- msg = 'Settings seems to be allready started for "%s". \
- This should not append !' % ctx_name
- #switch back to loader context in order to log & raise
- LodelContext.set(None)
- logger.critical(msg)
- raise LodelFatalError(msg)
- if lodelsites_instance:
- settings_preloader(os.path.join('./', confdir_basename), )
- else:
- settings_preloader(os.path.join('./', confdir_basename))
- #
- #Loading hooks & plugins
- #
- LodelContext.expose_modules(globals(), {
- 'lodel.plugin': ['Plugin', 'LodelHook'],
- 'lodel.logger': 'logger',
- 'lodel.plugin.core_hooks': 'core_hooks',
- 'lodel.plugin.core_scripts': 'core_scripts'
- })
- Plugin.load_all() #Then all plugins & hooks are loaded
- #triggering dyncode datasource instanciations
- LodelHook.call_hook('lodel2_plugins_loaded', '__main__', None)
- #triggering boostrapped hook
- LodelHook.call_hook('lodel2_bootstraped', '__main__', None)
- #Populating FAST_APP_EXPOSAL_CACHE
- #
- #WARNING !!!! Hardcoded interface name ! Here we have to find the
- #interface plugin name in order to populate the cache properly
- FAST_APP_EXPOSAL_CACHE[ctx_name] = LodelContext.module(
- 'lodel.plugins.webui.run')
- #a dirty & quick attempt to fix context unwanted exite via
- #hooks
- for name in ( 'LodelHook', 'core_hooks', 'core_scripts',
- 'Settings', 'settings', 'logger', 'Plugin'):
- del(globals()[name])
- #site fully loaded, switching back to loader context
- LodelContext.set(None)
- #lodel2 multisite instances are loaded and ready to run
-
|