#!@PYTHON@ # Copyright (C) 2010 Internet Systems Consortium. # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import sys; sys.path.append ('@@PYTHONPATH@@') from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError from isc.cc import SessionError import isc.util.process import signal import os from optparse import OptionParser import glob import os.path isc.util.process.rename() # If B10_FROM_SOURCE is set in the environment, we use data files # from a directory relative to the value of that variable, or, if defined, # relative to the value of B10_FROM_SOURCE_LOCALSTATEDIR. Otherwise # we use the ones installed on the system. # B10_FROM_SOURCE_LOCALSTATEDIR is specifically intended to be used for # tests where we want to use variuos types of configuration within the test # environment. (We may want to make it even more generic so that the path is # passed from the boss process) if "B10_FROM_SOURCE" in os.environ: if "B10_FROM_SOURCE_LOCALSTATEDIR" in os.environ: DATA_PATH = os.environ["B10_FROM_SOURCE_LOCALSTATEDIR"] else: DATA_PATH = os.environ["B10_FROM_SOURCE"] PLUGIN_PATH = [DATA_PATH + '/src/bin/cfgmgr/plugins'] else: PREFIX = "@prefix@" DATA_PATH = "@localstatedir@/@PACKAGE@".replace("${prefix}", PREFIX) PLUGIN_PATHS = ["@prefix@/share/@PACKAGE@/config_plugins"] DEFAULT_CONFIG_FILE = "b10-config.db" cm = None def parse_options(args=sys.argv[1:], Parser=OptionParser): parser = Parser() parser.add_option("-p", "--data-path", dest="data_path", help="Directory to search for configuration files " + "(default=" + DATA_PATH + ")", default=DATA_PATH) parser.add_option("-c", "--config-filename", dest="config_file", help="Configuration database filename " + "(default=" + DEFAULT_CONFIG_FILE + ")", default=DEFAULT_CONFIG_FILE) (options, args) = parser.parse_args(args) if args: parser.error("No non-option arguments allowed") return options def signal_handler(signal, frame): global cm if cm: cm.running = False def load_plugins(path, cm): """Load all python files in the given path and treat them as plugins.""" # Find the python files plugins = glob.glob(path + os.sep + '*.py') # Search this directory first, but leave the others there for the imports # of the modules sys.path.insert(0, path) try: for plugin in plugins: # Generate the name of the plugin filename = os.path.basename(plugin) name = filename[:-3] # Load it module = __import__(name) # Ask it to provide the spec and checking function (spec, check_func) = module.load() # And insert it into the manager cm.set_virtual_module(spec, check_func) finally: # Restore the search path sys.path = sys.path[1:] def main(): options = parse_options() global cm try: cm = ConfigManager(options.data_path, options.config_file) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) cm.read_config() for ppath in PLUGIN_PATHS: load_plugins(ppath, cm) cm.notify_boss() cm.run() except SessionError as se: print("[b10-cfgmgr] Error creating config manager, " "is the command channel daemon running?") return 1 except KeyboardInterrupt as kie: print("[b10-cfgmgr] Interrupted, exiting") except ConfigManagerDataReadError as cmdre: print("[b10-cfgmgr] " + str(cmdre)) return 2 return 0 if __name__ == "__main__": sys.exit(main())