]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[master] Merge branch 'trac1451'
authorJelte Jansen <jelte@isc.org>
Tue, 20 Dec 2011 13:44:27 +0000 (14:44 +0100)
committerJelte Jansen <jelte@isc.org>
Tue, 20 Dec 2011 13:44:27 +0000 (14:44 +0100)
Conflicts:
src/bin/Makefile.am

1  2 
configure.ac
src/bin/Makefile.am
src/bin/ddns/ddns.py.in
src/bin/ddns/tests/Makefile.am

diff --cc configure.ac
index 671a9b6769681c7607df76263367a22f30fc4e79,0e5df1759b6106886822e01b920b09c3397f37df..9dc530ec5a5a09c958a4ca33496baa2d7bcc0a24
@@@ -890,10 -890,10 +890,12 @@@ AC_CONFIG_FILES([Makefil
                   src/bin/auth/Makefile
                   src/bin/auth/tests/Makefile
                   src/bin/auth/benchmarks/Makefile
+                  src/bin/ddns/Makefile
+                  src/bin/ddns/tests/Makefile
                   src/bin/dhcp6/Makefile
                   src/bin/dhcp6/tests/Makefile
 +               src/bin/dhcp4/Makefile
 +               src/bin/dhcp4/tests/Makefile
                   src/bin/resolver/Makefile
                   src/bin/resolver/tests/Makefile
                   src/bin/sockcreator/Makefile
index ba7ae812aa392c63fb41df07f42df7056337e734,1dacd9e1f3d72d780cd1a0566d923ad91f4c976f..7c6cdb8bded680b8dd1d867b43d1ea2359d77e83
@@@ -1,4 -1,4 +1,4 @@@
- SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
-       usermgr zonemgr stats tests resolver sockcreator dhcp6 dhcp4
+ SUBDIRS = bind10 bindctl cfgmgr ddns loadzone msgq host cmdctl auth xfrin \
 -      xfrout usermgr zonemgr stats tests resolver sockcreator dhcp6
++      xfrout usermgr zonemgr stats tests resolver sockcreator dhcp4 dhcp6
  
  check-recursive: all-recursive
index 0000000000000000000000000000000000000000,8320ded4cf86f87fa9b9a6410750c9dfc5072d18..e5ce31d48333ca391d27519bc248f8d2b47ae5ab
mode 000000,100755..100755
--- /dev/null
@@@ -1,0 -1,209 +1,209 @@@
 -if "B10_FROM_BUILD" in os.environ:
 -    DATA_PATH = os.environ['B10_FROM_BUILD'] + "/src/bin/ddns"
+ #!@PYTHON@
+ # Copyright (C) 2011  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 isc
+ import bind10_config
+ from isc.dns import *
+ from isc.config.ccsession import *
+ from isc.cc import SessionError, SessionTimeout
+ import isc.util.process
+ from isc.log_messages.ddns_messages import *
+ from optparse import OptionParser, OptionValueError
+ import os
+ import signal
+ isc.log.init("b10-ddns")
+ logger = isc.log.Logger("ddns")
+ DATA_PATH = bind10_config.DATA_PATH
++if "B10_FROM_SOURCE" in os.environ:
++    DATA_PATH = os.environ['B10_FROM_SOURCE'] + "/src/bin/ddns"
+ SPECFILE_LOCATION = DATA_PATH + "/ddns.spec"
+ isc.util.process.rename()
+ class DDNSConfigError(Exception):
+     '''An exception indicating an error in updating ddns configuration.
+     This exception is raised when the ddns process encounters an error in
+     handling configuration updates.  Not all syntax error can be caught
+     at the module-CC layer, so ddns needs to (explicitly or implicitly)
+     validate the given configuration data itself.  When it finds an error
+     it raises this exception (either directly or by converting an exception
+     from other modules) as a unified error in configuration.
+     '''
+     pass
+ class DDNSSessionError(Exception):
+     '''An exception raised for some unexpected events during a ddns session.
+     '''
+     pass
+ class DDNSSession:
+     '''Class to handle one DDNS update'''
+     def __init__(self):
+         '''Initialize a DDNS Session'''
+         pass
+ class DDNSServer:
+     def __init__(self, cc_session=None):
+         '''
+         Initialize the DDNS Server.
+         This sets up a ModuleCCSession for the BIND 10 system.
+         Parameters:
+         cc_session: If None (default), a new ModuleCCSession will be set up.
+                     If specified, the given session will be used. This is
+                     mainly used for testing.
+         '''
+         if cc_session is not None:
+             self._cc = cc_session
+         else:
+             self._cc = isc.config.ModuleCCSession(SPECFILE_LOCATION,
+                                                   self.config_handler,
+                                                   self.command_handler)
+         self._config_data = self._cc.get_full_config()
+         self._cc.start()
+         self._shutdown = False
+     def config_handler(self, new_config):
+         '''Update config data.'''
+         answer = create_answer(0)
+         return answer
+     def command_handler(self, cmd, args):
+         '''
+         Handle a CC session command, as sent from bindctl or other
+         BIND 10 modules.
+         '''
+         if cmd == "shutdown":
+             logger.info(DDNS_RECEIVED_SHUTDOWN_COMMAND)
+             self.trigger_shutdown()
+             answer = create_answer(0)
+         else:
+             answer = create_answer(1, "Unknown command: " + str(cmd))
+         return answer
+     def trigger_shutdown(self):
+         '''Initiate a shutdown sequence.
+         This method is expected to be called in various ways including
+         in the middle of a signal handler, and is designed to be as simple
+         as possible to minimize side effects.  Actual shutdown will take
+         place in a normal control flow.
+         '''
+         logger.info(DDNS_SHUTDOWN)
+         self._shutdown = True
+     def shutdown_cleanup(self):
+         '''
+         Perform any cleanup that is necessary when shutting down the server.
+         Do NOT call this to initialize shutdown, use trigger_shutdown().
+         Currently, it does nothing, but cleanup routines are expected.
+         '''
+         pass
+     def run(self):
+         '''
+         Get and process all commands sent from cfgmgr or other modules.
+         This loops waiting for events until self.shutdown() has been called.
+         '''
+         logger.info(DDNS_RUNNING)
+         while not self._shutdown:
+             # We do not catch any exceptions here right now, but this would
+             # be a good place to catch any exceptions that b10-ddns can
+             # recover from. We currently have no exception hierarchy to
+             # make such a distinction easily, but once we do, this would
+             # be the place to catch.
+             self._cc.check_command(False)
+         self.shutdown_cleanup()
+         logger.info(DDNS_STOPPED)
+ def create_signal_handler(ddns_server):
+     '''
+     This creates a signal_handler for use in set_signal_handler, which
+     shuts down the given DDNSServer (or any object that has a shutdown()
+     method)
+     '''
+     def signal_handler(signal, frame):
+         '''
+         Handler for process signals. Since only signals to shut down are sent
+         here, the actual signal is not checked and the server is simply shut
+         down.
+         '''
+         ddns_server.trigger_shutdown()
+     return signal_handler
+ def set_signal_handler(signal_handler):
+     '''
+     Sets the signal handler(s).
+     '''
+     signal.signal(signal.SIGTERM, signal_handler)
+     signal.signal(signal.SIGINT, signal_handler)
+ def set_cmd_options(parser):
+     '''
+     Helper function to set command-line options
+     '''
+     parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
+             help="display more about what is going on")
+ def main(ddns_server=None):
+     '''
+     The main function.
+     Parameters:
+     ddns_server: If None (default), a DDNSServer object is initialized.
+                  If specified, the given DDNSServer will be used. This is
+                  mainly used for testing.
+     cc_session: If None (default), a new ModuleCCSession will be set up.
+                 If specified, the given session will be used. This is
+                 mainly used for testing.
+     '''
+     try:
+         parser = OptionParser()
+         set_cmd_options(parser)
+         (options, args) = parser.parse_args()
+         if options.verbose:
+             print("[b10-ddns] Warning: -v verbose option is ignored at this point.")
+         if ddns_server is None:
+             ddns_server = DDNSServer()
+         set_signal_handler(create_signal_handler(ddns_server))
+         ddns_server.run()
+     except KeyboardInterrupt:
+         logger.info(DDNS_STOPPED_BY_KEYBOARD)
+     except SessionError as e:
+         logger.error(DDNS_CC_SESSION_ERROR, str(e))
+     except ModuleCCSessionError as e:
+         logger.error(DDNS_MODULECC_SESSION_ERROR, str(e))
+     except DDNSConfigError as e:
+         logger.error(DDNS_CONFIG_ERROR, str(e))
+     except SessionTimeout as e:
+         logger.error(DDNS_CC_SESSION_TIMEOUT_ERROR)
+     except Exception as e:
+         logger.error(DDNS_UNCAUGHT_EXCEPTION, type(e).__name__, str(e))
+ if '__main__' == __name__:
+     main()
index 0000000000000000000000000000000000000000,61d740ca6759f24e74c4178ce08d2be966e43e94..d8b1c794af92f3ac97f3ea88d5a55d78e69ac3ba
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,28 +1,28 @@@
 -      B10_FROM_BUILD=$(abs_top_builddir) \
+ PYCOVERAGE_RUN=@PYCOVERAGE_RUN@
+ PYTESTS = ddns_test.py
+ EXTRA_DIST = $(PYTESTS)
+ # If necessary (rare cases), explicitly specify paths to dynamic libraries
+ # required by loadable python modules.
+ LIBRARY_PATH_PLACEHOLDER =
+ if SET_ENV_LIBRARY_PATH
+ LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/cryptolink/.libs:$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/cc/.libs:$(abs_top_builddir)/src/lib/config/.libs:$(abs_top_builddir)/src/lib/log/.libs:$(abs_top_builddir)/src/lib/util/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/util/io/.libs:$(abs_top_builddir)/src/lib/datasrc/.libs:$(abs_top_builddir)/src/lib/acl/.libs:$$$(ENV_LIBRARY_PATH)
+ endif
+ # test using command-line arguments, so use check-local target instead of TESTS
+ # We set B10_FROM_BUILD below, so that the test can refer to the in-source
+ # spec file.
+ check-local:
+ if ENABLE_PYTHON_COVERAGE
+       touch $(abs_top_srcdir)/.coverage
+       rm -f .coverage
+       ${LN_S} $(abs_top_srcdir)/.coverage .coverage
+ endif
+       for pytest in $(PYTESTS) ; do \
+       echo Running test: $$pytest ; \
++      B10_FROM_SOURCE=$(abs_top_srcdir) \
+       $(LIBRARY_PATH_PLACEHOLDER) \
+       PYTHONPATH=$(COMMON_PYTHON_PATH):$(abs_top_builddir)/src/bin/ddns:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/util/io/.libs \
+       TESTDATASRCDIR=$(abs_srcdir)/testdata/ \
+       $(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
+       done