#!@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@@') import bind10_config from isc.cc import SessionError import isc.util.process import signal import os from optparse import OptionParser import glob import os.path import isc.log isc.log.init("b10-cfgmgr") from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError, logger from isc.log_messages.cfgmgr_messages import * isc.util.process.rename() # Import some paths from our configuration DATA_PATH = bind10_config.DATA_PATH PLUGIN_PATHS = bind10_config.PLUGIN_PATHS PREFIX = bind10_config.PREFIX 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=None) parser.add_option("-c", "--config-filename", dest="config_file", help="Configuration database filename " + "(default=" + DEFAULT_CONFIG_FILE + ")", default=None) parser.add_option("--clear-config", action="store_true", dest="clear_config", default=False, help="Back up the configuration file and start with " + "a clean one") (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 determine_path_and_file(data_path_option, config_file_option): """Given the data path and config file as specified on the command line (or not specified, as may be the case), determine the full path and file to use when starting the config manager; - if neither are given, use defaults - if both are given, use both - if only data path is given, use default file in that path - if only file is given, use cwd() + file (if file happens to be an absolute file name, path will be ignored) Arguments are either a string, or None. Returns a tuple containing (result_path, result_file). """ data_path = data_path_option config_file = config_file_option if config_file is None: config_file = DEFAULT_CONFIG_FILE if data_path is None: data_path = DATA_PATH else: if data_path is None: data_path = os.getcwd() return (data_path, config_file) def main(): options = parse_options() global cm try: (data_path, config_file) = determine_path_and_file(options.data_path, options.config_file) cm = ConfigManager(data_path, config_file, None, options.clear_config) 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: logger.fatal(CFGMGR_CC_SESSION_ERROR, se) return 1 except KeyboardInterrupt as kie: logger.info(CFGMGR_STOPPED_BY_KEYBOARD) except ConfigManagerDataReadError as cmdre: logger.fatal(CFGMGR_DATA_READ_ERROR, cmdre) return 2 return 0 if __name__ == "__main__": sys.exit(main())