b10-cfgmgr.py.in 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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 isc.log
  26. isc.log.init("b10-cfgmgr")
  27. from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError, logger
  28. from isc.log_messages.cfgmgr_messages import *
  29. isc.util.process.rename()
  30. # Import some paths from our configuration
  31. DATA_PATH = bind10_config.DATA_PATH
  32. PLUGIN_PATHS = bind10_config.PLUGIN_PATHS
  33. PREFIX = bind10_config.PREFIX
  34. DEFAULT_CONFIG_FILE = "b10-config.db"
  35. cm = None
  36. def parse_options(args=sys.argv[1:], Parser=OptionParser):
  37. parser = Parser()
  38. parser.add_option("-p", "--data-path", dest="data_path",
  39. help="Directory to search for configuration files " +
  40. "(default=" + DATA_PATH + ")", default=None)
  41. parser.add_option("-c", "--config-filename", dest="config_file",
  42. help="Configuration database filename " +
  43. "(default=" + DEFAULT_CONFIG_FILE + ")",
  44. default=None)
  45. parser.add_option("--clear-config", action="store_true",
  46. dest="clear_config", default=False,
  47. help="Back up the configuration file and start with " +
  48. "a clean one")
  49. (options, args) = parser.parse_args(args)
  50. if args:
  51. parser.error("No non-option arguments allowed")
  52. return options
  53. def signal_handler(signal, frame):
  54. global cm
  55. if cm:
  56. cm.running = False
  57. def load_plugins(path, cm):
  58. """Load all python files in the given path and treat them as plugins."""
  59. # Find the python files
  60. plugins = glob.glob(path + os.sep + '*.py')
  61. # Search this directory first, but leave the others there for the imports
  62. # of the modules
  63. sys.path.insert(0, path)
  64. try:
  65. for plugin in plugins:
  66. # Generate the name of the plugin
  67. filename = os.path.basename(plugin)
  68. name = filename[:-3]
  69. # Load it
  70. module = __import__(name)
  71. # Ask it to provide the spec and checking function
  72. (spec, check_func) = module.load()
  73. # And insert it into the manager
  74. cm.set_virtual_module(spec, check_func)
  75. finally:
  76. # Restore the search path
  77. sys.path = sys.path[1:]
  78. def determine_path_and_file(data_path_option, config_file_option):
  79. """Given the data path and config file as specified on the command line
  80. (or not specified, as may be the case), determine the full path and
  81. file to use when starting the config manager;
  82. - if neither are given, use defaults
  83. - if both are given, use both
  84. - if only data path is given, use default file in that path
  85. - if only file is given, use cwd() + file (if file happens to
  86. be an absolute file name, path will be ignored)
  87. Arguments are either a string, or None.
  88. Returns a tuple containing (result_path, result_file).
  89. """
  90. data_path = data_path_option
  91. config_file = config_file_option
  92. if config_file is None:
  93. config_file = DEFAULT_CONFIG_FILE
  94. if data_path is None:
  95. data_path = DATA_PATH
  96. else:
  97. if data_path is None:
  98. data_path = os.getcwd()
  99. return (data_path, config_file)
  100. def main():
  101. options = parse_options()
  102. global cm
  103. try:
  104. (data_path, config_file) = determine_path_and_file(options.data_path,
  105. options.config_file)
  106. cm = ConfigManager(data_path, config_file, None, options.clear_config)
  107. signal.signal(signal.SIGINT, signal_handler)
  108. signal.signal(signal.SIGTERM, signal_handler)
  109. cm.read_config()
  110. for ppath in PLUGIN_PATHS:
  111. load_plugins(ppath, cm)
  112. cm.notify_boss()
  113. cm.run()
  114. except SessionError as se:
  115. logger.fatal(CFGMGR_CC_SESSION_ERROR, se)
  116. return 1
  117. except KeyboardInterrupt as kie:
  118. logger.info(CFGMGR_STOPPED_BY_KEYBOARD)
  119. except ConfigManagerDataReadError as cmdre:
  120. logger.fatal(CFGMGR_DATA_READ_ERROR, cmdre)
  121. return 2
  122. return 0
  123. if __name__ == "__main__":
  124. sys.exit(main())