Commit 8681b863 authored by Stephen Morris's avatar Stephen Morris
Browse files

Added start_auth and start_recurse options to the Boss process to determine

where to start the authoritative and/or recursive server.  Additional
command-line options have been provided to set the address/port for the
latter.


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac412@3638 e5f2f494-b856-4b98-b285-d166d9295462
parent ba058244
......@@ -467,6 +467,7 @@ AC_CONFIG_FILES([Makefile
src/bin/auth/tests/Makefile
src/bin/auth/tests/testdata/Makefile
src/bin/auth/benchmarks/Makefile
src/bin/recurse/Makefile
src/bin/xfrin/Makefile
src/bin/xfrin/tests/Makefile
src/bin/xfrout/Makefile
......@@ -530,6 +531,9 @@ AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
src/bin/xfrout/xfrout.spec.pre
src/bin/xfrout/tests/xfrout_test
src/bin/xfrout/run_b10-xfrout.sh
src/bin/recurse/recurse.py
src/bin/recurse/recurse.spec.pre
src/bin/recurse/run_b10-recurse.sh
src/bin/zonemgr/zonemgr.py
src/bin/zonemgr/zonemgr.spec.pre
src/bin/zonemgr/tests/zonemgr_test
......@@ -572,6 +576,7 @@ AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
chmod +x src/bin/cmdctl/run_b10-cmdctl.sh
chmod +x src/bin/xfrin/run_b10-xfrin.sh
chmod +x src/bin/xfrout/run_b10-xfrout.sh
chmod +x src/bin/recurse/run_b10-recurse.sh
chmod +x src/bin/zonemgr/run_b10-zonemgr.sh
chmod +x src/bin/stats/tests/stats_test
chmod +x src/bin/stats/run_b10-stats.sh
......
SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
usermgr zonemgr stats tests
usermgr zonemgr stats tests recurse
check-recursive: all-recursive
This diff is collapsed.
......@@ -3,6 +3,18 @@
"module_name": "Boss",
"module_description": "Master process",
"config_data": [
{
"item_name": "start_auth",
"item_type": "boolean",
"item_optional": false,
"item_default": true
},
{
"item_name": "start_recurse",
"item_type": "boolean",
"item_optional": false,
"item_default": false
}
],
"commands": [
{
......
......@@ -20,7 +20,7 @@ export PYTHON_EXEC
BIND10_PATH=@abs_top_builddir@/src/bin/bind10
PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:$PATH
PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:@abs_top_builddir@/src/bin/stats:@abs_top_builddir@/src/bin/xfrin:@abs_top_builddir@/src/bin/xfrout:@abs_top_builddir@/src/bin/zonemgr:@abs_top_builddir@/src/bin/recurse:$PATH
export PATH
PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/xfr/.libs
......
......@@ -79,43 +79,280 @@ class TestBoB(unittest.TestCase):
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, None)
self.assertEqual(bob.auth_port, 5300)
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.res_port, 5301)
self.assertEqual(bob.address, None)
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
self.assertEqual(bob.processes, {})
self.assertEqual(bob.dead_processes, {})
self.assertEqual(bob.runnable, False)
self.assertEqual(bob.uid, None)
self.assertEqual(bob.username, None)
self.assertEqual(bob.nocache, False)
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_recurse, False)
def test_init_alternate_socket(self):
bob = BoB("alt_socket_file")
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, "alt_socket_file")
self.assertEqual(bob.auth_port, 5300)
self.assertEqual(bob.res_port, 5301)
self.assertEqual(bob.address, None)
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
self.assertEqual(bob.processes, {})
self.assertEqual(bob.dead_processes, {})
self.assertEqual(bob.runnable, False)
self.assertEqual(bob.uid, None)
self.assertEqual(bob.username, None)
self.assertEqual(bob.nocache, False)
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_recurse, False)
def test_init_alternate_auth_port(self):
bob = BoB(None, 9999)
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, None)
self.assertEqual(bob.auth_port, 9999)
self.assertEqual(bob.res_port, 5301)
self.assertEqual(bob.address, None)
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
self.assertEqual(bob.processes, {})
self.assertEqual(bob.dead_processes, {})
self.assertEqual(bob.runnable, False)
self.assertEqual(bob.uid, None)
self.assertEqual(bob.username, None)
self.assertEqual(bob.nocache, False)
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_recurse, False)
def test_init_alternate_res_port(self):
bob = BoB(None, 9999, 9998)
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, None)
self.assertEqual(bob.auth_port, 9999)
self.assertEqual(bob.res_port, 9998)
self.assertEqual(bob.address, None)
self.assertEqual(bob.res_address, None)
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
self.assertEqual(bob.processes, {})
self.assertEqual(bob.dead_processes, {})
self.assertEqual(bob.runnable, False)
self.assertEqual(bob.uid, None)
self.assertEqual(bob.username, None)
self.assertEqual(bob.nocache, False)
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_recurse, False)
def test_init_alternate_address(self):
bob = BoB(None, 5300, IPAddr('127.127.127.127'))
bob = BoB(None, 1234, 5678, IPAddr('127.127.127.127'))
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.auth_port, 5300)
self.assertEqual(bob.msgq_socket_file, None)
self.assertEqual(bob.auth_port, 1234)
self.assertEqual(bob.res_port, 5678)
self.assertEqual(bob.address.addr, socket.inet_aton('127.127.127.127'))
self.assertEqual(bob.res_address, None)
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
self.assertEqual(bob.processes, {})
self.assertEqual(bob.dead_processes, {})
self.assertEqual(bob.runnable, False)
self.assertEqual(bob.uid, None)
self.assertEqual(bob.username, None)
self.assertEqual(bob.nocache, False)
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_recurse, False)
def test_init_alternate_res_address(self):
bob = BoB(None, 1234, 5678, IPAddr('127.127.127.127'), IPAddr("255.254.253.252"))
self.assertEqual(bob.verbose, False)
self.assertEqual(bob.msgq_socket_file, None)
self.assertEqual(bob.auth_port, 1234)
self.assertEqual(bob.res_port, 5678)
self.assertEqual(bob.address.addr, socket.inet_aton('127.127.127.127'))
self.assertEqual(bob.res_address.addr, socket.inet_aton('255.254.253.252'))
self.assertEqual(bob.cc_session, None)
self.assertEqual(bob.ccs, None)
self.assertEqual(bob.processes, {})
self.assertEqual(bob.dead_processes, {})
self.assertEqual(bob.runnable, False)
# verbose testing...
self.assertEqual(bob.uid, None)
self.assertEqual(bob.username, None)
self.assertEqual(bob.nocache, False)
self.assertEqual(bob.cfg_start_auth, True)
self.assertEqual(bob.cfg_start_recurse, False)
# Class for testing the Bob.start_all_processes() method call.
#
# Although testing that external processes start is outside the scope
# of the unit test, by overriding the process start methods we can check
# that the right processes are started depending on the configuration
# options.
class StartAllProcessesBob(BoB):
def __init__(self):
BoB.__init__(self)
# Set flags as to which of the overridden methods has been run.
self.msgq = False
self.cfgmgr = False
self.ccsession = False
self.auth = False
self.recurse = False
self.xfrout = False
self.xfrin = False
self.zonemgr = False
self.stats = False
self.cmdctl = False
def read_bind10_config(self):
# Configuration options are set directly
pass
def start_msgq(self, c_channel_env):
self.msgq = True
def start_cfgmgr(self, c_channel_env):
self.cfgmgr = True
def start_ccsession(self, c_channel_env):
self.ccsession = True
def start_auth(self, c_channel_env):
self.auth = True
def start_recurse(self, c_channel_env):
self.recurse = True
def start_xfrout(self, c_channel_env):
self.xfrout = True
def start_xfrin(self, c_channel_env):
self.xfrin = True
def start_zonemgr(self, c_channel_env):
self.zonemgr = True
def start_stats(self, c_channel_env):
self.stats = True
def start_cmdctl(self, c_channel_env):
self.cmdctl = True
# Check that the start_all_processes method starts the right combination
# of processes.
class TestStartAllProcessesBob(unittest.TestCase):
def check_preconditions(self, bob):
self.assertEqual(bob.msgq, False)
self.assertEqual(bob.cfgmgr, False)
self.assertEqual(bob.ccsession, False)
self.assertEqual(bob.auth, False)
self.assertEqual(bob.recurse, False)
self.assertEqual(bob.xfrout, False)
self.assertEqual(bob.xfrin, False)
self.assertEqual(bob.zonemgr, False)
self.assertEqual(bob.stats, False)
self.assertEqual(bob.cmdctl, False)
# Checks the processes started when starting neither auth nor recruse
# is specified.
def test_start_none(self):
# Created Bob and ensure initialization correct
bob = StartAllProcessesBob()
self.check_preconditions(bob)
# Start processes and check what was started
c_channel_env = {}
bob.cfg_start_auth = False
bob.cfg_start_recurse = False
bob.start_all_processes(c_channel_env)
self.assertEqual(bob.msgq, True)
self.assertEqual(bob.cfgmgr, True)
self.assertEqual(bob.ccsession, True)
self.assertEqual(bob.auth, False)
self.assertEqual(bob.recurse, False)
self.assertEqual(bob.xfrout, False)
self.assertEqual(bob.xfrin, False)
self.assertEqual(bob.zonemgr, False)
self.assertEqual(bob.stats, True)
self.assertEqual(bob.cmdctl, True)
# Checks the processes started when starting only the auth process
def test_start_auth(self):
# Created Bob and ensure initialization correct
bob = StartAllProcessesBob()
self.check_preconditions(bob)
# Start processes and check what was started
c_channel_env = {}
bob.cfg_start_auth = True
bob.cfg_start_recurse = False
bob.start_all_processes(c_channel_env)
self.assertEqual(bob.msgq, True)
self.assertEqual(bob.cfgmgr, True)
self.assertEqual(bob.ccsession, True)
self.assertEqual(bob.auth, True)
self.assertEqual(bob.recurse, False)
self.assertEqual(bob.xfrout, True)
self.assertEqual(bob.xfrin, True)
self.assertEqual(bob.zonemgr, True)
self.assertEqual(bob.stats, True)
self.assertEqual(bob.cmdctl, True)
# Checks the processes started when starting only the recurse process
def test_start_recurse(self):
# Created Bob and ensure initialization correct
bob = StartAllProcessesBob()
self.check_preconditions(bob)
# Start processes and check what was started
c_channel_env = {}
bob.cfg_start_auth = False
bob.cfg_start_recurse = True
bob.start_all_processes(c_channel_env)
self.assertEqual(bob.msgq, True)
self.assertEqual(bob.cfgmgr, True)
self.assertEqual(bob.ccsession, True)
self.assertEqual(bob.auth, False)
self.assertEqual(bob.recurse, True)
self.assertEqual(bob.xfrout, False)
self.assertEqual(bob.xfrin, False)
self.assertEqual(bob.zonemgr, False)
self.assertEqual(bob.stats, True)
self.assertEqual(bob.cmdctl, True)
# Checks the processes started when starting both auth and recurse process
def test_start_both(self):
# Created Bob and ensure initialization correct
bob = StartAllProcessesBob()
self.check_preconditions(bob)
# Start processes and check what was started
c_channel_env = {}
bob.cfg_start_auth = True
bob.cfg_start_recurse = True
bob.start_all_processes(c_channel_env)
self.assertEqual(bob.msgq, True)
self.assertEqual(bob.cfgmgr, True)
self.assertEqual(bob.ccsession, True)
self.assertEqual(bob.auth, True)
self.assertEqual(bob.recurse, True)
self.assertEqual(bob.xfrout, True)
self.assertEqual(bob.xfrin, True)
self.assertEqual(bob.zonemgr, True)
self.assertEqual(bob.stats, True)
self.assertEqual(bob.cmdctl, True)
if __name__ == '__main__':
unittest.main()
# SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
pkglibexec_SCRIPTS = b10-recurse
b10_recursedir = $(DESTDIR)$(pkgdatadir)
b10_recurse_DATA = recurse.spec
CLEANFILES= b10-recurse recurse.pyc recurse.py recurse.spec recurse.spec.pre
recurse.spec: recurse.spec.pre
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" recurse.spec.pre >$@
# TODO: does this need $$(DESTDIR) also?
# this is done here since configure.ac AC_OUTPUT doesn't expand exec_prefix
b10-recurse: recurse.py
$(SED) -e "s|@@PYTHONPATH@@|@pyexecdir@|" \
-e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" recurse.py >$@
chmod a+x $@
All the files in this directory are for testing ticket #412 only.
Another ticket has created the "b10-recurse" program. When both are merged
into the trunk, these files should be deleted.
Stephen Morris
24 November 2010
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
# Copyright (C) 2010 CZ NIC
#
# 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.
"""
This is a dummy recursor module, purely for testing that the changes to
the Boss regarding the starting of recurse/auth works. It should be deleted
when the real recursor module is made available.
"""
import sys; sys.path.append ('@@PYTHONPATH@@')
import isc
import isc.cc
import threading
import struct
import signal
from isc.datasrc import sqlite3_ds
from socketserver import *
import os
from isc.config.ccsession import *
from isc.log.log import *
from isc.cc import SessionError, SessionTimeout
from isc.notify import notify_out
import isc.util.process
import socket
import select
import errno
from optparse import OptionParser, OptionValueError
from isc.util import socketserver_mixin
try:
from libxfr_python import *
from pydnspp import *
except ImportError as e:
# C++ loadable module may not be installed; even so the recurse process
# must keep running, so we warn about it and move forward.
sys.stderr.write('[b10-recurse] failed to import DNS or XFR module: %s\n' % str(e))
isc.util.process.rename()
if "B10_FROM_BUILD" in os.environ:
SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/recurse"
AUTH_SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/auth"
UNIX_SOCKET_FILE= os.environ["B10_FROM_BUILD"] + "/auth_recurse_conn"
else:
PREFIX = "@prefix@"
DATAROOTDIR = "@datarootdir@"
SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
AUTH_SPECFILE_PATH = SPECFILE_PATH
UNIX_SOCKET_FILE = "@@LOCALSTATEDIR@@/auth_recurse_conn"
SPECFILE_LOCATION = SPECFILE_PATH + "/recurse.spec"
AUTH_SPECFILE_LOCATION = AUTH_SPECFILE_PATH + os.sep + "auth.spec"
MAX_TRANSFERS_OUT = 10
VERBOSE_MODE = False
RESOLVER_MAX_MESSAGE_SIZE = 65535
class ResolverServer:
def __init__(self):
self._unix_socket_server = None
self._log = None
self._listen_sock_file = UNIX_SOCKET_FILE
self._shutdown_event = threading.Event()
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._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
def config_handler(self, new_config):
'''Update config data. TODO. Do error check'''
answer = create_answer(0)
for key in new_config:
if key not in self._config_data:
answer = create_answer(1, "Unknown config data: " + str(key))
continue
self._config_data[key] = new_config[key]
if self._log:
self._log.update_config(new_config)
if self._unix_socket_server:
self._unix_socket_server.update_config_data(self._config_data)
return answer
def shutdown(self):
'''
shutdown the recurse process.
'''
global recurse_server
recurse_server = None #Avoid shutdown is called twice
self._shutdown_event.set()
if self._unix_socket_server:
self._unix_socket_server.shutdown()
sys.exit(0)
def command_handler(self, cmd, args):
if cmd == "shutdown":
self._log.log_message("info", "Received shutdown command.")
self.shutdown()
answer = create_answer(0)
else:
answer = create_answer(1, "Unknown command:" + str(cmd))
return answer
def run(self):
'''Get and process all commands sent from cfgmgr or other modules. '''
while not self._shutdown_event.is_set():
self._cc.check_command(False)
recurse_server = None
def signal_handler(signal, frame):
if recurse_server:
recurse_server.shutdown()
sys.exit(0)
def set_signal_handler():
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)
def set_cmd_options(parser):
parser.add_option("-a", "--address", dest="address", type="string",
default="127.0.0.1", help="Address on which recursor listens")
parser.add_option("-n", "--nocache", dest="nocache", action="store_true",
help="Specify to disable the cache")
parser.add_option("-p", "--port", dest="port", type="string",
default="10", help="UID under which recursor runs")
parser.add_option("-u", "--uid", dest="uid", type="string",
default="5301", help="Port on which recursor listens")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
help="display more about what is going on")
if '__main__' == __name__:
try:
parser = OptionParser()
set_cmd_options(parser)
(options, args) = parser.parse_args()
VERBOSE_MODE = options.verbose
set_signal_handler()
recurse_server = ResolverServer()
recurse_server.run()
except KeyboardInterrupt:
sys.stderr.write("[b10-recurse] exit recurse process\n")
except SessionError as e:
sys.stderr.write("[b10-recurse] Error creating recurse, "
"is the command channel daemon running?\n")
except SessionTimeout as e:
sys.stderr.write("[b10-recurse] Error creating recurse, "
"is the configuration manager running?\n")
except ModuleCCSessionError as e:
sys.stderr.write("[b10-recurse] exit recurse process:%s\n" % str(e))
if recurse_server:
recurse_server.shutdown()
{
"module_spec": {
"module_name": "Recurse",
"config_data": [
],
"commands": [
{
"command_name": "shutdown",
"command_description": "Shut down Resolver",
"command_args": []
}
]
}
}
#! /bin/sh
# 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.
PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
export PYTHON_EXEC
MYPATH_PATH=@abs_top_builddir@/src/bin/recurse
PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/xfr/.libs:@abs_top_builddir@/src/lib/dns/python/.libs
export PYTHONPATH
cd ${MYPATH_PATH}
${PYTHON_EXEC} b10-recurse
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment