b10-cfgmgr.py.in 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #!@PYTHON@
  2. # Copyright (C) 2010 Internet Systems Consortium.
  3. #
  4. # Permission to use, copy, modify, and distribute this software for any
  5. # purpose with or without fee is hereby granted, provided that the above
  6. # copyright notice and this permission notice appear in all copies.
  7. #
  8. # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
  9. # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
  10. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  11. # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
  12. # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
  13. # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  14. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  15. # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. import sys; sys.path.append ('@@PYTHONPATH@@')
  17. import bind10_config
  18. from isc.cc import SessionError
  19. import isc.util.process
  20. import signal
  21. import os
  22. from optparse import OptionParser
  23. import glob
  24. import os.path
  25. import imp
  26. import isc.log
  27. isc.log.init("b10-cfgmgr", buffer=True)
  28. from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError, logger
  29. from isc.log_messages.cfgmgr_messages import *
  30. import isc.util.traceback_handler
  31. isc.util.process.rename()
  32. # Import some paths from our configuration
  33. DATA_PATH = bind10_config.DATA_PATH
  34. PLUGIN_PATHS = bind10_config.PLUGIN_PATHS
  35. PREFIX = bind10_config.PREFIX
  36. DEFAULT_CONFIG_FILE = "b10-config.db"
  37. cm = None
  38. def parse_options(args=sys.argv[1:], Parser=OptionParser):
  39. parser = Parser()
  40. parser.add_option("-p", "--data-path", dest="data_path",
  41. help="Directory to search for configuration files " +
  42. "(default=" + DATA_PATH + ")", default=None)
  43. parser.add_option("-c", "--config-filename", dest="config_file",
  44. help="Configuration database filename " +
  45. "(default=" + DEFAULT_CONFIG_FILE + ")",
  46. default=None)
  47. parser.add_option("--clear-config", action="store_true",
  48. dest="clear_config", default=False,
  49. help="Back up the configuration file and start with " +
  50. "a clean one")
  51. (options, args) = parser.parse_args(args)
  52. if args:
  53. parser.error("No non-option arguments allowed")
  54. return options
  55. def signal_handler(signal, frame):
  56. global cm
  57. if cm:
  58. cm.running = False
  59. def load_plugins(path, cm):
  60. """Load all python files in the given path and treat them as plugins."""
  61. # Find the python files
  62. plugins = glob.glob(path + os.sep + '*.py')
  63. for plugin in plugins:
  64. # Generate the name of the plugin
  65. filename = os.path.basename(plugin)
  66. name = filename[:-3]
  67. # Load it
  68. module = imp.load_source(name, plugin)
  69. # Ask it to provide the spec and checking function
  70. (spec, check_func) = module.load()
  71. # And insert it into the manager
  72. cm.set_virtual_module(spec, check_func)
  73. def determine_path_and_file(data_path_option, config_file_option):
  74. """Given the data path and config file as specified on the command line
  75. (or not specified, as may be the case), determine the full path and
  76. file to use when starting the config manager;
  77. - if neither are given, use defaults
  78. - if both are given, use both
  79. - if only data path is given, use default file in that path
  80. - if only file is given, use cwd() + file (if file happens to
  81. be an absolute file name, path will be ignored)
  82. Arguments are either a string, or None.
  83. Returns a tuple containing (result_path, result_file).
  84. """
  85. data_path = data_path_option
  86. config_file = config_file_option
  87. if config_file is None:
  88. config_file = DEFAULT_CONFIG_FILE
  89. if data_path is None:
  90. data_path = DATA_PATH
  91. else:
  92. if data_path is None:
  93. data_path = os.getcwd()
  94. return (data_path, config_file)
  95. def main():
  96. options = parse_options()
  97. global cm
  98. try:
  99. (data_path, config_file) = determine_path_and_file(options.data_path,
  100. options.config_file)
  101. cm = ConfigManager(data_path, config_file, None, options.clear_config)
  102. signal.signal(signal.SIGINT, signal_handler)
  103. signal.signal(signal.SIGTERM, signal_handler)
  104. cm.read_config()
  105. for ppath in PLUGIN_PATHS:
  106. load_plugins(ppath, cm)
  107. cm.notify_b10_init()
  108. cm.run()
  109. except SessionError as se:
  110. logger.fatal(CFGMGR_CC_SESSION_ERROR, se)
  111. return 1
  112. except KeyboardInterrupt as kie:
  113. logger.info(CFGMGR_STOPPED_BY_KEYBOARD)
  114. except ConfigManagerDataReadError as cmdre:
  115. logger.fatal(CFGMGR_DATA_READ_ERROR, cmdre)
  116. return 2
  117. return 0
  118. if __name__ == "__main__":
  119. sys.exit(isc.util.traceback_handler.traceback_handler(main))