Commit 78770f52 authored by Stephen Morris's avatar Stephen Morris
Browse files

Merge branch 'master' into trac1330

parents eb53cae4 498677a8
317. [func] vorner
datasrc: the getUpdater method of DataSourceClient supports an optional
'journaling' parameter to indicate the generated updater to store diffs.
The database based derived class implements this extension.
(Trac #1331, git 713160c9bed3d991a00b2ea5e7e3e7714d79625d)
316. [func]* vorner
The configuration of what parts of the system run is more flexible now.
Everything that should run must have an entry in Boss/components.
(Trac #213, git 08e1873a3593b4fa06754654d22d99771aa388a6)
315. [func] tomek
libdhcp: Support for DHCPv4 packet manipulation is now implemented.
All fixed fields are now supported. Generic support for DHCPv4
options is available (both parsing and assembly). There is no code
that uses this new functionality yet, so it is not usable directly
at this time. This code will be used by upcoming b10-dhcp4 daemon.
(Trac #1228, git 31d5a4f66b18cca838ca1182b9f13034066427a7)
314. [bug] jelte
b10-xfrin would previously initiate incoming transfers upon
receiving NOTIFY messages from any address (if the zone was
known to b10-xfrin, and using the configured address). It now
only starts a transfer if the source address from the NOTIFY
packet matches the configured master address and port. This was
really already fixed in release bind10-devel-20111014, but there
were some deferred cleanups to add.
(Trac #1298, git 1177bfe30e17a76bea6b6447e14ae9be9e1ca8c2)
313. [func] jinmei
datasrc: Added C++ API for adding zone differences to database
based data sources. It's intended to be used for the support for
IXFR-in and dynamic update (so they can subsequently be retrieved
for IXFR-out). The addRecordDiff method of the DatabaseAccessor
defines the interface, and a concrete implementation for SQLite3
was provided.
(Trac #1329, git 1aa233fab1d74dc776899df61181806679d14013)
312. [func] jelte
Added an initial framework for doing system tests using the
cucumber-based BDD tool Lettuce. A number of general steps are
included, for instance running bind10 with specific
configurations, sending queries, and inspecting query answers. A
few very basic tests are included as well.
(Trac #1290, git 6b75c128bcdcefd85c18ccb6def59e9acedd4437)
311. [bug] jelte
Fixed a bug in bindctl where tab-completion for names that
contain a hyphen resulted in unexpected behaviour, such as
......@@ -25,7 +71,7 @@
given using the '--with-botan=' flag
(Trac #1194, git dc491833cf75ac1481ba1475795b0f266545013d)
307. [func] vorner
307. [func] vorner
When zone transfer in fails with IXFR, it is retried with AXFR
automatically.
(Trac #1279, git cd3588c9020d0310f949bfd053c4d3a4bd84ef88)
......@@ -444,7 +490,7 @@ bind10-devel-20110705 released on July 05, 2011
(Trac #542, git 1aa773d84cd6431aa1483eb34a7f4204949a610f)
243. [func]* feng
Add optional hmac algorithm SHA224/384/812.
Add optional hmac algorithm SHA224/384/512.
(Trac #782, git 77d792c9d7c1a3f95d3e6a8b721ac79002cd7db1)
bind10-devel-20110519 released on May 19, 2011
......
......@@ -107,6 +107,12 @@ case "$host" in
SET_ENV_LIBRARY_PATH=yes
ENV_LIBRARY_PATH=DYLD_LIBRARY_PATH
;;
*-freebsd*)
SET_ENV_LIBRARY_PATH=yes
;;
*-netbsd*)
SET_ENV_LIBRARY_PATH=yes
;;
esac
AM_CONDITIONAL(SET_ENV_LIBRARY_PATH, test $SET_ENV_LIBRARY_PATH = yes)
AC_SUBST(SET_ENV_LIBRARY_PATH)
......@@ -991,6 +997,7 @@ AC_OUTPUT([doc/version.ent
src/lib/util/python/mkpywrapper.py
src/lib/util/python/gen_wiredata.py
src/lib/server_common/tests/data_path.h
tests/lettuce/setup_intree_bind10.sh
tests/system/conf.sh
tests/system/run.sh
tests/system/glue/setup.sh
......
- Read msgq configuration from configuration manager (Trac #213)
https://bind10.isc.org/ticket/213
- Provide more administrator options:
- Get process list
- Get information on a process (returns list of times started & stopped,
plus current information such as PID)
- Add a component (not necessary for parking lot, but...)
- Stop a component
- Force-stop a component
- Mechanism to wait for child to start before continuing
- Way to ask a child to die politely
- Start statistics daemon
- Statistics interaction (?)
- Use .spec file to define comands
- Rename "c-channel" stuff to msgq for clarity
- Use logger
- Reply to shutdown message?
- Some sort of group creation so termination signals can be sent to
children of children processes (if any)
......
......@@ -20,18 +20,72 @@ The boss process is starting up and will now check if the message bus
daemon is already running. If so, it will not be able to start, as it
needs a dedicated message bus.
% BIND10_CONFIGURATION_START_AUTH start authoritative server: %1
This message shows whether or not the authoritative server should be
started according to the configuration.
% BIND10_CONFIGURATION_START_RESOLVER start resolver: %1
This message shows whether or not the resolver should be
started according to the configuration.
% BIND10_INVALID_STATISTICS_DATA invalid specification of statistics data specified
An error was encountered when the boss module specified
statistics data which is invalid for the boss specification file.
% BIND10_COMPONENT_FAILED component %1 (pid %2) failed with %3 exit status
The process terminated, but the bind10 boss didn't expect it to, which means
it must have failed.
% BIND10_COMPONENT_RESTART component %1 is about to restart
The named component failed previously and we will try to restart it to provide
as flawless service as possible, but it should be investigated what happened,
as it could happen again.
% BIND10_COMPONENT_START component %1 is starting
The named component is about to be started by the boss process.
% BIND10_COMPONENT_START_EXCEPTION component %1 failed to start: %2
An exception (mentioned in the message) happened during the startup of the
named component. The componet is not considered started and further actions
will be taken about it.
% BIND10_COMPONENT_STOP component %1 is being stopped
A component is about to be asked to stop willingly by the boss.
% BIND10_COMPONENT_UNSATISFIED component %1 is required to run and failed
A component failed for some reason (see previous messages). It is either a core
component or needed component that was just started. In any case, the system
can't continue without it and will terminate.
% BIND10_CONFIGURATOR_BUILD building plan '%1' -> '%2'
A debug message. This indicates that the configurator is building a plan
how to change configuration from the older one to newer one. This does no
real work yet, it just does the planning what needs to be done.
% BIND10_CONFIGURATOR_PLAN_INTERRUPTED configurator plan interrupted, only %1 of %2 done
There was an exception during some planned task. The plan will not continue and
only some tasks of the plan were completed. The rest is aborted. The exception
will be propagated.
% BIND10_CONFIGURATOR_RECONFIGURE reconfiguring running components
A different configuration of which components should be running is being
installed. All components that are no longer needed will be stopped and
newly introduced ones started. This happens at startup, when the configuration
is read the first time, or when an operator changes configuration of the boss.
% BIND10_CONFIGURATOR_RUN running plan of %1 tasks
A debug message. The configurator is about to execute a plan of actions it
computed previously.
% BIND10_CONFIGURATOR_START bind10 component configurator is starting up
The part that cares about starting and stopping the right component from the
boss process is starting up. This happens only once at the startup of the
boss process. It will start the basic set of processes now (the ones boss
needs to read the configuration), the rest will be started after the
configuration is known.
% BIND10_CONFIGURATOR_STOP bind10 component configurator is shutting down
The part that cares about starting and stopping processes in the boss is
shutting down. All started components will be shut down now (more precisely,
asked to terminate by their own, if they fail to comply, other parts of
the boss process will try to force them).
% BIND10_CONFIGURATOR_TASK performing task %1 on %2
A debug message. The configurator is about to perform one task of the plan it
is currently executing on the named component.
% BIND10_INVALID_USER invalid user: %1
The boss process was started with the -u option, to drop root privileges
and continue running as the specified user, but the user is unknown.
......@@ -51,27 +105,15 @@ old process was not shut down correctly, and needs to be killed, or
another instance of BIND10, with the same msgq domain socket, is
running, which needs to be stopped.
% BIND10_MSGQ_DAEMON_ENDED b10-msgq process died, shutting down
The message bus daemon has died. This is a fatal error, since it may
leave the system in an inconsistent state. BIND10 will now shut down.
% BIND10_MSGQ_DISAPPEARED msgq channel disappeared
While listening on the message bus channel for messages, it suddenly
disappeared. The msgq daemon may have died. This might lead to an
inconsistent state of the system, and BIND 10 will now shut down.
% BIND10_PROCESS_ENDED_NO_EXIT_STATUS process %1 (PID %2) died: exit status not available
The given process ended unexpectedly, but no exit status is
available. See BIND10_PROCESS_ENDED_WITH_EXIT_STATUS for a longer
description.
% BIND10_PROCESS_ENDED_WITH_EXIT_STATUS process %1 (PID %2) terminated, exit status = %3
The given process ended unexpectedly with the given exit status.
Depending on which module it was, it may simply be restarted, or it
may be a problem that will cause the boss module to shut down too.
The latter happens if it was the message bus daemon, which, if it has
died suddenly, may leave the system in an inconsistent state. BIND10
will also shut down now if it has been run with --brittle.
% BIND10_PROCESS_ENDED process %2 of %1 ended with status %3
This indicates a process started previously terminated. The process id
and component owning the process are indicated, as well as the exit code.
This doesn't distinguish if the process was supposed to terminate or not.
% BIND10_READING_BOSS_CONFIGURATION reading boss configuration
The boss process is starting up, and will now process the initial
......@@ -107,6 +149,9 @@ The boss module is sending a SIGKILL signal to the given process.
% BIND10_SEND_SIGTERM sending SIGTERM to %1 (PID %2)
The boss module is sending a SIGTERM signal to the given process.
% BIND10_SETUID setting UID to %1
The boss switches the user it runs as to the given UID.
% BIND10_SHUTDOWN stopping the server
The boss process received a command or signal telling it to shut down.
It will send a shutdown command to each process. The processes that do
......@@ -125,11 +170,6 @@ which failed is unknown (not one of 'S' for socket or 'B' for bind).
The boss requested a socket from the creator, but the answer is unknown. This
looks like a programmer error.
% BIND10_SOCKCREATOR_CRASHED the socket creator crashed
The socket creator terminated unexpectedly. It is not possible to restart it
(because the boss already gave up root privileges), so the system is going
to terminate.
% BIND10_SOCKCREATOR_EOF eof while expecting data from socket creator
There should be more data from the socket creator, but it closed the socket.
It probably crashed.
......@@ -208,8 +248,15 @@ During the startup process, a number of messages are exchanged between the
Boss process and the processes it starts. This error is output when a
message received by the Boss process is not recognised.
% BIND10_START_AS_NON_ROOT starting %1 as a user, not root. This might fail.
The given module is being started or restarted without root privileges.
% BIND10_START_AS_NON_ROOT_AUTH starting b10-auth as a user, not root. This might fail.
The authoritative server is being started or restarted without root privileges.
If the module needs these privileges, it may have problems starting.
Note that this issue should be resolved by the pending 'socket-creator'
process; once that has been implemented, modules should not need root
privileges anymore. See tickets #800 and #801 for more information.
% BIND10_START_AS_NON_ROOT_RESOLVER starting b10-resolver as a user, not root. This might fail.
The resolver is being started or restarted without root privileges.
If the module needs these privileges, it may have problems starting.
Note that this issue should be resolved by the pending 'socket-creator'
process; once that has been implemented, modules should not need root
......
This diff is collapsed.
......@@ -4,16 +4,71 @@
"module_description": "Master process",
"config_data": [
{
"item_name": "start_auth",
"item_type": "boolean",
"item_name": "components",
"item_type": "named_set",
"item_optional": false,
"item_default": true
},
{
"item_name": "start_resolver",
"item_type": "boolean",
"item_optional": false,
"item_default": false
"item_default": {
"b10-auth": { "special": "auth", "kind": "needed", "priority": 10 },
"setuid": {
"special": "setuid",
"priority": 5,
"kind": "dispensable"
},
"b10-xfrin": { "special": "xfrin", "kind": "dispensable" },
"b10-xfrout": { "special": "xfrout", "kind": "dispensable" },
"b10-zonemgr": { "address": "Zonemgr", "kind": "dispensable" },
"b10-stats": { "address": "Stats", "kind": "dispensable" },
"b10-stats-httpd": {
"address": "StatsHttpd",
"kind": "dispensable"
},
"b10-cmdctl": { "special": "cmdctl", "kind": "needed" }
},
"named_set_item_spec": {
"item_name": "component",
"item_type": "map",
"item_optional": false,
"item_default": { },
"map_item_spec": [
{
"item_name": "special",
"item_optional": true,
"item_type": "string"
},
{
"item_name": "process",
"item_optional": true,
"item_type": "string"
},
{
"item_name": "kind",
"item_optional": false,
"item_type": "string",
"item_default": "dispensable"
},
{
"item_name": "address",
"item_optional": true,
"item_type": "string"
},
{
"item_name": "params",
"item_optional": true,
"item_type": "list",
"list_item_spec": {
"item_name": "param",
"item_optional": false,
"item_type": "string",
"item_default": ""
}
},
{
"item_name": "priority",
"item_optional": true,
"item_type": "integer"
}
]
}
}
],
"commands": [
......
......@@ -45,6 +45,5 @@ export B10_FROM_BUILD
BIND10_MSGQ_SOCKET_FILE=@abs_top_builddir@/msgq_socket
export BIND10_MSGQ_SOCKET_FILE
cd ${BIND10_PATH}
exec ${PYTHON_EXEC} -O bind10 "$@"
exec ${PYTHON_EXEC} -O ${BIND10_PATH}/bind10 "$@"
This diff is collapsed.
......@@ -71,21 +71,21 @@ Type \"<module_name> <command_name> help\" for help on the specific command.
\nAvailable module names: """
class ValidatedHTTPSConnection(http.client.HTTPSConnection):
'''Overrides HTTPSConnection to support certification
'''Overrides HTTPSConnection to support certification
validation. '''
def __init__(self, host, ca_certs):
http.client.HTTPSConnection.__init__(self, host)
self.ca_certs = ca_certs
def connect(self):
''' Overrides the connect() so that we do
''' Overrides the connect() so that we do
certificate validation. '''
sock = socket.create_connection((self.host, self.port),
self.timeout)
if self._tunnel_host:
self.sock = sock
self._tunnel()
req_cert = ssl.CERT_NONE
if self.ca_certs:
req_cert = ssl.CERT_REQUIRED
......@@ -95,7 +95,7 @@ class ValidatedHTTPSConnection(http.client.HTTPSConnection):
ca_certs=self.ca_certs)
class BindCmdInterpreter(Cmd):
"""simple bindctl example."""
"""simple bindctl example."""
def __init__(self, server_port='localhost:8080', pem_file=None,
csv_file_dir=None):
......@@ -128,29 +128,33 @@ class BindCmdInterpreter(Cmd):
socket.gethostname())).encode())
digest = session_id.hexdigest()
return digest
def run(self):
'''Parse commands from user and send them to cmdctl. '''
try:
if not self.login_to_cmdctl():
return
return 1
self.cmdloop()
print('\nExit from bindctl')
return 0
except FailToLogin as err:
# error already printed when this was raised, ignoring
pass
return 1
except KeyboardInterrupt:
print('\nExit from bindctl')
return 0
except socket.error as err:
print('Failed to send request, the connection is closed')
return 1
except http.client.CannotSendRequest:
print('Can not send request, the connection is busy')
return 1
def _get_saved_user_info(self, dir, file_name):
''' Read all the available username and password pairs saved in
''' Read all the available username and password pairs saved in
file(path is "dir + file_name"), Return value is one list of elements
['name', 'password'], If get information failed, empty list will be
['name', 'password'], If get information failed, empty list will be
returned.'''
if (not dir) or (not os.path.exists(dir)):
return []
......@@ -176,7 +180,7 @@ class BindCmdInterpreter(Cmd):
if not os.path.exists(dir):
os.mkdir(dir, 0o700)
csvfilepath = dir + file_name
csvfilepath = dir + file_name
csvfile = open(csvfilepath, 'w')
os.chmod(csvfilepath, 0o600)
writer = csv.writer(csvfile)
......@@ -190,7 +194,7 @@ class BindCmdInterpreter(Cmd):
return True
def login_to_cmdctl(self):
'''Login to cmdctl with the username and password inputted
'''Login to cmdctl with the username and password inputted
from user. After the login is sucessful, the username and
password will be saved in 'default_user.csv', when run the next
time, username and password saved in 'default_user.csv' will be
......@@ -256,14 +260,14 @@ class BindCmdInterpreter(Cmd):
if self.login_to_cmdctl():
# successful, so try send again
status, reply_msg = self._send_message(url, body)
if reply_msg:
return json.loads(reply_msg.decode())
else:
return {}
def send_POST(self, url, post_param = None):
def send_POST(self, url, post_param = None):
'''Send POST request to cmdctl, session id is send with the name
'cookie' in header.
Format: /module_name/command_name
......@@ -322,12 +326,12 @@ class BindCmdInterpreter(Cmd):
def _validate_cmd(self, cmd):
'''validate the parameters and merge some parameters together,
merge algorithm is based on the command line syntax, later, if
a better command line syntax come out, this function should be
updated first.
a better command line syntax come out, this function should be
updated first.
'''
if not cmd.module in self.modules:
raise CmdUnknownModuleSyntaxError(cmd.module)
module_info = self.modules[cmd.module]
if not module_info.has_command_with_name(cmd.command):
raise CmdUnknownCmdSyntaxError(cmd.module, cmd.command)
......@@ -335,17 +339,17 @@ class BindCmdInterpreter(Cmd):
command_info = module_info.get_command_with_name(cmd.command)
manda_params = command_info.get_mandatory_param_names()
all_params = command_info.get_param_names()
# If help is entered, don't do further parameter validation.
for val in cmd.params.keys():
if val == "help":
return
params = cmd.params.copy()
if not params and manda_params:
raise CmdMissParamSyntaxError(cmd.module, cmd.command, manda_params[0])
params = cmd.params.copy()
if not params and manda_params:
raise CmdMissParamSyntaxError(cmd.module, cmd.command, manda_params[0])
elif params and not all_params:
raise CmdUnknownParamSyntaxError(cmd.module, cmd.command,
raise CmdUnknownParamSyntaxError(cmd.module, cmd.command,
list(params.keys())[0])
elif params:
param_name = None
......@@ -376,7 +380,7 @@ class BindCmdInterpreter(Cmd):
param_name = command_info.get_param_name_by_position(name, param_count)
cmd.params[param_name] = cmd.params[name]
del cmd.params[name]
elif not name in all_params:
raise CmdUnknownParamSyntaxError(cmd.module, cmd.command, name)
......@@ -385,7 +389,7 @@ class BindCmdInterpreter(Cmd):
if not name in params and not param_nr in params:
raise CmdMissParamSyntaxError(cmd.module, cmd.command, name)
param_nr += 1
# Convert parameter value according parameter spec file.
# Ignore check for commands belongs to module 'config'
if cmd.module != CONFIG_MODULE_NAME:
......@@ -394,9 +398,9 @@ class BindCmdInterpreter(Cmd):
try:
cmd.params[param_name] = isc.config.config_data.convert_type(param_spec, cmd.params[param_name])
except isc.cc.data.DataTypeError as e:
raise isc.cc.data.DataTypeError('Invalid parameter value for \"%s\", the type should be \"%s\" \n'
raise isc.cc.data.DataTypeError('Invalid parameter value for \"%s\", the type should be \"%s\" \n'
% (param_name, param_spec['item_type']) + str(e))
def _handle_cmd(self, cmd):
'''Handle a command entered by the user'''
if cmd.command == "help" or ("help" in cmd.params.keys()):
......@@ -418,7 +422,7 @@ class BindCmdInterpreter(Cmd):
def add_module_info(self, module_info):
'''Add the information about one module'''
self.modules[module_info.name] = module_info
def get_module_names(self):
'''Return the names of all known modules'''
return list(self.modules.keys())
......@@ -450,15 +454,15 @@ class BindCmdInterpreter(Cmd):
subsequent_indent=" " +
" " * CONST_BINDCTL_HELP_INDENT_WIDTH,
width=70))
def onecmd(self, line):
if line == 'EOF' or line.lower() == "quit":
self.conn.close()
return True
if line == 'h':
line = 'help'
Cmd.onecmd(self, line)
def remove_prefix(self, list, prefix):
......@@ -486,7 +490,7 @@ class BindCmdInterpreter(Cmd):
cmd = BindCmdParse(cur_line)
if not cmd.params and text:
hints = self._get_command_startswith(cmd.module, text)
else:
else:
hints = self._get_param_startswith(cmd.module, cmd.command,
text)
if cmd.module == CONFIG_MODULE_NAME:
......@@ -502,8 +506,8 @@ class BindCmdInterpreter(Cmd):
except CmdMissCommandNameFormatError as e:
if not text.strip(): # command name is empty
hints = self.modules[e.module].get_command_names()
else:
hints = self.modules[e.module].get_command_names()
else:
hints = self._get_module_startswith(text)
except CmdCommandNameFormatError as e:
......@@ -523,36 +527,37 @@ class BindCmdInterpreter(Cmd):
else:
return None
def _get_module_startswith(self, text):
def _get_module_startswith(self, text):
return [module
for module in self.modules
for module in self.modules
if module.startswith(text)]
def _get_command_startswith(self, module, text):
if module in self.modules:
if module in self.modules:
return [command
for command in self.modules[module].get_command_names()
for command in self.modules[module].get_command_names()
if command.startswith(text)]
return []
def _get_param_startswith(self, module, command, text):
return []
def _get_param_startswith(self, module, command, text):
if module in self.modules:
module_info = self.modules[module]
if command in module_info.get_command_names():
module_info = self.modules[module]
if command in module_info.get_command_names():
cmd_info = module_info.get_command_with_name(command)
params = cmd_info.get_param_names()
params = cmd_info.get_param_names()
hint = []
if text:
if text:
hint = [val for val in params if val.startswith(text)]
else:
hint = list(params)
if len(hint) == 1 and hint[0] != "help":
hint[0] = hint[0] + " ="
hint[0] = hint[0] + " ="
return hint
return []
......@@ -569,24 +574,24 @@ class BindCmdInterpreter(Cmd):
self._print_correct_usage(err)
except isc.cc.data.DataTypeError as err:
print("Error! ", err)
def _print_correct_usage(self, ept):
def _print_correct_usage(self, ept):