BIND 10 trac2676, updated. c8870e86d867789bf2e8dedf6f5e960dc47faaee [2676] Note why Cmdctl is not converted.
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Feb 18 11:39:46 UTC 2013
The branch, trac2676 has been updated
via c8870e86d867789bf2e8dedf6f5e960dc47faaee (commit)
via cd2d3c39ebcba3fb50822fba492c41c6a4bfce25 (commit)
via 09af4e2b9e9b2840dd475ef112d485e3476badd1 (commit)
via 9d00b71c14e4e1eb7e390c78b40e015f960595af (commit)
via 2b0ef32a8eb90122efa930c31147ca6e56df5716 (commit)
via 104a04b32d7705a95d5e9492dce82469aff21a0e (commit)
from ff2215ffb7e7149c50764841e00d8d9186a81294 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c8870e86d867789bf2e8dedf6f5e960dc47faaee
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Feb 18 11:23:08 2013 +0100
[2676] Note why Cmdctl is not converted.
Similar to previous commit, there's a hack in cmdctl that doesn't allow
it now.
commit cd2d3c39ebcba3fb50822fba492c41c6a4bfce25
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Feb 18 09:54:40 2013 +0100
[2676] Note why XfrIn is not converted
There's a hack in XfrIn that prevents straight-forward conversion.
Adding the want_answer parameter for now as a temporary measure, until
the thing is fixed.
commit 09af4e2b9e9b2840dd475ef112d485e3476badd1
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Fri Feb 15 12:47:12 2013 +0100
[2676] Convert stats to use rpc_call
Most parts are converted, with one exception.
There's a place where many messages are sent at once and then it waits
for all the answers. This allows the other modules to process the
commands in parallel. The rpc_call is not flexible enough to allow this
(we'll need the rpc_call_async for that), so we stay with the original,
just adding the want_answer parameter.
commit 9d00b71c14e4e1eb7e390c78b40e015f960595af
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Fri Feb 15 12:37:38 2013 +0100
[2676] Convert ZoneMgr to use the rpc_call
Just a plain conversion.
commit 2b0ef32a8eb90122efa930c31147ca6e56df5716
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Fri Feb 15 12:15:47 2013 +0100
[2676] Convert DDNS to use rpc_call
Just a straight-forward conversion.
commit 104a04b32d7705a95d5e9492dce82469aff21a0e
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Fri Feb 15 09:01:30 2013 +0100
[2676] Use dict, not keyword arguments
As it turns out, it is not as flexible as needed (it wouldn't be
possible to pass no arguments, it would not be possible to specify
parameters of name `class` easily, and so on).
-----------------------------------------------------------------------
Summary of changes:
src/bin/cmdctl/cmdctl.py.in | 7 +++-
src/bin/ddns/ddns.py.in | 45 ++++++++------------
src/bin/ddns/tests/ddns_test.py | 5 ++-
src/bin/stats/stats.py.in | 46 ++++++++++-----------
src/bin/stats/stats_httpd.py.in | 25 +++--------
src/bin/xfrin/tests/xfrin_test.py | 2 +-
src/bin/xfrin/xfrin.py.in | 21 ++++++++--
src/bin/zonemgr/tests/zonemgr_test.py | 18 +++-----
src/bin/zonemgr/zonemgr.py.in | 12 +++---
src/lib/python/isc/config/ccsession.py | 2 +-
src/lib/python/isc/config/tests/ccsession_test.py | 6 ++-
11 files changed, 87 insertions(+), 102 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/cmdctl/cmdctl.py.in b/src/bin/cmdctl/cmdctl.py.in
index 15a41ec..6468016 100755
--- a/src/bin/cmdctl/cmdctl.py.in
+++ b/src/bin/cmdctl/cmdctl.py.in
@@ -429,8 +429,13 @@ class CommandControl():
# Process the command sent to cmdctl directly.
answer = self.command_handler(command_name, params)
else:
+ # FIXME: Due to the fact that we use a separate session
+ # from the module one (due to threads and blocking), and
+ # because the plain cc session does not have the high-level
+ # rpc-call method, we use the low-level way and create the
+ # command ourself.
msg = ccsession.create_command(command_name, params)
- seq = self._cc.group_sendmsg(msg, module_name)
+ seq = self._cc.group_sendmsg(msg, module_name, want_answer=True)
logger.debug(DBG_CMDCTL_MESSAGING, CMDCTL_COMMAND_SENT,
command_name, module_name)
#TODO, it may be blocked, msqg need to add a new interface waiting in timeout.
diff --git a/src/bin/ddns/ddns.py.in b/src/bin/ddns/ddns.py.in
index d7fcab7..e8cff14 100755
--- a/src/bin/ddns/ddns.py.in
+++ b/src/bin/ddns/ddns.py.in
@@ -32,7 +32,6 @@ import isc.util.cio.socketsession
import isc.server_common.tsig_keyring
from isc.server_common.dns_tcp import DNSTCPContext
from isc.datasrc import DataSourceClient
-from isc.server_common.auth_command import auth_loadzone_command
import select
import time
import errno
@@ -544,12 +543,9 @@ class DDNSServer:
def __notify_start_forwarder(self):
'''Notify auth that DDNS Update messages can now be forwarded'''
try:
- seq = self._cc._session.group_sendmsg(create_command(
- "start_ddns_forwarder"), AUTH_MODULE_NAME)
- answer, _ = self._cc._session.group_recvmsg(False, seq)
- rcode, error_msg = parse_answer(answer)
- if rcode != 0:
- logger.error(DDNS_START_FORWARDER_ERROR, error_msg)
+ self._cc.rpc_call("start_ddns_forwarder", AUTH_MODULE_NAME)
+ except RPCError as e:
+ logger.error(DDNS_START_FORWARDER_ERROR, e)
except (SessionTimeout, SessionError, ProtocolError) as ex:
logger.error(DDNS_START_FORWARDER_FAIL, ex)
@@ -558,28 +554,25 @@ class DDNSServer:
'''
try:
- seq = self._cc._session.group_sendmsg(create_command(
- "stop_ddns_forwarder"), AUTH_MODULE_NAME)
- answer, _ = self._cc._session.group_recvmsg(False, seq)
- rcode, error_msg = parse_answer(answer)
- if rcode != 0:
- logger.error(DDNS_STOP_FORWARDER_ERROR, error_msg)
+ self._cc.rpc_call("stop_ddns_forwarder", AUTH_MODULE_NAME)
+ except RPCError as e:
+ logger.error(DDNS_STOP_FORWARDER_ERROR, e)
except (SessionTimeout, SessionError, ProtocolError) as ex:
logger.error(DDNS_STOP_FORWARDER_FAIL, ex)
def __notify_auth(self, zname, zclass):
'''Notify auth of the update, if necessary.'''
- msg = auth_loadzone_command(self._cc, zname, zclass)
- if msg is not None:
- self.__notify_update(AUTH_MODULE_NAME, msg, zname, zclass)
+ param = {'origin': zname.to_text(), 'class': zclass.to_text()}
+ self.__notify_update(AUTH_MODULE_NAME, 'loadzone', param, zname,
+ zclass)
def __notify_xfrout(self, zname, zclass):
'''Notify xfrout of the update.'''
param = {'zone_name': zname.to_text(), 'zone_class': zclass.to_text()}
- msg = create_command('notify', param)
- self.__notify_update(XFROUT_MODULE_NAME, msg, zname, zclass)
+ self.__notify_update(XFROUT_MODULE_NAME, 'notify', param, zname,
+ zclass)
- def __notify_update(self, modname, msg, zname, zclass):
+ def __notify_update(self, modname, command, params, zname, zclass):
'''Notify other module of the update.
Note that we use blocking communication here. While the internal
@@ -599,18 +592,14 @@ class DDNSServer:
'''
try:
- seq = self._cc._session.group_sendmsg(msg, modname)
- answer, _ = self._cc._session.group_recvmsg(False, seq)
- rcode, error_msg = parse_answer(answer)
- except (SessionTimeout, SessionError, ProtocolError) as ex:
- rcode = 1
- error_msg = str(ex)
- if rcode == 0:
+ # FIXME? Do we really need to wait for the answer here? Shouldn't
+ # this be some kind of notification instead?
+ self._cc.rpc_call(command, modname, params=params)
logger.debug(TRACE_BASIC, DDNS_UPDATE_NOTIFY, modname,
ZoneFormatter(zname, zclass))
- else:
+ except (SessionTimeout, SessionError, ProtocolError, RPCError) as ex:
logger.error(DDNS_UPDATE_NOTIFY_FAIL, modname,
- ZoneFormatter(zname, zclass), error_msg)
+ ZoneFormatter(zname, zclass), ex)
def handle_session(self, fileno):
"""Handle incoming session on the socket with given fileno.
diff --git a/src/bin/ddns/tests/ddns_test.py b/src/bin/ddns/tests/ddns_test.py
index d366f09..e7d2099 100755
--- a/src/bin/ddns/tests/ddns_test.py
+++ b/src/bin/ddns/tests/ddns_test.py
@@ -191,7 +191,7 @@ class FakeKeyringModule:
'''Simply return the predefined TSIG keyring unconditionally.'''
return TEST_TSIG_KEYRING
-class MyCCSession(isc.config.ConfigData):
+class MyCCSession(isc.config.ModuleCCSession):
'''Fake session with minimal interface compliance.'''
# faked CC sequence used in group_send/recvmsg
@@ -276,7 +276,8 @@ class MyCCSession(isc.config.ConfigData):
'secondary_zones')
return seczone_default, True
- def group_sendmsg(self, msg, group):
+ def group_sendmsg(self, msg, group, instance='*', to='*',
+ want_answer=False):
# remember the passed parameter, and return dummy sequence
self._sent_msg.append((msg, group))
if self._sendmsg_exception is not None:
diff --git a/src/bin/stats/stats.py.in b/src/bin/stats/stats.py.in
index 0af0933..925ba53 100755
--- a/src/bin/stats/stats.py.in
+++ b/src/bin/stats/stats.py.in
@@ -251,14 +251,9 @@ class Stats:
# It counts the number of instances of same module by
# examining the third value from the array result of
# 'show_processes' of Init
- seq = self.cc_session.group_sendmsg(
- isc.config.ccsession.create_command("show_processes"),
- 'Init')
- (answer, env) = self.cc_session.group_recvmsg(False, seq)
- modules = []
- if answer:
- (rcode, value) = isc.config.ccsession.parse_answer(answer)
- if rcode == 0 and type(value) is list:
+ try:
+ value = self.mccs.rpc_call('show_processes', 'Init')
+ if type(value) is list:
# NOTE: For example, the "show_processes" command
# of Init is assumed to return the response in this
# format:
@@ -286,6 +281,10 @@ class Stats:
# release.
modules = [ v[2] if type(v) is list and len(v) > 2 \
else None for v in value ]
+ except isc.config.RPCError:
+ # TODO: Is it OK to just pass? As part of refactoring, preserving
+ # the original behaviour.
+ pass
# start requesting each module to collect statistics data
sequences = []
for (module_name, data) in self.get_statistics_data().items():
@@ -296,7 +295,10 @@ class Stats:
module_name)
cmd = isc.config.ccsession.create_command(
"getstats", None) # no argument
- seq = self.cc_session.group_sendmsg(cmd, module_name)
+ # Not using rpc_call here, we query a lot of modules in parallel
+ # here
+ seq = self.cc_session.group_sendmsg(cmd, module_name,
+ want_answer=True)
sequences.append((module_name, seq))
cnt = modules.count(module_name)
if cnt > 1:
@@ -421,21 +423,17 @@ class Stats:
raises StatsError.
"""
modules = {}
- seq = self.cc_session.group_sendmsg(
- isc.config.ccsession.create_command(
- isc.config.ccsession.COMMAND_GET_STATISTICS_SPEC),
- 'ConfigManager')
- (answer, env) = self.cc_session.group_recvmsg(False, seq)
- if answer:
- (rcode, value) = isc.config.ccsession.parse_answer(answer)
- if rcode == 0:
- for mod in value:
- spec = { "module_name" : mod }
- if value[mod] and type(value[mod]) is list:
- spec["statistics"] = value[mod]
- modules[mod] = isc.config.module_spec.ModuleSpec(spec)
- else:
- raise StatsError("Updating module spec fails: " + str(value))
+ try:
+ value = self.mccs.rpc_call(isc.config.ccsession. \
+ COMMAND_GET_STATISTICS_SPEC,
+ 'ConfigManager')
+ except isc.config.RPCError as e:
+ raise StatsError("Updating module spec fails: " + str(e))
+ for mod in value:
+ spec = { "module_name" : mod }
+ if value[mod] and type(value[mod]) is list:
+ spec["statistics"] = value[mod]
+ modules[mod] = isc.config.module_spec.ModuleSpec(spec)
modules[self.module_name] = self.mccs.get_module_spec()
self.modules = modules
diff --git a/src/bin/stats/stats_httpd.py.in b/src/bin/stats/stats_httpd.py.in
index 367f56e..f42b1d1 100755
--- a/src/bin/stats/stats_httpd.py.in
+++ b/src/bin/stats/stats_httpd.py.in
@@ -459,20 +459,13 @@ class StatsHttpd:
if name is not None:
param['name'] = name
try:
- seq = self.cc_session.group_sendmsg(
- isc.config.ccsession.create_command('show', param), 'Stats')
- (answer, env) = self.cc_session.group_recvmsg(False, seq)
- if answer:
- (rcode, value) = isc.config.ccsession.parse_answer(answer)
+ return self.mccs.rpc_call('show', 'Stats', params=param)
+ except isc.config.RPCError as e:
+ raise StatsHttpdDataError("Stats module: %s" % str(e))
except (isc.cc.session.SessionTimeout,
isc.cc.session.SessionError) as err:
raise StatsHttpdError("%s: %s" %
(err.__class__.__name__, err))
- else:
- if rcode == 0:
- return value
- else:
- raise StatsHttpdDataError("Stats module: %s" % str(value))
def get_stats_spec(self, owner=None, name=None):
"""Requests statistics data to the Stats daemon and returns
@@ -493,15 +486,9 @@ class StatsHttpd:
if name is not None:
param['name'] = name
try:
- seq = self.cc_session.group_sendmsg(
- isc.config.ccsession.create_command('showschema', param), 'Stats')
- (answer, env) = self.cc_session.group_recvmsg(False, seq)
- if answer:
- (rcode, value) = isc.config.ccsession.parse_answer(answer)
- if rcode == 0:
- return value
- else:
- raise StatsHttpdDataError("Stats module: %s" % str(value))
+ return self.mccs.rpc_call('showschema', 'Stats', params=param)
+ except isc.config.RPCError as e:
+ raise StatsHttpdDataError("Stats module: %s" % str(e))
except (isc.cc.session.SessionTimeout,
isc.cc.session.SessionError) as err:
raise StatsHttpdError("%s: %s" %
diff --git a/src/bin/xfrin/tests/xfrin_test.py b/src/bin/xfrin/tests/xfrin_test.py
index a1714de..272124b 100644
--- a/src/bin/xfrin/tests/xfrin_test.py
+++ b/src/bin/xfrin/tests/xfrin_test.py
@@ -2909,7 +2909,7 @@ class TestXfrinProcessMockCCSession:
self.recv_called = False
self.recv_called_correctly = False
- def group_sendmsg(self, msg, module):
+ def group_sendmsg(self, msg, module, want_answer=False):
self.send_called = True
if module == 'Auth' and msg['command'][0] == 'loadzone':
self.send_called_correctly = True
diff --git a/src/bin/xfrin/xfrin.py.in b/src/bin/xfrin/xfrin.py.in
index 55d9818..ac479b4 100755
--- a/src/bin/xfrin/xfrin.py.in
+++ b/src/bin/xfrin/xfrin.py.in
@@ -1324,7 +1324,8 @@ def _do_auth_loadzone(server, zone_name, zone_class):
param = msg['command'][1]
logger.debug(DBG_XFRIN_TRACE, XFRIN_AUTH_LOADZONE, param["origin"],
param["class"])
- seq = server._send_cc_session.group_sendmsg(msg, AUTH_MODULE_NAME)
+ seq = server._send_cc_session.group_sendmsg(msg, AUTH_MODULE_NAME,
+ want_answer=True)
answer, env = server._send_cc_session.group_recvmsg(False, seq)
class Xfrin:
@@ -1630,18 +1631,29 @@ class Xfrin:
param = {'zone_name': zone_name.to_text(),
'zone_class': zone_class.to_text()}
if xfr_result == XFRIN_OK:
+ # FIXME: Due to the hack with two different CC sessions
+ # (see the _cc_setup comment) and the fact the rpc_call
+ # is a high-level call present only at ModuleCCSession,
+ # we are forced to use the primitive way of manually
+ # calling group_sendmsg and the group_recvmsg. Also, why
+ # do we do group_recvmsg when we don't need the answer?
+ # And why is this direct RPC call if a notification would
+ # be more appropriate?
_do_auth_loadzone(self, zone_name, zone_class)
msg = create_command(notify_out.ZONE_NEW_DATA_READY_CMD, param)
# catch the exception, in case msgq has been killed.
try:
seq = self._send_cc_session.group_sendmsg(msg,
- XFROUT_MODULE_NAME)
+ XFROUT_MODULE_NAME,
+ want_answer=True)
try:
answer, env = self._send_cc_session.group_recvmsg(False,
seq)
except isc.cc.session.SessionTimeout:
pass # for now we just ignore the failure
- seq = self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
+ seq = self._send_cc_session.group_sendmsg(msg,
+ ZONE_MANAGER_MODULE_NAME,
+ want_answer=True)
try:
answer, env = self._send_cc_session.group_recvmsg(False,
seq)
@@ -1654,7 +1666,8 @@ class Xfrin:
msg = create_command(notify_out.ZONE_XFRIN_FAILED, param)
# catch the exception, in case msgq has been killed.
try:
- seq = self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME)
+ seq = self._send_cc_session.group_sendmsg(msg, ZONE_MANAGER_MODULE_NAME,
+ want_answer=True)
try:
answer, env = self._send_cc_session.group_recvmsg(False,
seq)
diff --git a/src/bin/zonemgr/tests/zonemgr_test.py b/src/bin/zonemgr/tests/zonemgr_test.py
index 42ed679..f8acf66 100644
--- a/src/bin/zonemgr/tests/zonemgr_test.py
+++ b/src/bin/zonemgr/tests/zonemgr_test.py
@@ -41,23 +41,16 @@ TEST_SQLITE3_DBFILE = os.getenv("TESTDATAOBJDIR") + '/initdb.file'
class ZonemgrTestException(Exception):
pass
-class MySession():
- def __init__(self):
- pass
-
- def group_sendmsg(self, msg, module_name):
- if module_name not in ("Auth", "Xfrin"):
- raise ZonemgrTestException("module name not exist")
-
- def group_recvmsg(self, nonblock, seq):
- return None, None
-
class FakeCCSession(isc.config.ConfigData, MockModuleCCSession):
def __init__(self):
module_spec = isc.config.module_spec_from_file(SPECFILE_LOCATION)
ConfigData.__init__(self, module_spec)
MockModuleCCSession.__init__(self)
+ def rpc_call(self, command, module, instance="*", to="*", params=None):
+ if module not in ("Auth", "Xfrin"):
+ raise ZonemgrTestException("module name not exist")
+
def get_remote_config_value(self, module_name, identifier):
if module_name == "Auth" and identifier == "database_file":
return TEST_SQLITE3_DBFILE, False
@@ -84,7 +77,7 @@ class MyZonemgrRefresh(ZonemgrRefresh):
return None
sqlite3_ds.get_zone_soa = get_zone_soa
- ZonemgrRefresh.__init__(self, MySession(), TEST_SQLITE3_DBFILE,
+ ZonemgrRefresh.__init__(self, None, TEST_SQLITE3_DBFILE,
self._slave_socket, FakeCCSession())
current_time = time.time()
self._zonemgr_refresh_info = {
@@ -619,7 +612,6 @@ class MyZonemgr(Zonemgr):
self._db_file = TEST_SQLITE3_DBFILE
self._zone_refresh = None
self._shutdown_event = threading.Event()
- self._cc = MySession()
self._module_cc = FakeCCSession()
self._config_data = {
"lowerbound_refresh" : 10,
diff --git a/src/bin/zonemgr/zonemgr.py.in b/src/bin/zonemgr/zonemgr.py.in
index 40bfa39..1f18fd5 100755
--- a/src/bin/zonemgr/zonemgr.py.in
+++ b/src/bin/zonemgr/zonemgr.py.in
@@ -105,6 +105,7 @@ class ZonemgrRefresh:
def __init__(self, cc, db_file, slave_socket, module_cc_session):
self._cc = cc
+ self._mccs = module_cc_session
self._check_sock = slave_socket
self._db_file = db_file
self._zonemgr_refresh_info = {}
@@ -277,15 +278,12 @@ class ZonemgrRefresh:
def _send_command(self, module_name, command_name, params):
"""Send command between modules."""
- msg = create_command(command_name, params)
try:
- seq = self._cc.group_sendmsg(msg, module_name)
- try:
- answer, env = self._cc.group_recvmsg(False, seq)
- except isc.cc.session.SessionTimeout:
- pass # for now we just ignore the failure
- except socket.error:
+ self._mccs.rpc_call(command_name, module_name, params=params)
+ except socket.error: # FIXME: WTF?
logger.error(ZONEMGR_SEND_FAIL, module_name)
+ except (isc.cc.session.SessionTimeout, isc.config.RPCError):
+ pass # for now we just ignore the failure
def _find_need_do_refresh_zone(self):
"""Find the first zone need do refresh, if no zone need
diff --git a/src/lib/python/isc/config/ccsession.py b/src/lib/python/isc/config/ccsession.py
index 10e5e8c..21d0780 100644
--- a/src/lib/python/isc/config/ccsession.py
+++ b/src/lib/python/isc/config/ccsession.py
@@ -501,7 +501,7 @@ class ModuleCCSession(ConfigData):
raise ModuleCCSessionError("CC Session timeout waiting for configuration manager")
def rpc_call(self, command, group, instance=CC_INSTANCE_WILDCARD,
- to=CC_TO_WILDCARD, **params):
+ to=CC_TO_WILDCARD, params=None):
"""
Create a command with the given name and parameters. Send it to a
recipient, wait for the answer and parse it.
diff --git a/src/lib/python/isc/config/tests/ccsession_test.py b/src/lib/python/isc/config/tests/ccsession_test.py
index cc81526..3c1c57e 100644
--- a/src/lib/python/isc/config/tests/ccsession_test.py
+++ b/src/lib/python/isc/config/tests/ccsession_test.py
@@ -297,8 +297,10 @@ class TestModuleCCSession(unittest.TestCase):
]
exception = None
try:
- result = mccs.rpc_call("test", "Spec2", param1="Param 1",
- param2="Param 2")
+ result = mccs.rpc_call("test", "Spec2", params={
+ "param1": "Param 1",
+ "param2": "Param 2"
+ })
except Exception as e:
# We first want to check the value sent, raise the exception
# afterwards. So store it for a short while.
More information about the bind10-changes
mailing list