BIND 10 trac930, updated. 3225575a1d7dc447b802efe5cc15687465acbbc4 Merge branch 'trac930' of ssh://bind10.isc.org/var/bind10/git/bind10 into trac930
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Jul 13 11:42:26 UTC 2011
The branch, trac930 has been updated
via 3225575a1d7dc447b802efe5cc15687465acbbc4 (commit)
via fd9ecffcb0f2efec55134214f592775f09beeeb5 (commit)
via 22b53398bc9734bf49214280c9d1c4690796dca6 (commit)
via bc84f2f852ee70b36eaaef4b4b0c57acc0c3fbba (commit)
via f4b6ee76908f0929a38fadce33f096ca2b90e97b (commit)
via ce0d7695c182d35cd859d65bd1020009418ce82a (commit)
via 0470f0fbba242529e3bfb96b36e077655c6ab78b (commit)
via f0212ac979bd415e91993472dc13d4e3ce8af9ff (commit)
via de90b6a18aa67cc4e80038d248b69fe700d398f8 (commit)
via 3b1918aeaa02185365241b58f95c971e1626ce58 (commit)
via 04027a910fa41a6ae2f6fec871f3717f07c7bcd8 (commit)
via 2b03d7e359f4f00c681f249ac37a9ce1cf9a8003 (commit)
via ef2750436b5dcaa010963d30b62b9adb8f8067a9 (commit)
via deaff8e25096bc988ea64bea7fbf3e58900c8d19 (commit)
via 806855d68d9298d08d57d3aadac26246fa29f884 (commit)
via 99d21295b8f7ac9b59b5a3959ce5a6e58cebef09 (commit)
via f8750c5b4683f932f633c24acb27ebee164677cd (commit)
via 7ed4e6195bf07482d197e2d27512cb1621032b36 (commit)
via 7963c5d1e8dccbd13408b1c43de7243a1eaa4e03 (commit)
via 80940bf1435927f3dadbe1a3ff247ab5521beeb9 (commit)
via 31f9234c32e59d1b3d447dfe333974266dcf9c1e (commit)
via 88c1fc7576f04eb0b8b47ce00c81891be1265492 (commit)
via 33ae22f4a64faeef24511ebc2b25f5c32bc47842 (commit)
via bf9c46a19ba59fa798236b64521fc6d95f18e076 (commit)
via 2357e7abc8bac23f60d79ca8abe81854b5550eea (commit)
via 0dd272381befd9b464365cc7df0bb2d761d0d2e0 (commit)
via 046f1b9556d3b8197c03225843ff96d0d79ae762 (commit)
via 65bc0fbf12199bee2d16b914a544a69345c37cae (commit)
via a2a8094104e32ed8249c2811c94f74b876f78b3d (commit)
via 933adf250348caf92c04f5249120333e3e300227 (commit)
via 1658417daeac170c4068fbbc6f4e3762ada0e72c (commit)
via 9ff2f7bc88be85c09d37209bd0feeb96ca256892 (commit)
via a837df2e0c4858543c0bd2e420f726b89994a7e2 (commit)
via 0cd32b208c9a92e5e773b7874a3f75ee58abd6c0 (commit)
via 5e1e54cbee0215374fb712152f7906fff960b334 (commit)
via f30f07e5b15e118686f5665c0a6dca430a95abba (commit)
via 63918fd91e570dbcc2c06f39c75083bbae6a2303 (commit)
via 5599a9aa3b735b42a4a726b79f0c85a0d38eb5da (commit)
via 469bda3f72a097af3dd1bde56d757d7ea916d996 (commit)
via a0209aebd72ab6ec63941d5881b58a3c689b943f (commit)
via 9dec49291c2ccefab6cf97b9146c292897783c5a (commit)
via 6c9695dac3a16574ff3e7d0d310cff3df6d542f6 (commit)
via 551a2d7f6ed5744170265ea5bc7b99690b58a6f5 (commit)
via 0529433796c0024e9345edd3c458e22e1aec9043 (commit)
via 91e59cdd3ffa76c041f774c4ff61cd865299ab75 (commit)
via e2127bd275b2263f06d7ba039123411c9b7cf07d (commit)
via 35d4ca9a46fd8372cce752577944b2fdc458a0f5 (commit)
via 4082b7fdb7a1b23518e2dcbb5077f52a79bffa8c (commit)
via 18ba901c91b5bd1e910c7ccc8ae1ebbb1e00fa36 (commit)
via 2f088998525f389391efb86ac4e917174449df85 (commit)
via 87fe9bf486e8671d74ed7e6683309a77add03f51 (commit)
from 041dbe39c85f68a3e0477e8fdd759b4b8186a2aa (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 3225575a1d7dc447b802efe5cc15687465acbbc4
Merge: fd9ecffcb0f2efec55134214f592775f09beeeb5 041dbe39c85f68a3e0477e8fdd759b4b8186a2aa
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Jul 13 20:41:52 2011 +0900
Merge branch 'trac930' of ssh://bind10.isc.org/var/bind10/git/bind10 into trac930
Conflicts:
src/bin/stats/stats.py.in
src/bin/stats/stats_httpd.py.in
src/bin/stats/tests/Makefile.am
src/bin/stats/tests/b10-stats-httpd_test.py
src/bin/stats/tests/b10-stats_test.py
src/bin/stats/tests/isc/Makefile.am
src/bin/stats/tests/isc/log/__init__.py
src/bin/stats/tests/test_utils.py
commit fd9ecffcb0f2efec55134214f592775f09beeeb5
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Wed Jul 13 20:25:54 2011 +0900
[trac930]
- increase seconds in sleep time which is before HTTP client connects to the server
- delete 'test_log_message' because of the deletion of original function
commit 22b53398bc9734bf49214280c9d1c4690796dca6
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 21:22:34 2011 +0900
[trac930] remove unneeded empty TODO comments
commit bc84f2f852ee70b36eaaef4b4b0c57acc0c3fbba
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 21:09:41 2011 +0900
[trac930] add new entry for #928-#930
commit f4b6ee76908f0929a38fadce33f096ca2b90e97b
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 20:08:22 2011 +0900
[trac930] refurbish the unittests for new stats module, new stats httpd module
and new mockups and utilities in test_utils.py
commit ce0d7695c182d35cd859d65bd1020009418ce82a
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 19:56:24 2011 +0900
[trac930] modify Stats
- remove unneeded subject and listener classes
- add StatsError for handling errors in Stats
- add some new methods (update_modules, update_statistics_data and
get_statistics_data)
- modify implementations of existent commands(show and set) according changes
stats.spec
- remove reset and remove command because stats module couldn't manage other
modules' statistics data schema
- add implementation of strict validation of each statistics data
(If the validation is failed, it puts out the error.)
- stats module shows its PID when status command invoked
- add new command showschema invokable via bindctl
- set command requires arguments of owner module name and statistics item name
- show and showschema commands accepts arguments of owner module name and
statistics item name
- exits at exit code 1 if got runtime errors
- has boot time in _BASETIME
commit 0470f0fbba242529e3bfb96b36e077655c6ab78b
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 19:40:15 2011 +0900
[trac930]
- remove "stats-schema.spec" setting and getting statistics data schema via
this spec file
- add "version" item in DEFAULT_CONFIG
- get the address family by socket.getaddrinfo function with specified
server_address in advance, and create HttpServer object once, in stead of
creating double HttpServer objects for IPv6 and IPv4 in the prior code
(It is aimed for avoiding to fail to close the once opened sockets.)
- open HTTP port in start method
- avoid calling config_handler recursively in the except statement
- create XML, XSD, XSL documents after getting statistics data and schema from
remote stats module via CC session
- definitely close once opened template file object
commit f0212ac979bd415e91993472dc13d4e3ce8af9ff
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 16:33:59 2011 +0900
[trac930] update spec file of stats module
- update description of status command, shutdown command and show command
- change argument of show command (Owner module name of statistics data can be
specified)
- change argument of set command (Owner module name of statistics data is
always required)
- add showschema command which shows statistics data schema of each module
specified)
- disabled reset command and remove command
commit de90b6a18aa67cc4e80038d248b69fe700d398f8
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 16:21:49 2011 +0900
[trac930] update argument name and argument format of set command in auth module and boss module
and also update related unittests of their modules
commit 3b1918aeaa02185365241b58f95c971e1626ce58
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 16:18:38 2011 +0900
[trac930] remove description about removing statistics data by stats module
update example format in bindctl when show command of stats module is invoked
commit 04027a910fa41a6ae2f6fec871f3717f07c7bcd8
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 16:13:17 2011 +0900
[trac930] add a column "Owner" in the table tag
commit 2b03d7e359f4f00c681f249ac37a9ce1cf9a8003
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 16:12:09 2011 +0900
[trac930] remove descriptions about "stats-schema.spec" and add description about new
features because stats module can be requested to show statistics data schema.
commit ef2750436b5dcaa010963d30b62b9adb8f8067a9
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 16:00:30 2011 +0900
[trac930] add utilities and mock-up modules for unittests of
statistics modules and change some environ variables (PYTHONPATH,
CONFIG_TESTDATA_PATH) in Makefile
test_utilies.py internally calls msgq, cfgmgr and some mock modules
with threads for as real situation as possible.
commit deaff8e25096bc988ea64bea7fbf3e58900c8d19
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 15:57:41 2011 +0900
[trac930] remove unneeded mockups, fake modules and dummy data
commit 806855d68d9298d08d57d3aadac26246fa29f884
Author: Naoki Kambe <kambe at jprs.co.jp>
Date: Fri Jul 8 15:55:55 2011 +0900
[trac930] remove unneeded specfile "stats-schema.spec"
-----------------------------------------------------------------------
Summary of changes:
doc/Doxyfile | 4 +-
src/bin/bindctl/bindcmd.py | 5 +-
src/bin/resolver/resolver_messages.mes | 249 +++++++++++---------
src/bin/stats/Makefile.am | 10 +
src/bin/stats/stats.py.in | 70 +++---
src/bin/stats/stats_httpd.py.in | 98 ++++----
src/bin/stats/stats_httpd_messages.mes | 92 +++++++
src/bin/stats/stats_messages.mes | 75 ++++++
src/bin/stats/tests/Makefile.am | 8 +
src/bin/stats/tests/b10-stats-httpd_test.py | 57 ++---
src/bin/stats/tests/b10-stats_test.py | 33 +---
src/bin/stats/tests/isc/Makefile.am | 8 +
.../stats/tests/isc/log}/Makefile.am | 3 +-
.../python => bin/stats/tests}/isc/log/__init__.py | 0
src/bin/stats/tests/test_utils.py | 37 ++--
src/lib/log/compiler/message.cc | 92 +++++--
src/lib/python/isc/config/Makefile.am | 16 +-
src/lib/python/isc/config/ccsession.py | 14 +-
src/lib/python/isc/config/config_messages.mes | 33 +++
src/lib/python/isc/config/tests/ccsession_test.py | 2 +
src/lib/python/isc/notify/Makefile.am | 11 +
src/lib/python/isc/notify/notify_out.py | 71 +++---
src/lib/python/isc/notify/notify_out_messages.mes | 83 +++++++
src/lib/python/isc/notify/tests/notify_out_test.py | 25 ++-
src/lib/resolve/resolve_messages.mes | 14 +-
src/lib/util/filename.cc | 18 ++
src/lib/util/filename.h | 7 +
src/lib/util/tests/filename_unittest.cc | 37 +++
28 files changed, 800 insertions(+), 372 deletions(-)
create mode 100644 src/bin/stats/stats_httpd_messages.mes
create mode 100644 src/bin/stats/stats_messages.mes
create mode 100644 src/bin/stats/tests/isc/Makefile.am
copy src/{lib/python/isc/testutils => bin/stats/tests/isc/log}/Makefile.am (52%)
copy src/{lib/python => bin/stats/tests}/isc/log/__init__.py (100%)
create mode 100644 src/lib/python/isc/config/config_messages.mes
create mode 100644 src/lib/python/isc/notify/notify_out_messages.mes
-----------------------------------------------------------------------
diff --git a/doc/Doxyfile b/doc/Doxyfile
index b8a4656..ceb806f 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -570,8 +570,8 @@ WARN_LOGFILE =
INPUT = ../src/lib/cc ../src/lib/config \
../src/lib/cryptolink ../src/lib/dns ../src/lib/datasrc \
- ../src/bin/auth ../src/bin/resolver ../src/lib/bench \
- ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas \
+ ../src/bin/auth ../src/bin/resolver ../src/lib/bench ../src/lib/log \
+ ../src/lib/log/compiler ../src/lib/asiolink/ ../src/lib/nsas \
../src/lib/testutils ../src/lib/cache ../src/lib/server_common/ \
../src/bin/sockcreator/ ../src/lib/util/ \
../src/lib/resolve ../src/lib/acl
diff --git a/src/bin/bindctl/bindcmd.py b/src/bin/bindctl/bindcmd.py
index 8973aa5..0bfcda5 100644
--- a/src/bin/bindctl/bindcmd.py
+++ b/src/bin/bindctl/bindcmd.py
@@ -674,7 +674,10 @@ class BindCmdInterpreter(Cmd):
elif cmd.command == "revert":
self.config_data.clear_local_changes()
elif cmd.command == "commit":
- self.config_data.commit()
+ try:
+ self.config_data.commit()
+ except isc.config.ModuleCCSessionError as mcse:
+ print(str(mcse))
elif cmd.command == "diff":
print(self.config_data.get_local_changes());
elif cmd.command == "go":
diff --git a/src/bin/resolver/resolver_messages.mes b/src/bin/resolver/resolver_messages.mes
index 05b9a8b..b44115a 100644
--- a/src/bin/resolver/resolver_messages.mes
+++ b/src/bin/resolver/resolver_messages.mes
@@ -16,151 +16,174 @@
# along with the resolver methods.
% RESOLVER_AXFR_TCP AXFR request received over TCP
-A debug message, the resolver received a NOTIFY message over TCP. The server
-cannot process it and will return an error message to the sender with the
-RCODE set to NOTIMP.
+This is a debug message output when the resolver received a request for
+an AXFR (full transfer of a zone) over TCP. Only authoritative servers
+are able to handle AXFR requests, so the resolver will return an error
+message to the sender with the RCODE set to NOTIMP.
% RESOLVER_AXFR_UDP AXFR request received over UDP
-A debug message, the resolver received a NOTIFY message over UDP. The server
-cannot process it (and in any case, an AXFR request should be sent over TCP)
-and will return an error message to the sender with the RCODE set to FORMERR.
+This is a debug message output when the resolver received a request for
+an AXFR (full transfer of a zone) over UDP. Only authoritative servers
+are able to handle AXFR requests (and in any case, an AXFR request should
+be sent over TCP), so the resolver will return an error message to the
+sender with the RCODE set to NOTIMP.
% RESOLVER_CLIENT_TIME_SMALL client timeout of %1 is too small
-An error indicating that the configuration value specified for the query
-timeout is too small.
+During the update of the resolver's configuration parameters, the value
+of the client timeout was found to be too small. The configuration
+update was abandoned and the parameters were not changed.
% RESOLVER_CONFIG_CHANNEL configuration channel created
-A debug message, output when the resolver has successfully established a
-connection to the configuration channel.
+This is a debug message output when the resolver has successfully
+established a connection to the configuration channel.
% RESOLVER_CONFIG_ERROR error in configuration: %1
-An error was detected in a configuration update received by the resolver. This
-may be in the format of the configuration message (in which case this is a
-programming error) or it may be in the data supplied (in which case it is
-a user error). The reason for the error, given as a parameter in the message,
-will give more details.
+An error was detected in a configuration update received by the
+resolver. This may be in the format of the configuration message (in
+which case this is a programming error) or it may be in the data supplied
+(in which case it is a user error). The reason for the error, included
+in the message, will give more details. The configuration update is
+not applied and the resolver parameters were not changed.
% RESOLVER_CONFIG_LOADED configuration loaded
-A debug message, output when the resolver configuration has been successfully
-loaded.
+This is a debug message output when the resolver configuration has been
+successfully loaded.
% RESOLVER_CONFIG_UPDATED configuration updated: %1
-A debug message, the configuration has been updated with the specified
-information.
+This is a debug message output when the resolver configuration is being
+updated with the specified information.
% RESOLVER_CREATED main resolver object created
-A debug message, output when the Resolver() object has been created.
+This is a debug message indicating that the main resolver object has
+been created.
% RESOLVER_DNS_MESSAGE_RECEIVED DNS message received: %1
-A debug message, this always precedes some other logging message and is the
-formatted contents of the DNS packet that the other message refers to.
+This is a debug message from the resolver listing the contents of a
+received DNS message.
% RESOLVER_DNS_MESSAGE_SENT DNS message of %1 bytes sent: %2
-A debug message, this contains details of the response sent back to the querying
-system.
+This is a debug message containing details of the response returned by
+the resolver to the querying system.
% RESOLVER_FAILED resolver failed, reason: %1
-This is an error message output when an unhandled exception is caught by the
-resolver. All it can do is to shut down.
+This is an error message output when an unhandled exception is caught
+by the resolver. After this, the resolver will shut itself down.
+Please submit a bug report.
% RESOLVER_FORWARD_ADDRESS setting forward address %1(%2)
-This message may appear multiple times during startup, and it lists the
-forward addresses used by the resolver when running in forwarding mode.
+If the resolver is running in forward mode, this message will appear
+during startup to list the forward address. If multiple addresses are
+specified, it will appear once for each address.
% RESOLVER_FORWARD_QUERY processing forward query
-The received query has passed all checks and is being forwarded to upstream
+This is a debug message indicating that a query received by the resolver
+has passed a set of checks (message is well-formed, it is allowed by the
+ACL, it is a supported opcode etc.) and is being forwarded to upstream
servers.
% RESOLVER_HEADER_ERROR message received, exception when processing header: %1
-A debug message noting that an exception occurred during the processing of
-a received packet. The packet has been dropped.
+This is a debug message from the resolver noting that an exception
+occurred during the processing of a received packet. The packet has
+been dropped.
% RESOLVER_IXFR IXFR request received
-The resolver received a NOTIFY message over TCP. The server cannot process it
-and will return an error message to the sender with the RCODE set to NOTIMP.
+This is a debug message indicating that the resolver received a request
+for an IXFR (incremental transfer of a zone). Only authoritative servers
+are able to handle IXFR requests, so the resolver will return an error
+message to the sender with the RCODE set to NOTIMP.
% RESOLVER_LOOKUP_TIME_SMALL lookup timeout of %1 is too small
-An error indicating that the configuration value specified for the lookup
-timeout is too small.
+During the update of the resolver's configuration parameters, the value
+of the lookup timeout was found to be too small. The configuration
+update will not be applied.
% RESOLVER_MESSAGE_ERROR error parsing received message: %1 - returning %2
-A debug message noting that the resolver received a message and the
-parsing of the body of the message failed due to some error (although
-the parsing of the header succeeded). The message parameters give a
-textual description of the problem and the RCODE returned.
+This is a debug message noting that parsing of the body of a received
+message by the resolver failed due to some error (although the parsing of
+the header succeeded). The message parameters give a textual description
+of the problem and the RCODE returned.
% RESOLVER_NEGATIVE_RETRIES negative number of retries (%1) specified in the configuration
-An error message indicating that the resolver configuration has specified a
-negative retry count. Only zero or positive values are valid.
+This error is issued when a resolver configuration update has specified
+a negative retry count: only zero or positive values are valid. The
+configuration update was abandoned and the parameters were not changed.
% RESOLVER_NON_IN_PACKET non-IN class request received, returning REFUSED message
-A debug message, the resolver has received a DNS packet that was not IN class.
-The resolver cannot handle such packets, so is returning a REFUSED response to
-the sender.
+This debug message is issued when resolver has received a DNS packet that
+was not IN (Internet) class. The resolver cannot handle such packets,
+so is returning a REFUSED response to the sender.
% RESOLVER_NORMAL_QUERY processing normal query
-The received query has passed all checks and is being processed by the resolver.
+This is a debug message indicating that the query received by the resolver
+has passed a set of checks (message is well-formed, it is allowed by the
+ACL, it is a supported opcode etc.) and is being processed the resolver.
% RESOLVER_NOTIFY_RECEIVED NOTIFY arrived but server is not authoritative
-The resolver received a NOTIFY message. As the server is not authoritative it
-cannot process it, so it returns an error message to the sender with the RCODE
-set to NOTAUTH.
+The resolver has received a NOTIFY message. As the server is not
+authoritative it cannot process it, so it returns an error message to
+the sender with the RCODE set to NOTAUTH.
% RESOLVER_NOT_ONE_QUESTION query contained %1 questions, exactly one question was expected
-A debug message, the resolver received a query that contained the number of
-entires in the question section detailed in the message. This is a malformed
-message, as a DNS query must contain only one question. The resolver will
-return a message to the sender with the RCODE set to FORMERR.
+This debug message indicates that the resolver received a query that
+contained the number of entries in the question section detailed in
+the message. This is a malformed message, as a DNS query must contain
+only one question. The resolver will return a message to the sender
+with the RCODE set to FORMERR.
% RESOLVER_NO_ROOT_ADDRESS no root addresses available
-A warning message during startup, indicates that no root addresses have been
-set. This may be because the resolver will get them from a priming query.
+A warning message issued during resolver startup, this indicates that
+no root addresses have been set. This may be because the resolver will
+get them from a priming query.
% RESOLVER_PARSE_ERROR error parsing received message: %1 - returning %2
-A debug message noting that the resolver received a message and the parsing
-of the body of the message failed due to some non-protocol related reason
-(although the parsing of the header succeeded). The message parameters give
-a textual description of the problem and the RCODE returned.
+This is a debug message noting that the resolver received a message and
+the parsing of the body of the message failed due to some non-protocol
+related reason (although the parsing of the header succeeded).
+The message parameters give a textual description of the problem and
+the RCODE returned.
% RESOLVER_PRINT_COMMAND print message command, arguments are: %1
-This message is logged when a "print_message" command is received over the
-command channel.
+This debug message is logged when a "print_message" command is received
+by the resolver over the command channel.
% RESOLVER_PROTOCOL_ERROR protocol error parsing received message: %1 - returning %2
-A debug message noting that the resolver received a message and the parsing
-of the body of the message failed due to some protocol error (although the
-parsing of the header succeeded). The message parameters give a textual
-description of the problem and the RCODE returned.
+This is a debug message noting that the resolver received a message and
+the parsing of the body of the message failed due to some protocol error
+(although the parsing of the header succeeded). The message parameters
+give a textual description of the problem and the RCODE returned.
% RESOLVER_QUERY_SETUP query setup
-A debug message noting that the resolver is creating a RecursiveQuery object.
+This is a debug message noting that the resolver is creating a
+RecursiveQuery object.
% RESOLVER_QUERY_SHUTDOWN query shutdown
-A debug message noting that the resolver is destroying a RecursiveQuery object.
+This is a debug message noting that the resolver is destroying a
+RecursiveQuery object.
% RESOLVER_QUERY_TIME_SMALL query timeout of %1 is too small
-An error indicating that the configuration value specified for the query
-timeout is too small.
+During the update of the resolver's configuration parameters, the value
+of the query timeout was found to be too small. The configuration
+parameters were not changed.
% RESOLVER_RECEIVED_MESSAGE resolver has received a DNS message
-A debug message indicating that the resolver has received a message. Depending
-on the debug settings, subsequent log output will indicate the nature of the
-message.
+This is a debug message indicating that the resolver has received a
+DNS message. Depending on the debug settings, subsequent log output
+will indicate the nature of the message.
% RESOLVER_RECURSIVE running in recursive mode
-This is an informational message that appears at startup noting that the
-resolver is running in recursive mode.
+This is an informational message that appears at startup noting that
+the resolver is running in recursive mode.
% RESOLVER_SERVICE_CREATED service object created
-A debug message, output when the main service object (which handles the
-received queries) is created.
+This debug message is output when resolver creates the main service object
+(which handles the received queries).
% RESOLVER_SET_PARAMS query timeout: %1, client timeout: %2, lookup timeout: %3, retry count: %4
-A debug message, lists the parameters being set for the resolver. These are:
+This debug message lists the parameters being set for the resolver. These are:
query timeout: the timeout (in ms) used for queries originated by the resolver
-to upstream servers. Client timeout: the interval to resolver a query by
+to upstream servers. Client timeout: the interval to resolve a query by
a client: after this time, the resolver sends back a SERVFAIL to the client
-whilst continuing to resolver the query. Lookup timeout: the time at which the
+whilst continuing to resolve the query. Lookup timeout: the time at which the
resolver gives up trying to resolve a query. Retry count: the number of times
the resolver will retry a query to an upstream server if it gets a timeout.
@@ -169,17 +192,18 @@ resolution of the client query might require a large number of queries to
upstream nameservers. Even if none of these queries timeout, the total time
taken to perform all the queries may exceed the client timeout. When this
happens, a SERVFAIL is returned to the client, but the resolver continues
-with the resolution process. Data received is added to the cache. However,
+with the resolution process; data received is added to the cache. However,
there comes a time - the lookup timeout - when even the resolver gives up.
At this point it will wait for pending upstream queries to complete or
timeout and drop the query.
% RESOLVER_SET_ROOT_ADDRESS setting root address %1(%2)
-This message may appear multiple times during startup; it lists the root
-addresses used by the resolver.
+This message gives the address of one of the root servers used by the
+resolver. It is output during startup and may appear multiple times,
+once for each root server address.
% RESOLVER_SHUTDOWN resolver shutdown complete
-This information message is output when the resolver has shut down.
+This informational message is output when the resolver has shut down.
% RESOLVER_STARTED resolver started
This informational message is output by the resolver when all initialization
@@ -189,35 +213,36 @@ has been completed and it is entering its main loop.
An informational message, this is output when the resolver starts up.
% RESOLVER_UNEXPECTED_RESPONSE received unexpected response, ignoring
-A debug message noting that the server has received a response instead of a
-query and is ignoring it.
+This is a debug message noting that the resolver received a DNS response
+packet on the port on which is it listening for queries. The packet
+has been ignored.
% RESOLVER_UNSUPPORTED_OPCODE opcode %1 not supported by the resolver
-A debug message, the resolver received a message with an unsupported opcode
-(it can only process QUERY opcodes). It will return a message to the sender
-with the RCODE set to NOTIMP.
-
-% RESOLVER_SET_QUERY_ACL query ACL is configured
-A debug message that appears when a new query ACL is configured for the
-resolver.
-
-% RESOLVER_QUERY_ACCEPTED query accepted: '%1/%2/%3' from %4
-A debug message that indicates an incoming query is accepted in terms of
-the query ACL. The log message shows the query in the form of
-<query name>/<query type>/<query class>, and the client that sends the
-query in the form of <Source IP address>#<source port>.
-
-% RESOLVER_QUERY_REJECTED query rejected: '%1/%2/%3' from %4
-An informational message that indicates an incoming query is rejected
-in terms of the query ACL. This results in a response with an RCODE of
-REFUSED. The log message shows the query in the form of <query
-name>/<query type>/<query class>, and the client that sends the
-query in the form of <Source IP address>#<source port>.
-
-% RESOLVER_QUERY_DROPPED query dropped: '%1/%2/%3' from %4
-An informational message that indicates an incoming query is dropped
-in terms of the query ACL. Unlike the RESOLVER_QUERY_REJECTED
-case, the server does not return any response. The log message
-shows the query in the form of <query name>/<query type>/<query
-class>, and the client that sends the query in the form of <Source
-IP address>#<source port>.
+This is debug message output when the resolver received a message with an
+unsupported opcode (it can only process QUERY opcodes). It will return
+a message to the sender with the RCODE set to NOTIMP.
+
+% RESOLVER_SET_QUERY_ACL query ACL is configured
+This debug message is generated when a new query ACL is configured for
+the resolver.
+
+% RESOLVER_QUERY_ACCEPTED query accepted: '%1/%2/%3' from %4
+This debug message is produced by the resolver when an incoming query
+is accepted in terms of the query ACL. The log message shows the query
+in the form of <query name>/<query type>/<query class>, and the client
+that sends the query in the form of <Source IP address>#<source port>.
+
+% RESOLVER_QUERY_REJECTED query rejected: '%1/%2/%3' from %4
+This is an informational message that indicates an incoming query has
+been rejected by the resolver because of the query ACL. This results
+in a response with an RCODE of REFUSED. The log message shows the query
+in the form of <query name>/<query type>/<query class>, and the client
+that sends the query in the form of <Source IP address>#<source port>.
+
+% RESOLVER_QUERY_DROPPED query dropped: '%1/%2/%3' from %4
+This is an informational message that indicates an incoming query has
+been dropped by the resolver because of the query ACL. Unlike the
+RESOLVER_QUERY_REJECTED case, the server does not return any response.
+The log message shows the query in the form of <query name>/<query
+type>/<query class>, and the client that sends the query in the form of
+<Source IP address>#<source port>.
diff --git a/src/bin/stats/Makefile.am b/src/bin/stats/Makefile.am
index 80869e2..49cadad 100644
--- a/src/bin/stats/Makefile.am
+++ b/src/bin/stats/Makefile.am
@@ -7,14 +7,18 @@ pkglibexec_SCRIPTS = b10-stats b10-stats-httpd
b10_statsdir = $(pkgdatadir)
b10_stats_DATA = stats.spec stats-httpd.spec
b10_stats_DATA += stats-httpd-xml.tpl stats-httpd-xsd.tpl stats-httpd-xsl.tpl
+pyexec_DATA = stats_messages.py stats_httpd_messages.py
CLEANFILES = b10-stats stats.pyc
CLEANFILES += b10-stats-httpd stats_httpd.pyc
+CLEANFILES += stats_messages.py stats_messages.pyc
+CLEANFILES += stats_httpd_messages.py stats_httpd_messages.pyc
man_MANS = b10-stats.8 b10-stats-httpd.8
EXTRA_DIST = $(man_MANS) b10-stats.xml b10-stats-httpd.xml
EXTRA_DIST += stats.spec stats-httpd.spec
EXTRA_DIST += stats-httpd-xml.tpl stats-httpd-xsd.tpl stats-httpd-xsl.tpl
+EXTRA_DIST += stats_messages.mes stats_httpd_messages.mes
if ENABLE_MAN
@@ -26,6 +30,12 @@ b10-stats-httpd.8: b10-stats-httpd.xml
endif
+stats_messages.py: stats_messages.mes
+ $(top_builddir)/src/lib/log/compiler/message -p $(top_srcdir)/src/bin/stats/stats_messages.mes
+
+stats_httpd_messages.py: stats_httpd_messages.mes
+ $(top_builddir)/src/lib/log/compiler/message -p $(top_srcdir)/src/bin/stats/stats_httpd_messages.mes
+
# this is done here since configure.ac AC_OUTPUT doesn't expand exec_prefix
b10-stats: stats.py
$(SED) -e "s|@@PYTHONPATH@@|@pyexecdir@|" stats.py >$@
diff --git a/src/bin/stats/stats.py.in b/src/bin/stats/stats.py.in
index 77ca1a8..3faa305 100644
--- a/src/bin/stats/stats.py.in
+++ b/src/bin/stats/stats.py.in
@@ -26,6 +26,15 @@ from optparse import OptionParser, OptionValueError
import isc
import isc.util.process
+import isc.log
+from stats_messages import *
+
+isc.log.init("b10-stats")
+logger = isc.log.Logger("stats")
+
+# Some constants for debug levels, these should be removed when we
+# have #1074
+DBG_STATS_MESSAGING = 30
# This is for boot_time of Stats
_BASETIME = gmtime()
@@ -107,8 +116,7 @@ class Stats:
"""
Main class of stats module
"""
- def __init__(self, verbose=False):
- self.verbose = verbose
+ def __init__(self):
self.running = False
# create ModuleCCSession object
self.mccs = isc.config.ModuleCCSession(SPECFILE_LOCATION,
@@ -131,9 +139,7 @@ class Stats:
kwargs = parse_spec(cmd["command_args"])
self.callbacks[name] = Callback(command=callback, kwargs=kwargs)
except AttributeError:
- raise StatsError(
- "Caught undefined command while parsing spec file: "
- +str(cmd["command_name"]))
+ raise StatsError(STATS_UNKNOWN_COMMAND_IN_SPEC, cmd["command_name"])
self.mccs.start()
def start(self):
@@ -141,12 +147,12 @@ class Stats:
Start stats module
"""
self.running = True
- if self.verbose:
- sys.stdout.write("[b10-stats] starting\n")
+ # TODO: should be added into new logging interface
+ # if self.verbose:
+ # sys.stdout.write("[b10-stats] starting\n")
- # send to Boss
- if self.verbose:
- sys.stdout.write("[b10-stats] request Bob to send statistics data\n")
+ # request Bob to send statistics data
+ logger.debug(DBG_STATS_MESSAGING, STATS_SEND_REQUEST_BOSS)
cmd = isc.config.ccsession.create_command("sendstats", None)
seq = self.cc_session.group_sendmsg(cmd, 'Boss')
self.cc_session.group_recvmsg(True, seq)
@@ -167,8 +173,8 @@ class Stats:
"""
handle a configure from the cc channel
"""
- if self.verbose:
- sys.stdout.write("[b10-stats] newconfig received: "+str(new_config)+"\n")
+ logger.debug(DBG_STATS_MESSAGING, STATS_RECEIVED_NEW_CONFIG,
+ new_config)
# do nothing currently
return isc.config.create_answer(0)
@@ -184,9 +190,7 @@ class Stats:
else:
return callback()
else:
- if self.verbose:
- sys.stdout.write("[b10-stats] Unknown command received: '"
- + str(command) + "'\n")
+ logger.error(STATS_RECEIVED_UNKNOWN_COMMAND, command)
return isc.config.create_answer(1, "Unknown command: '"+str(command)+"'")
def update_modules(self):
@@ -261,8 +265,7 @@ class Stats:
"""
handle status command
"""
- if self.verbose:
- sys.stdout.write("[b10-stats] 'status' command received\n")
+ logger.debug(DBG_STATS_MESSAGING, STATS_RECEIVED_STATUS_COMMAND)
return isc.config.create_answer(
0, "Stats is up. (PID " + str(os.getpid()) + ")")
@@ -270,8 +273,7 @@ class Stats:
"""
handle shutdown command
"""
- if self.verbose:
- sys.stdout.write("[b10-stats] 'shutdown' command received\n")
+ logger.info(STATS_RECEIVED_SHUTDOWN_COMMAND)
self.running = False
return isc.config.create_answer(0)
@@ -279,8 +281,13 @@ class Stats:
"""
handle show command
"""
- if self.verbose:
- sys.stdout.write("[b10-stats] 'show' command received\n")
+ if (owner or name):
+ logger.debug(DBG_STATS_MESSAGING,
+ STATS_RECEIVED_SHOW_NAME_COMMAND,
+ str(owner)+", "+str(name))
+ else:
+ logger.debug(DBG_STATS_MESSAGING,
+ STATS_RECEIVED_SHOW_ALL_COMMAND)
if owner and not name:
return isc.config.create_answer(1, "item name is not specified")
errors = self.update_statistics_data(
@@ -300,8 +307,9 @@ class Stats:
"""
handle show command
"""
- if self.verbose:
- sys.stdout.write("[b10-stats] 'showschema' command received\n")
+ # TODO: should be added into new logging interface
+ # if self.verbose:
+ # sys.stdout.write("[b10-stats] 'showschema' command received\n")
self.update_modules()
schema = {}
schema_byname = {}
@@ -351,14 +359,16 @@ if __name__ == "__main__":
"-v", "--verbose", dest="verbose", action="store_true",
help="display more about what is going on")
(options, args) = parser.parse_args()
- stats = Stats(verbose=options.verbose)
+ if options.verbose:
+ isc.log.init("b10-stats", "DEBUG", 99)
+ stats = Stats()
stats.start()
- except OptionValueError:
- sys.exit("[b10-stats] Error parsing options")
- except isc.cc.session.SessionError as se:
- sys.exit("[b10-stats] Error creating module, "
- + "is the command channel daemon running?")
+ except OptionValueError as ove:
+ logger.fatal(STATS_BAD_OPTION_VALUE, ove)
+ except SessionError as se:
+ logger.fatal(STATS_CC_SESSION_ERROR, se)
+ # TODO: should be added into new logging interface
except StatsError as se:
sys.exit("[b10-stats] %s" % se)
except KeyboardInterrupt as kie:
- sys.exit("[b10-stats] Interrupted, exiting")
+ logger.info(STATS_STOPPED_BY_KEYBOARD)
diff --git a/src/bin/stats/stats_httpd.py.in b/src/bin/stats/stats_httpd.py.in
index 721fc73..6f225ab 100755
--- a/src/bin/stats/stats_httpd.py.in
+++ b/src/bin/stats/stats_httpd.py.in
@@ -34,6 +34,17 @@ import isc.cc
import isc.config
import isc.util.process
+import isc.log
+from stats_httpd_messages import *
+
+isc.log.init("b10-stats-httpd")
+logger = isc.log.Logger("stats-httpd")
+
+# Some constants for debug levels, these should be removed when we
+# have #1074
+DBG_STATHTTPD_INIT = 10
+DBG_STATHTTPD_MESSAGING = 30
+
# If B10_FROM_SOURCE is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
# installed on the system
@@ -97,9 +108,7 @@ class HttpHandler(http.server.BaseHTTPRequestHandler):
return None
except StatsHttpdError as err:
self.send_error(500)
- if self.server.verbose:
- self.server.log_writer(
- "[b10-stats-httpd] %s\n" % err)
+ logger.error(STATHTTPD_SERVER_ERROR, err)
return None
else:
self.send_response(200)
@@ -108,15 +117,6 @@ class HttpHandler(http.server.BaseHTTPRequestHandler):
self.end_headers()
return body
- def log_message(self, format, *args):
- """Change the default log format"""
- if self.server.verbose:
- self.server.log_writer(
- "[b10-stats-httpd] %s - - [%s] %s\n" %
- (self.address_string(),
- self.log_date_time_string(),
- format%args))
-
class HttpServerError(Exception):
"""Exception class for HttpServer class. It is intended to be
passed from the HttpServer object to the StatsHttpd object."""
@@ -133,13 +133,12 @@ class HttpServer(http.server.HTTPServer):
sys.stderr.write. They are intended to be referred by HttpHandler
object."""
def __init__(self, server_address, handler,
- xml_handler, xsd_handler, xsl_handler, log_writer, verbose=False):
+ xml_handler, xsd_handler, xsl_handler, log_writer):
self.server_address = server_address
self.xml_handler = xml_handler
self.xsd_handler = xsd_handler
self.xsl_handler = xsl_handler
self.log_writer = log_writer
- self.verbose = verbose
http.server.HTTPServer.__init__(self, server_address, handler)
class StatsHttpdError(Exception):
@@ -153,8 +152,7 @@ class StatsHttpd:
statistics module. It handles HTTP requests, and command channel
and config channel CC session. It uses select.select function
while waiting for clients requests."""
- def __init__(self, verbose=False):
- self.verbose = verbose
+ def __init__(self):
self.running = False
self.poll_intval = 0.5
self.write_log = sys.stderr.write
@@ -166,8 +164,7 @@ class StatsHttpd:
def open_mccs(self):
"""Opens a ModuleCCSession object"""
# create ModuleCCSession
- if self.verbose:
- self.write_log("[b10-stats-httpd] Starting CC Session\n")
+ logger.debug(DBG_STATHTTPD_INIT, STATHTTPD_STARTING_CC_SESSION)
self.mccs = isc.config.ModuleCCSession(
SPECFILE_LOCATION, self.config_handler, self.command_handler)
self.cc_session = self.mccs._session
@@ -176,8 +173,8 @@ class StatsHttpd:
"""Closes a ModuleCCSession object"""
if self.mccs is None:
return
- if self.verbose:
- self.write_log("[b10-stats-httpd] Closing CC Session\n")
+
+ logger.debug(DBG_STATHTTPD_INIT, STATHTTPD_CLOSING_CC_SESSION)
self.mccs.close()
self.mccs = None
@@ -214,11 +211,9 @@ class StatsHttpd:
httpd = HttpServer(
server_address, HttpHandler,
self.xml_handler, self.xsd_handler, self.xsl_handler,
- self.write_log, self.verbose)
- if self.verbose:
- self.write_log(
- "[b10-stats-httpd] Started on address %s, port %s\n" %
- server_address)
+ self.write_log)
+ logger.info(STATHTTPD_STARTED, server_address[0],
+ server_address[1])
return httpd
except (socket.gaierror, socket.error,
OverflowError, TypeError) as err:
@@ -233,10 +228,8 @@ class StatsHttpd:
"""Closes sockets for HTTP"""
while len(self.httpd)>0:
ht = self.httpd.pop()
- if self.verbose:
- self.write_log(
- "[b10-stats-httpd] Closing address %s, port %d\n" % \
- (ht.server_address[0], ht.server_address[1]))
+ logger.info(STATHTTPD_CLOSING, ht.server_address[0],
+ ht.server_address[1])
ht.server_close()
def start(self):
@@ -273,8 +266,7 @@ class StatsHttpd:
def stop(self):
"""Stops the running StatsHttpd objects. Closes CC session and
HTTP handling sockets"""
- if self.verbose:
- self.write_log("[b10-stats-httpd] Shutting down\n")
+ logger.info(STATHTTPD_SHUTDOWN)
self.close_httpd()
self.close_mccs()
@@ -291,13 +283,11 @@ class StatsHttpd:
def config_handler(self, new_config):
"""Config handler for the ModuleCCSession object. It resets
addresses and ports to listen HTTP requests on."""
- if self.verbose:
- self.write_log("[b10-stats-httpd] Loading config : %s\n" % str(new_config))
+ logger.debug(DBG_STATHTTPD_MESSAGING, STATHTTPD_HANDLE_CONFIG,
+ new_config)
for key in new_config.keys():
- if key not in DEFAULT_CONFIG:
- if self.verbose:
- self.write_log(
- "[b10-stats-httpd] Unknown known config: %s" % key)
+ if key not in DEFAULT_CONFIG and key != "version":
+ logger.error(STATHTTPD_UNKNOWN_CONFIG_ITEM, key)
return isc.config.ccsession.create_answer(
1, "Unknown known config: %s" % key)
# backup old config
@@ -307,9 +297,7 @@ class StatsHttpd:
try:
self.open_httpd()
except HttpServerError as err:
- if self.verbose:
- self.write_log("[b10-stats-httpd] %s\n" % err)
- self.write_log("[b10-stats-httpd] Restoring old config\n")
+ logger.error(STATHTTPD_SERVER_ERROR, err)
# restore old config
self.load_config(old_config)
self.open_httpd()
@@ -322,19 +310,19 @@ class StatsHttpd:
"""Command handler for the ModuleCCSesson object. It handles
"status" and "shutdown" commands."""
if command == "status":
- if self.verbose:
- self.write_log("[b10-stats-httpd] Received 'status' command\n")
+ logger.debug(DBG_STATHTTPD_MESSAGING,
+ STATHTTPD_RECEIVED_STATUS_COMMAND)
return isc.config.ccsession.create_answer(
0, "Stats Httpd is up. (PID " + str(os.getpid()) + ")")
elif command == "shutdown":
- if self.verbose:
- self.write_log("[b10-stats-httpd] Received 'shutdown' command\n")
+ logger.debug(DBG_STATHTTPD_MESSAGING,
+ STATHTTPD_RECEIVED_SHUTDOWN_COMMAND)
self.running = False
return isc.config.ccsession.create_answer(
0, "Stats Httpd is shutting down.")
else:
- if self.verbose:
- self.write_log("[b10-stats-httpd] Received unknown command\n")
+ logger.debug(DBG_STATHTTPD_MESSAGING,
+ STATHTTPD_RECEIVED_UNKNOWN_COMMAND, command)
return isc.config.ccsession.create_answer(
1, "Unknown command: " + str(command))
@@ -491,14 +479,18 @@ if __name__ == "__main__":
"-v", "--verbose", dest="verbose", action="store_true",
help="display more about what is going on")
(options, args) = parser.parse_args()
- stats_httpd = StatsHttpd(verbose=options.verbose)
+ if options.verbose:
+ isc.log.init("b10-stats-httpd", "DEBUG", 99)
+ stats_httpd = StatsHttpd()
stats_httpd.start()
- except OptionValueError:
- sys.exit("[b10-stats-httpd] Error parsing options")
+ except OptionValueError as ove:
+ logger.fatal(STATHTTPD_BAD_OPTION_VALUE, ove)
+ sys.exit(1)
except isc.cc.session.SessionError as se:
- sys.exit("[b10-stats-httpd] Error creating module, "
- + "is the command channel daemon running?")
+ logger.fatal(STATHTTPD_CC_SESSION_ERROR, se)
+ sys.exit(1)
except HttpServerError as hse:
- sys.exit("[b10-stats-httpd] %s" % hse)
+ logger.fatal(STATHTTPD_START_SERVER_ERROR, hse)
+ sys.exit(1)
except KeyboardInterrupt as kie:
- sys.exit("[b10-stats-httpd] Interrupted, exiting")
+ logger.info(STATHTTPD_STOPPED_BY_KEYBOARD)
diff --git a/src/bin/stats/stats_httpd_messages.mes b/src/bin/stats/stats_httpd_messages.mes
new file mode 100644
index 0000000..d0f7e2c
--- /dev/null
+++ b/src/bin/stats/stats_httpd_messages.mes
@@ -0,0 +1,92 @@
+# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC 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.
+
+# No namespace declaration - these constants go in the global namespace
+# of the stats_httpd_messages python module.
+
+% STATHTTPD_BAD_OPTION_VALUE bad command line argument: %1
+The stats-httpd module was called with a bad command-line argument
+and will not start.
+
+% STATHTTPD_CC_SESSION_ERROR error connecting to message bus: %1
+The stats-httpd module was unable to connect to the BIND 10 command
+and control bus. A likely problem is that the message bus daemon
+(b10-msgq) is not running. The stats-httpd module will now shut down.
+
+% STATHTTPD_CLOSING_CC_SESSION stopping cc session
+Debug message indicating that the stats-httpd module is disconnecting
+from the command and control bus.
+
+% STATHTTPD_CLOSING closing %1#%2
+The stats-httpd daemon will stop listening for requests on the given
+address and port number.
+
+% STATHTTPD_HANDLE_CONFIG reading configuration: %1
+The stats-httpd daemon has received new configuration data and will now
+process it. The (changed) data is printed.
+
+% STATHTTPD_RECEIVED_SHUTDOWN_COMMAND shutdown command received
+A shutdown command was sent to the stats-httpd module, and it will
+now shut down.
+
+% STATHTTPD_RECEIVED_STATUS_COMMAND received command to return status
+A status command was sent to the stats-httpd module, and it will
+respond with 'Stats Httpd is up.' and its PID.
+
+% STATHTTPD_RECEIVED_UNKNOWN_COMMAND received unknown command: %1
+An unknown command has been sent to the stats-httpd module. The
+stats-httpd module will respond with an error, and the command will
+be ignored.
+
+% STATHTTPD_SERVER_ERROR http server error: %1
+An internal error occurred while handling an http request. A HTTP 500
+response will be sent back, and the specific error is printed. This
+is an error condition that likely points to a module that is not
+responding correctly to statistic requests.
+
+% STATHTTPD_SERVER_INIT_ERROR http server initialization error: %1
+There was a problem initializing the http server in the stats-httpd
+module upon receiving its configuration data. The most likely cause
+is a port binding problem or a bad configuration value. The specific
+error is printed in the message. The new configuration is ignored,
+and an error is sent back.
+
+% STATHTTPD_SHUTDOWN shutting down
+The stats-httpd daemon is shutting down.
+
+% STATHTTPD_START_SERVER_INIT_ERROR http server initialization error: %1
+There was a problem initializing the http server in the stats-httpd
+module upon startup. The most likely cause is that it was not able
+to bind to the listening port. The specific error is printed, and the
+module will shut down.
+
+% STATHTTPD_STARTED listening on %1#%2
+The stats-httpd daemon will now start listening for requests on the
+given address and port number.
+
+% STATHTTPD_STARTING_CC_SESSION starting cc session
+Debug message indicating that the stats-httpd module is connecting to
+the command and control bus.
+
+% STATHTTPD_STOPPED_BY_KEYBOARD keyboard interrupt, shutting down
+There was a keyboard interrupt signal to stop the stats-httpd
+daemon. The daemon will now shut down.
+
+% STATHTTPD_UNKNOWN_CONFIG_ITEM unknown configuration item: %1
+The stats-httpd daemon received a configuration update from the
+configuration manager. However, one of the items in the
+configuration is unknown. The new configuration is ignored, and an
+error is sent back. As possible cause is that there was an upgrade
+problem, and the stats-httpd version is out of sync with the rest of
+the system.
diff --git a/src/bin/stats/stats_messages.mes b/src/bin/stats/stats_messages.mes
new file mode 100644
index 0000000..9ad07cf
--- /dev/null
+++ b/src/bin/stats/stats_messages.mes
@@ -0,0 +1,75 @@
+# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC 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.
+
+# No namespace declaration - these constants go in the global namespace
+# of the stats_messages python module.
+
+% STATS_BAD_OPTION_VALUE bad command line argument: %1
+The stats module was called with a bad command-line argument and will
+not start.
+
+% STATS_CC_SESSION_ERROR error connecting to message bus: %1
+The stats module was unable to connect to the BIND 10 command and
+control bus. A likely problem is that the message bus daemon
+(b10-msgq) is not running. The stats module will now shut down.
+
+% STATS_RECEIVED_NEW_CONFIG received new configuration: %1
+This debug message is printed when the stats module has received a
+configuration update from the configuration manager.
+
+% STATS_RECEIVED_REMOVE_COMMAND received command to remove %1
+A remove command for the given name was sent to the stats module, and
+the given statistics value will now be removed. It will not appear in
+statistics reports until it appears in a statistics update from a
+module again.
+
+% STATS_RECEIVED_RESET_COMMAND received command to reset all statistics
+The stats module received a command to clear all collected statistics.
+The data is cleared until it receives an update from the modules again.
+
+% STATS_RECEIVED_SHOW_ALL_COMMAND received command to show all statistics
+The stats module received a command to show all statistics that it has
+collected.
+
+% STATS_RECEIVED_SHOW_NAME_COMMAND received command to show statistics for %1
+The stats module received a command to show the statistics that it has
+collected for the given item.
+
+% STATS_RECEIVED_SHUTDOWN_COMMAND shutdown command received
+A shutdown command was sent to the stats module and it will now shut down.
+
+% STATS_RECEIVED_STATUS_COMMAND received command to return status
+A status command was sent to the stats module. It will return a
+response indicating that it is running normally.
+
+% STATS_RECEIVED_UNKNOWN_COMMAND received unknown command: %1
+An unknown command has been sent to the stats module. The stats module
+will respond with an error and the command will be ignored.
+
+% STATS_SEND_REQUEST_BOSS requesting boss to send statistics
+This debug message is printed when a request is sent to the boss module
+to send its data to the stats module.
+
+% STATS_STOPPED_BY_KEYBOARD keyboard interrupt, shutting down
+There was a keyboard interrupt signal to stop the stats module. The
+daemon will now shut down.
+
+% STATS_UNKNOWN_COMMAND_IN_SPEC unknown command in specification file: %1
+The specification file for the stats module contains a command that
+is unknown in the implementation. The most likely cause is an
+installation problem, where the specification file stats.spec is
+from a different version of BIND 10 than the stats module itself.
+Please check your installation.
+
+
diff --git a/src/bin/stats/tests/Makefile.am b/src/bin/stats/tests/Makefile.am
index 67188a2..19f6117 100644
--- a/src/bin/stats/tests/Makefile.am
+++ b/src/bin/stats/tests/Makefile.am
@@ -3,6 +3,13 @@ PYTESTS = b10-stats_test.py b10-stats-httpd_test.py
EXTRA_DIST = $(PYTESTS) test_utils.py
CLEANFILES = test_utils.pyc
+# 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/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:$$$(ENV_LIBRARY_PATH)
+endif
+
# test using command-line arguments, so use check-local target instead of TESTS
check-local:
if ENABLE_PYTHON_COVERAGE
@@ -12,6 +19,7 @@ if ENABLE_PYTHON_COVERAGE
endif
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
+ $(LIBRARY_PATH_PLACEHOLDER) \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/bin/stats:$(abs_top_builddir)/src/bin/stats/tests:$(abs_top_builddir)/src/bin/msgq:$(abs_top_builddir)/src/lib/python/isc/config \
B10_FROM_SOURCE=$(abs_top_srcdir) \
CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/tests/testdata \
diff --git a/src/bin/stats/tests/b10-stats-httpd_test.py b/src/bin/stats/tests/b10-stats-httpd_test.py
index 17c618b..d25dcc9 100644
--- a/src/bin/stats/tests/b10-stats-httpd_test.py
+++ b/src/bin/stats/tests/b10-stats-httpd_test.py
@@ -28,7 +28,7 @@ import xml.etree.ElementTree
import isc
import stats_httpd
import stats
-from test_utils import BaseModules, ThreadingServerManager, MyStats, MyStatsHttpd, send_command, TIMEOUT_SEC
+from test_utils import BaseModules, ThreadingServerManager, MyStats, MyStatsHttpd, TIMEOUT_SEC
DUMMY_DATA = {
'Boss' : {
@@ -51,8 +51,8 @@ class TestHttpHandler(unittest.TestCase):
"""Tests for HttpHandler class"""
def setUp(self):
- self.base = BaseModules(False)
- self.stats_server = ThreadingServerManager(MyStats, False)
+ self.base = BaseModules()
+ self.stats_server = ThreadingServerManager(MyStats)
self.stats = self.stats_server.server
self.stats_server.run()
@@ -62,13 +62,13 @@ class TestHttpHandler(unittest.TestCase):
def test_do_GET(self):
(address, port) = ('127.0.0.1', 65450)
- statshttpd_server = ThreadingServerManager(MyStatsHttpd, True)
+ statshttpd_server = ThreadingServerManager(MyStatsHttpd)
self.stats_httpd = statshttpd_server.server
self.stats_httpd.load_config({'listen_on' : [{ 'address': address, 'port' : port }]})
self.assertTrue(type(self.stats_httpd.httpd) is list)
self.assertEqual(len(self.stats_httpd.httpd), 0)
statshttpd_server.run()
- time.sleep(TIMEOUT_SEC*5)
+ time.sleep(TIMEOUT_SEC*8)
client = http.client.HTTPConnection(address, port)
client._http_vsn_str = 'HTTP/1.0\n'
client.connect()
@@ -159,7 +159,7 @@ class TestHttpHandler(unittest.TestCase):
def test_do_GET_failed1(self):
# failure case(connection with Stats is down)
(address, port) = ('127.0.0.1', 65451)
- statshttpd_server = ThreadingServerManager(MyStatsHttpd, True)
+ statshttpd_server = ThreadingServerManager(MyStatsHttpd)
statshttpd = statshttpd_server.server
statshttpd.load_config({'listen_on' : [{ 'address': address, 'port' : port }]})
statshttpd_server.run()
@@ -195,7 +195,7 @@ class TestHttpHandler(unittest.TestCase):
def test_do_GET_failed2(self):
# failure case(connection with Stats is down)
(address, port) = ('127.0.0.1', 65452)
- statshttpd_server = ThreadingServerManager(MyStatsHttpd, True)
+ statshttpd_server = ThreadingServerManager(MyStatsHttpd)
self.stats_httpd = statshttpd_server.server
self.stats_httpd.load_config({'listen_on' : [{ 'address': address, 'port' : port }]})
statshttpd_server.run()
@@ -230,7 +230,7 @@ class TestHttpHandler(unittest.TestCase):
def test_do_HEAD(self):
(address, port) = ('127.0.0.1', 65453)
- statshttpd_server = ThreadingServerManager(MyStatsHttpd, True)
+ statshttpd_server = ThreadingServerManager(MyStatsHttpd)
self.stats_httpd = statshttpd_server.server
self.stats_httpd.load_config({'listen_on' : [{ 'address': address, 'port' : port }]})
statshttpd_server.run()
@@ -249,24 +249,6 @@ class TestHttpHandler(unittest.TestCase):
client.close()
statshttpd_server.shutdown()
- def test_log_message(self):
- class MyHttpHandler(stats_httpd.HttpHandler):
- def __init__(self):
- class _Dummy_class_(): pass
- self.address_string = lambda : 'dummyhost'
- self.log_date_time_string = lambda : \
- 'DD/MM/YYYY HH:MI:SS'
- self.server = _Dummy_class_()
- self.server.verbose = True
- self.server.log_writer = self.log_writer
- def log_writer(self, line):
- self.logged_line = line
- self.handler = MyHttpHandler()
- self.handler.log_message("%s %d", 'ABCDEFG', 12345)
- self.assertEqual(self.handler.logged_line,
- "[b10-stats-httpd] dummyhost - - "
- + "[DD/MM/YYYY HH:MI:SS] ABCDEFG 12345\n")
-
class TestHttpServerError(unittest.TestCase):
"""Tests for HttpServerError exception"""
def test_raises(self):
@@ -278,13 +260,13 @@ class TestHttpServerError(unittest.TestCase):
class TestHttpServer(unittest.TestCase):
"""Tests for HttpServer class"""
def setUp(self):
- self.base = BaseModules(False)
+ self.base = BaseModules()
def tearDown(self):
self.base.shutdown()
def test_httpserver(self):
- statshttpd = stats_httpd.StatsHttpd(True)
+ statshttpd = stats_httpd.StatsHttpd()
self.assertEqual(type(statshttpd.httpd), list)
self.assertEqual(len(statshttpd.httpd), 0)
@@ -301,11 +283,11 @@ class TestStatsHttpd(unittest.TestCase):
"""Tests for StatsHttpd class"""
def setUp(self):
- self.base = BaseModules(False)
- self.stats_server = ThreadingServerManager(MyStats, False)
+ self.base = BaseModules()
+ self.stats_server = ThreadingServerManager(MyStats)
self.stats = self.stats_server.server
self.stats_server.run()
- self.stats_httpd = stats_httpd.StatsHttpd(True)
+ self.stats_httpd = stats_httpd.StatsHttpd()
# checking IPv6 enabled on this platform
self.ipv6_enabled = True
@@ -322,7 +304,6 @@ class TestStatsHttpd(unittest.TestCase):
self.base.shutdown()
def test_init(self):
- self.assertTrue(self.stats_httpd.verbose)
self.assertEqual(self.stats_httpd.running, False)
self.assertEqual(self.stats_httpd.poll_intval, 0.5)
self.assertEqual(self.stats_httpd.httpd, [])
@@ -336,7 +317,7 @@ class TestStatsHttpd(unittest.TestCase):
self.assertTrue(('127.0.0.1', 8000) in set(self.stats_httpd.http_addrs))
def test_openclose_mccs(self):
- statshttpd = stats_httpd.StatsHttpd(True)
+ statshttpd = stats_httpd.StatsHttpd()
statshttpd.close_mccs()
self.assertEqual(statshttpd.mccs, None)
statshttpd.open_mccs()
@@ -429,7 +410,7 @@ class TestStatsHttpd(unittest.TestCase):
self.assertRaises(stats_httpd.HttpServerError, self.stats_httpd.open_httpd)
# Address already in use
- self.statshttpd_server = ThreadingServerManager(MyStatsHttpd, False)
+ self.statshttpd_server = ThreadingServerManager(MyStatsHttpd)
self.statshttpd_server.server.load_config({'listen_on' : [{ 'address': '127.0.0.1', 'port' : 65454 }]})
self.statshttpd_server.run()
time.sleep(TIMEOUT_SEC)
@@ -439,7 +420,7 @@ class TestStatsHttpd(unittest.TestCase):
def test_running(self):
self.assertFalse(self.stats_httpd.running)
- self.statshttpd_server = ThreadingServerManager(MyStatsHttpd, False)
+ self.statshttpd_server = ThreadingServerManager(MyStatsHttpd)
self.stats_httpd = self.statshttpd_server.server
self.stats_httpd.load_config({'listen_on' : [{ 'address': '127.0.0.1', 'port' : 65455 }]})
self.statshttpd_server.run()
@@ -449,7 +430,7 @@ class TestStatsHttpd(unittest.TestCase):
self.assertFalse(self.stats_httpd.running)
# failure case
- self.stats_httpd = stats_httpd.StatsHttpd(True)
+ self.stats_httpd = stats_httpd.StatsHttpd()
self.stats_httpd.cc_session.close()
self.assertRaises(
isc.cc.session.SessionError, self.stats_httpd.start)
@@ -461,12 +442,12 @@ class TestStatsHttpd(unittest.TestCase):
raise select.error(errno.EINTR)
(address, port) = ('127.0.0.1', 65456)
stats_httpd.select.select = raise_select_except
- statshttpd = stats_httpd.StatsHttpd(True)
+ statshttpd = stats_httpd.StatsHttpd()
statshttpd.load_config({'listen_on' : [{ 'address': address, 'port' : port }]})
self.assertRaises(select.error, statshttpd.start)
statshttpd.stop()
stats_httpd.select.select = raise_select_except_with_errno
- statshttpd_server = ThreadingServerManager(MyStatsHttpd, False)
+ statshttpd_server = ThreadingServerManager(MyStatsHttpd)
statshttpd = statshttpd_server.server
statshttpd.load_config({'listen_on' : [{ 'address': address, 'port' : port }]})
statshttpd_server.run()
diff --git a/src/bin/stats/tests/b10-stats_test.py b/src/bin/stats/tests/b10-stats_test.py
index abeb487..91fe950 100644
--- a/src/bin/stats/tests/b10-stats_test.py
+++ b/src/bin/stats/tests/b10-stats_test.py
@@ -132,39 +132,18 @@ class TestCallback(unittest.TestCase):
class TestStats(unittest.TestCase):
def setUp(self):
- self.verbose = True
- self.base = BaseModules(False)
- self.stats = stats.Stats(self.verbose)
+ self.base = BaseModules()
+ self.stats = stats.Stats()
self.assertTrue("B10_FROM_SOURCE" in os.environ)
self.assertEqual(stats.SPECFILE_LOCATION, \
os.environ["B10_FROM_SOURCE"] + os.sep + \
"src" + os.sep + "bin" + os.sep + "stats" + \
os.sep + "stats.spec")
- """
- self.test_statistics_data = {
- 'Boss' : {
- 'boot_time' : "1970-01-01T00:00:00Z"
- },
- 'Auth' : {
- 'auth.queries.tcp': 0,
- 'auth.queries.udp': 0
- },
- 'Stats' : {
- 'report_time' : '2010-09-01T18:15:38Z',
- 'stats.timestamp' : 1283364938.229088,
- 'stats.lname' : 'XXX',
- 'stats.boot_time': '2010-09-01T18:15:38Z',
- 'stats.start_time': '2010-09-01T18:15:38Z',
- 'stats.last_update_time': '2010-09-01T18:15:38Z'
- }
- }
- """
def tearDown(self):
self.base.shutdown()
def test_init(self):
- self.assertEqual(self.stats.verbose, True)
self.assertEqual(self.stats.module_name, 'Stats')
self.assertFalse(self.stats.running)
self.assertTrue('command_show' in self.stats.callbacks)
@@ -198,7 +177,7 @@ class TestStats(unittest.TestCase):
stats.SPECFILE_LOCATION = orig_spec_location
def test_start(self):
- statsserver = ThreadingServerManager(MyStats, self.verbose)
+ statsserver = ThreadingServerManager(MyStats)
stats = statsserver.server
self.assertFalse(stats.running)
statsserver.run()
@@ -208,7 +187,7 @@ class TestStats(unittest.TestCase):
self.assertFalse(stats.running)
def test_start_with_err(self):
- statsd = stats.Stats(True)
+ statsd = stats.Stats()
statsd.update_statistics_data = lambda x,**y: [1]
self.assertRaises(stats.StatsError, statsd.start)
@@ -217,7 +196,7 @@ class TestStats(unittest.TestCase):
isc.config.create_answer(0))
def test_command_handler(self):
- statsserver = ThreadingServerManager(MyStats, self.verbose)
+ statsserver = ThreadingServerManager(MyStats)
statsserver.run()
time.sleep(TIMEOUT_SEC*4)
self.base.boss.server._started.wait()
@@ -285,7 +264,6 @@ class TestStats(unittest.TestCase):
self.assertTrue('item_description' in item)
if len(item) == 7:
self.assertTrue('item_format' in item)
-
self.assertEqual(
send_command('__UNKNOWN__', 'Stats'),
(1, "Unknown command: '__UNKNOWN__'"))
@@ -525,7 +503,6 @@ class TestStats(unittest.TestCase):
self.assertRaises(stats.StatsError,
self.stats.command_set, owner='Stats', data={ 'dummy' : '_xxxx_yyyy_zzz_' })
-
def test_osenv(self):
"""
test for not having environ "B10_FROM_SOURCE"
diff --git a/src/bin/stats/tests/isc/Makefile.am b/src/bin/stats/tests/isc/Makefile.am
new file mode 100644
index 0000000..d31395d
--- /dev/null
+++ b/src/bin/stats/tests/isc/Makefile.am
@@ -0,0 +1,8 @@
+SUBDIRS = cc config util log
+EXTRA_DIST = __init__.py
+CLEANFILES = __init__.pyc
+
+CLEANDIRS = __pycache__
+
+clean-local:
+ rm -rf $(CLEANDIRS)
diff --git a/src/bin/stats/tests/isc/log/Makefile.am b/src/bin/stats/tests/isc/log/Makefile.am
new file mode 100644
index 0000000..457b9de
--- /dev/null
+++ b/src/bin/stats/tests/isc/log/Makefile.am
@@ -0,0 +1,7 @@
+EXTRA_DIST = __init__.py
+CLEANFILES = __init__.pyc
+
+CLEANDIRS = __pycache__
+
+clean-local:
+ rm -rf $(CLEANDIRS)
diff --git a/src/bin/stats/tests/isc/log/__init__.py b/src/bin/stats/tests/isc/log/__init__.py
new file mode 100644
index 0000000..641cf79
--- /dev/null
+++ b/src/bin/stats/tests/isc/log/__init__.py
@@ -0,0 +1,33 @@
+# 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.
+
+# This file is not installed. The log.so is installed into the right place.
+# It is only to find it in the .libs directory when we run as a test or
+# from the build directory.
+# But as nobody gives us the builddir explicitly (and we can't use generation
+# from .in file, as it would put us into the builddir and we wouldn't be found)
+# we guess from current directory. Any idea for something better? This should
+# be enough for the tests, but would it work for B10_FROM_SOURCE as well?
+# Should we look there? Or define something in bind10_config?
+
+import os
+import sys
+
+for base in sys.path[:]:
+ loglibdir = os.path.join(base, 'isc/log/.libs')
+ if os.path.exists(loglibdir):
+ sys.path.insert(0, loglibdir)
+
+from log import *
diff --git a/src/bin/stats/tests/test_utils.py b/src/bin/stats/tests/test_utils.py
index bd23182..cfffc15 100644
--- a/src/bin/stats/tests/test_utils.py
+++ b/src/bin/stats/tests/test_utils.py
@@ -42,11 +42,10 @@ def send_shutdown(module_name):
return send_command("shutdown", module_name)
class ThreadingServerManager:
- def __init__(self, server_class, verbose):
+ def __init__(self, server_class):
self.server_class = server_class
self.server_class_name = server_class.__name__
- self.verbose = verbose
- self.server = self.server_class(self.verbose)
+ self.server = self.server_class()
self.server._thread = threading.Thread(
name=self.server_class_name, target=self.server.run)
self.server._thread.daemon = True
@@ -60,10 +59,9 @@ class ThreadingServerManager:
self.server._thread.join(TIMEOUT_SEC)
class MockMsgq:
- def __init__(self, verbose):
- self.verbose = verbose
+ def __init__(self):
self._started = threading.Event()
- self.msgq = msgq.MsgQ(None, verbose)
+ self.msgq = msgq.MsgQ(None)
result = self.msgq.setup()
if result:
sys.exit("Error on Msgq startup: %s" % result)
@@ -81,7 +79,7 @@ class MockMsgq:
self.msgq.shutdown()
class MockCfgmgr:
- def __init__(self, verbose):
+ def __init__(self):
self._started = threading.Event()
self.cfgmgr = isc.config.cfgmgr.ConfigManager(
os.environ['CONFIG_TESTDATA_PATH'], "b10-config.db")
@@ -127,8 +125,7 @@ class MockBoss:
"""
_BASETIME = (2011, 6, 22, 8, 14, 8, 2, 173, 0)
- def __init__(self, verbose):
- self.verbose = verbose
+ def __init__(self):
self._started = threading.Event()
self.running = False
self.spec_file = io.StringIO(self.spec_str)
@@ -200,8 +197,7 @@ class MockAuth:
}
}
"""
- def __init__(self, verbose):
- self.verbose = verbose
+ def __init__(self):
self._started = threading.Event()
self.running = False
self.spec_file = io.StringIO(self.spec_str)
@@ -239,9 +235,9 @@ class MockAuth:
return isc.config.create_answer(1, "Unknown Command")
class MyStats(stats.Stats):
- def __init__(self, verbose):
+ def __init__(self):
self._started = threading.Event()
- stats.Stats.__init__(self, verbose)
+ stats.Stats.__init__(self)
def run(self):
self._started.set()
@@ -251,9 +247,9 @@ class MyStats(stats.Stats):
send_shutdown("Stats")
class MyStatsHttpd(stats_httpd.StatsHttpd):
- def __init__(self, verbose):
+ def __init__(self):
self._started = threading.Event()
- stats_httpd.StatsHttpd.__init__(self, verbose)
+ stats_httpd.StatsHttpd.__init__(self)
def run(self):
self._started.set()
@@ -263,23 +259,22 @@ class MyStatsHttpd(stats_httpd.StatsHttpd):
send_shutdown("StatsHttpd")
class BaseModules:
- def __init__(self, verbose):
- self.verbose = verbose
+ def __init__(self):
self.class_name = BaseModules.__name__
# Change value of BIND10_MSGQ_SOCKET_FILE in environment variables
os.environ['BIND10_MSGQ_SOCKET_FILE'] = tempfile.mktemp(prefix='unix_socket.')
# MockMsgq
- self.msgq = ThreadingServerManager(MockMsgq, self.verbose)
+ self.msgq = ThreadingServerManager(MockMsgq)
self.msgq.run()
# MockCfgmgr
- self.cfgmgr = ThreadingServerManager(MockCfgmgr, self.verbose)
+ self.cfgmgr = ThreadingServerManager(MockCfgmgr)
self.cfgmgr.run()
# MockBoss
- self.boss = ThreadingServerManager(MockBoss, self.verbose)
+ self.boss = ThreadingServerManager(MockBoss)
self.boss.run()
# MockAuth
- self.auth = ThreadingServerManager(MockAuth, self.verbose)
+ self.auth = ThreadingServerManager(MockAuth)
self.auth.run()
def shutdown(self):
diff --git a/src/lib/log/compiler/message.cc b/src/lib/log/compiler/message.cc
index 68335dc..f74020a 100644
--- a/src/lib/log/compiler/message.cc
+++ b/src/lib/log/compiler/message.cc
@@ -43,6 +43,7 @@ using namespace isc::util;
static const char* VERSION = "1.0-0";
+/// \file log/compiler/message.cc
/// \brief Message Compiler
///
/// \b Overview<BR>
@@ -55,13 +56,16 @@ static const char* VERSION = "1.0-0";
/// \b Invocation<BR>
/// The program is invoked with the command:
///
-/// <tt>message [-v | -h | \<message-file\>]</tt>
+/// <tt>message [-v | -h | -p | -d <dir> | <message-file>]</tt>
///
-/// It reads the message file and writes out two files of the same name in the
-/// default directory but with extensions of .h and .cc.
+/// It reads the message file and writes out two files of the same
+/// name in the current working directory (unless -d is used) but
+/// with extensions of .h and .cc, or .py if -p is used.
///
-/// \-v causes it to print the version number and exit. \-h prints a help
-/// message (and exits).
+/// -v causes it to print the version number and exit. -h prints a help
+/// message (and exits). -p sets the output to python. -d <dir> will make
+/// it write the output file(s) to dir instead of current working
+/// directory
/// \brief Print Version
@@ -80,11 +84,12 @@ version() {
void
usage() {
cout <<
- "Usage: message [-h] [-v] [-p] <message-file>\n" <<
+ "Usage: message [-h] [-v] [-p] [-d dir] <message-file>\n" <<
"\n" <<
"-h Print this message and exit\n" <<
"-v Print the program version and exit\n" <<
"-p Output python source instead of C++ ones\n" <<
+ "-d <dir> Place output files in given directory\n" <<
"\n" <<
"<message-file> is the name of the input message file.\n";
}
@@ -106,7 +111,7 @@ currentTime() {
// Convert to string and strip out the trailing newline
string current_time = buffer;
- return isc::util::str::trim(current_time);
+ return (isc::util::str::trim(current_time));
}
@@ -127,7 +132,7 @@ sentinel(Filename& file) {
string ext = file.extension();
string sentinel_text = "__" + name + "_" + ext.substr(1);
isc::util::str::uppercase(sentinel_text);
- return sentinel_text;
+ return (sentinel_text);
}
@@ -154,7 +159,7 @@ quoteString(const string& instring) {
outstring += instring[i];
}
- return outstring;
+ return (outstring);
}
@@ -177,7 +182,7 @@ sortedIdentifiers(MessageDictionary& dictionary) {
}
sort(ident.begin(), ident.end());
- return ident;
+ return (ident);
}
@@ -207,7 +212,7 @@ splitNamespace(string ns) {
// ... and return the vector of namespace components split on the single
// colon.
- return isc::util::str::tokens(ns, ":");
+ return (isc::util::str::tokens(ns, ":"));
}
@@ -249,14 +254,22 @@ writeClosingNamespace(ostream& output, const vector<string>& ns) {
/// \param file Name of the message file. The source code is written to a file
/// file of the same name but with a .py suffix.
/// \param dictionary The dictionary holding the message definitions.
+/// \param output_directory if not null NULL, output files are written
+/// to the given directory. If NULL, they are written to the current
+/// working directory.
///
/// \note We don't use the namespace as in C++. We don't need it, because
/// python file/module works as implicit namespace as well.
void
-writePythonFile(const string& file, MessageDictionary& dictionary) {
+writePythonFile(const string& file, MessageDictionary& dictionary,
+ const char* output_directory)
+{
Filename message_file(file);
Filename python_file(Filename(message_file.name()).useAsDefault(".py"));
+ if (output_directory != NULL) {
+ python_file.setDirectory(output_directory);
+ }
// Open the file for writing
ofstream pyfile(python_file.fullName().c_str());
@@ -291,13 +304,19 @@ writePythonFile(const string& file, MessageDictionary& dictionary) {
/// \param ns Namespace in which the definitions are to be placed. An empty
/// string indicates no namespace.
/// \param dictionary Dictionary holding the message definitions.
+/// \param output_directory if not null NULL, output files are written
+/// to the given directory. If NULL, they are written to the current
+/// working directory.
void
writeHeaderFile(const string& file, const vector<string>& ns_components,
- MessageDictionary& dictionary)
+ MessageDictionary& dictionary, const char* output_directory)
{
Filename message_file(file);
Filename header_file(Filename(message_file.name()).useAsDefault(".h"));
+ if (output_directory != NULL) {
+ header_file.setDirectory(output_directory);
+ }
// Text to use as the sentinels.
string sentinel_text = sentinel(header_file);
@@ -382,13 +401,25 @@ replaceNonAlphaNum(char c) {
/// optimisation is done at link-time, not compiler-time. In this it _may_
/// decide to remove the initializer object because of a lack of references
/// to it. But until BIND-10 is ported to Windows, we won't know.
-
+///
+/// \param file Name of the message file. The header file is written to a
+/// file of the same name but with a .h suffix.
+/// \param ns Namespace in which the definitions are to be placed. An empty
+/// string indicates no namespace.
+/// \param dictionary Dictionary holding the message definitions.
+/// \param output_directory if not null NULL, output files are written
+/// to the given directory. If NULL, they are written to the current
+/// working directory.
void
writeProgramFile(const string& file, const vector<string>& ns_components,
- MessageDictionary& dictionary)
+ MessageDictionary& dictionary,
+ const char* output_directory)
{
Filename message_file(file);
Filename program_file(Filename(message_file.name()).useAsDefault(".cc"));
+ if (output_directory) {
+ program_file.setDirectory(output_directory);
+ }
// Open the output file for writing
ofstream ccfile(program_file.fullName().c_str());
@@ -496,30 +527,35 @@ warnDuplicates(MessageReader& reader) {
int
main(int argc, char* argv[]) {
- const char* soptions = "hvp"; // Short options
+ const char* soptions = "hvpd:"; // Short options
optind = 1; // Ensure we start a new scan
int opt; // Value of the option
bool doPython = false;
+ const char *output_directory = NULL;
while ((opt = getopt(argc, argv, soptions)) != -1) {
switch (opt) {
+ case 'd':
+ output_directory = optarg;
+ break;
+
case 'p':
doPython = true;
break;
case 'h':
usage();
- return 0;
+ return (0);
case 'v':
version();
- return 0;
+ return (0);
default:
// A message will have already been output about the error.
- return 1;
+ return (1);
}
}
@@ -527,11 +563,11 @@ main(int argc, char* argv[]) {
if (optind < (argc - 1)) {
cout << "Error: excess arguments in command line\n";
usage();
- return 1;
+ return (1);
} else if (optind >= argc) {
cout << "Error: missing message file\n";
usage();
- return 1;
+ return (1);
}
string message_file = argv[optind];
@@ -552,7 +588,7 @@ main(int argc, char* argv[]) {
}
// Write the whole python file
- writePythonFile(message_file, dictionary);
+ writePythonFile(message_file, dictionary, output_directory);
} else {
// Get the namespace into which the message definitions will be put and
// split it into components.
@@ -560,16 +596,18 @@ main(int argc, char* argv[]) {
splitNamespace(reader.getNamespace());
// Write the header file.
- writeHeaderFile(message_file, ns_components, dictionary);
+ writeHeaderFile(message_file, ns_components, dictionary,
+ output_directory);
// Write the file that defines the message symbols and text
- writeProgramFile(message_file, ns_components, dictionary);
+ writeProgramFile(message_file, ns_components, dictionary,
+ output_directory);
}
// Finally, warn of any duplicates encountered.
warnDuplicates(reader);
}
- catch (MessageException& e) {
+ catch (const MessageException& e) {
// Create an error message from the ID and the text
MessageDictionary& global = MessageDictionary::globalDictionary();
string text = e.id();
@@ -583,9 +621,9 @@ main(int argc, char* argv[]) {
cerr << text << "\n";
- return 1;
+ return (1);
}
- return 0;
+ return (0);
}
diff --git a/src/lib/python/isc/config/Makefile.am b/src/lib/python/isc/config/Makefile.am
index 1efb6fc..312ad33 100644
--- a/src/lib/python/isc/config/Makefile.am
+++ b/src/lib/python/isc/config/Makefile.am
@@ -1,19 +1,27 @@
SUBDIRS = . tests
python_PYTHON = __init__.py ccsession.py cfgmgr.py config_data.py module_spec.py
-pyexec_DATA = cfgmgr_messages.py
+pyexec_DATA = cfgmgr_messages.py $(top_builddir)/src/lib/python/config_messages.py
pythondir = $(pyexecdir)/isc/config
# Define rule to build logging source files from message file
cfgmgr_messages.py: cfgmgr_messages.mes
- $(top_builddir)/src/lib/log/compiler/message -p $(top_srcdir)/src/lib/python/isc/config/cfgmgr_messages.mes
+ $(top_builddir)/src/lib/log/compiler/message \
+ -p $(top_srcdir)/src/lib/python/isc/config/cfgmgr_messages.mes
-CLEANFILES = cfgmgr_messages.py cfgmgr_messages.pyc
+$(top_builddir)/src/lib/python/config_messages.py: config_messages.mes
+ $(top_builddir)/src/lib/log/compiler/message \
+ -p -d $(top_builddir)/src/lib/python \
+ $(top_srcdir)/src/lib/python/isc/config/config_messages.mes
+
+CLEANFILES = cfgmgr_messages.py cfgmgr_messages.pyc
+CLEANFILES += $(top_builddir)/src/lib/python/config_messages.py
+CLEANFILES += $(top_builddir)/src/lib/python/config_messages.pyc
CLEANDIRS = __pycache__
-EXTRA_DIST = cfgmgr_messages.mes
+EXTRA_DIST = cfgmgr_messages.mes config_messages.mes
clean-local:
rm -rf $(CLEANDIRS)
diff --git a/src/lib/python/isc/config/ccsession.py b/src/lib/python/isc/config/ccsession.py
index 8864adf..3914ef9 100644
--- a/src/lib/python/isc/config/ccsession.py
+++ b/src/lib/python/isc/config/ccsession.py
@@ -43,6 +43,9 @@ from isc.util.file import path_search
import bind10_config
from isc.log import log_config_update
import json
+from config_messages import *
+
+logger = isc.log.Logger("config")
class ModuleCCSessionError(Exception): pass
@@ -128,10 +131,7 @@ def default_logconfig_handler(new_config, config_data):
isc.log.log_config_update(json.dumps(new_config),
json.dumps(config_data.get_module_spec().get_full_spec()))
else:
- # no logging here yet, TODO: log these errors
- print("Error in logging configuration, ignoring config update: ")
- for err in errors:
- print(err)
+ logger.error(CONFIG_LOG_CONFIG_ERRORS, errors)
class ModuleCCSession(ConfigData):
"""This class maintains a connection to the command channel, as
@@ -386,8 +386,7 @@ class ModuleCCSession(ConfigData):
"Wrong data in configuration: " +
" ".join(errors))
else:
- # log error
- print("[" + self._module_name + "] Error requesting configuration: " + value)
+ logger.error(CONFIG_GET_FAILED, value)
else:
raise ModuleCCSessionError("No answer from configuration manager")
except isc.cc.SessionTimeout:
@@ -499,7 +498,6 @@ class UIModuleCCSession(MultiConfigData):
self.request_current_config()
self.clear_local_changes()
elif "error" in answer:
- print("Error: " + answer["error"])
- print("Configuration not committed")
+ raise ModuleCCSessionError("Error: " + str(answer["error"]) + "\n" + "Configuration not committed")
else:
raise ModuleCCSessionError("Unknown format of answer in commit(): " + str(answer))
diff --git a/src/lib/python/isc/config/config_messages.mes b/src/lib/python/isc/config/config_messages.mes
new file mode 100644
index 0000000..c52efb4
--- /dev/null
+++ b/src/lib/python/isc/config/config_messages.mes
@@ -0,0 +1,33 @@
+# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC 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.
+
+# No namespace declaration - these constants go in the global namespace
+# of the config_messages python module.
+
+# since these messages are for the python config library, care must
+# be taken that names do not conflict with the messages from the c++
+# config library. A checker script should verify that, but we do not
+# have that at this moment. So when adding a message, make sure that
+# the name is not already used in src/lib/config/config_messages.mes
+
+% CONFIG_LOG_CONFIG_ERRORS error(s) in logging configuration: %1
+There was a logging configuration update, but the internal validator
+for logging configuration found that it contained errors. The errors
+are shown, and the update is ignored.
+
+% CONFIG_GET_FAILED error getting configuration from cfgmgr: %1
+The configuration manager returned an error response when the module
+requested its configuration. The full error message answer from the
+configuration manager is appended to the log error.
+
diff --git a/src/lib/python/isc/config/tests/ccsession_test.py b/src/lib/python/isc/config/tests/ccsession_test.py
index 830cbd7..5d09c96 100644
--- a/src/lib/python/isc/config/tests/ccsession_test.py
+++ b/src/lib/python/isc/config/tests/ccsession_test.py
@@ -23,6 +23,7 @@ from isc.config.ccsession import *
from isc.config.config_data import BIND10_CONFIG_DATA_VERSION
from unittest_fakesession import FakeModuleCCSession, WouldBlockForever
import bind10_config
+import isc.log
class TestHelperFunctions(unittest.TestCase):
def test_parse_answer(self):
@@ -739,5 +740,6 @@ class TestUIModuleCCSession(unittest.TestCase):
uccs.commit()
if __name__ == '__main__':
+ isc.log.init("bind10")
unittest.main()
diff --git a/src/lib/python/isc/notify/Makefile.am b/src/lib/python/isc/notify/Makefile.am
index 4081a17..a23a1ff 100644
--- a/src/lib/python/isc/notify/Makefile.am
+++ b/src/lib/python/isc/notify/Makefile.am
@@ -1,9 +1,20 @@
SUBDIRS = . tests
python_PYTHON = __init__.py notify_out.py
+pyexec_DATA = $(top_builddir)/src/lib/python/notify_out_messages.py
pythondir = $(pyexecdir)/isc/notify
+$(top_builddir)/src/lib/python/notify_out_messages.py: notify_out_messages.mes
+ $(top_builddir)/src/lib/log/compiler/message \
+ -p -d $(top_builddir)/src/lib/python \
+ $(top_srcdir)/src/lib/python/isc/notify/notify_out_messages.mes
+
+EXTRA_DIST = notify_out_messages.mes
+
+CLEANFILES = $(top_builddir)/src/lib/python/notify_out_messages.pyc
+CLEANFILES += $(top_builddir)/src/lib/python/notify_out_messages.py
+
CLEANDIRS = __pycache__
clean-local:
diff --git a/src/lib/python/isc/notify/notify_out.py b/src/lib/python/isc/notify/notify_out.py
index 4b25463..f1e02ca 100644
--- a/src/lib/python/isc/notify/notify_out.py
+++ b/src/lib/python/isc/notify/notify_out.py
@@ -23,11 +23,15 @@ import errno
from isc.datasrc import sqlite3_ds
from isc.net import addr
import isc
-try:
- from pydnspp import *
-except ImportError as e:
- # C++ loadable module may not be installed;
- sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
+from notify_out_messages import *
+
+logger = isc.log.Logger("notify_out")
+
+# there used to be a printed message if this import failed, but if
+# we can't import we should not start anyway, and logging an error
+# is a bad idea since the logging system is most likely not
+# initialized yet. see trac ticket #1103
+from pydnspp import *
ZONE_NEW_DATA_READY_CMD = 'zone_new_data_ready'
_MAX_NOTIFY_NUM = 30
@@ -46,9 +50,6 @@ _BAD_QR = 4
_BAD_REPLY_PACKET = 5
SOCK_DATA = b's'
-def addr_to_str(addr):
- return '%s#%s' % (addr[0], addr[1])
-
class ZoneNotifyInfo:
'''This class keeps track of notify-out information for one zone.'''
@@ -105,11 +106,10 @@ class NotifyOut:
notify message to its slaves). notify service can be started by
calling dispatcher(), and it can be stoped by calling shutdown()
in another thread. '''
- def __init__(self, datasrc_file, log=None, verbose=True):
+ def __init__(self, datasrc_file, verbose=True):
self._notify_infos = {} # key is (zone_name, zone_class)
self._waiting_zones = []
self._notifying_zones = []
- self._log = log
self._serving = False
self._read_sock, self._write_sock = socket.socketpair()
self._read_sock.setblocking(False)
@@ -362,18 +362,19 @@ class NotifyOut:
tgt = zone_notify_info.get_current_notify_target()
if event_type == _EVENT_READ:
reply = self._get_notify_reply(zone_notify_info.get_socket(), tgt)
- if reply:
- if self._handle_notify_reply(zone_notify_info, reply):
+ if reply is not None:
+ if self._handle_notify_reply(zone_notify_info, reply, tgt):
self._notify_next_target(zone_notify_info)
elif event_type == _EVENT_TIMEOUT and zone_notify_info.notify_try_num > 0:
- self._log_msg('info', 'notify retry to %s' % addr_to_str(tgt))
+ logger.info(NOTIFY_OUT_TIMEOUT, tgt[0], tgt[1])
tgt = zone_notify_info.get_current_notify_target()
if tgt:
zone_notify_info.notify_try_num += 1
if zone_notify_info.notify_try_num > _MAX_NOTIFY_TRY_NUM:
- self._log_msg('info', 'notify to %s: retried exceeded' % addr_to_str(tgt))
+ logger.warn(NOTIFY_OUT_RETRY_EXCEEDED, tgt[0], tgt[1],
+ _MAX_NOTIFY_TRY_NUM)
self._notify_next_target(zone_notify_info)
else:
# set exponential backoff according rfc1996 section 3.6
@@ -412,10 +413,15 @@ class NotifyOut:
try:
sock = zone_notify_info.create_socket(addrinfo[0])
sock.sendto(render.get_data(), 0, addrinfo)
- self._log_msg('info', 'sending notify to %s' % addr_to_str(addrinfo))
+ logger.info(NOTIFY_OUT_SENDING_NOTIFY, addrinfo[0],
+ addrinfo[1])
except (socket.error, addr.InvalidAddress) as err:
- self._log_msg('error', 'send notify to %s failed: %s' %
- (addr_to_str(addrinfo), str(err)))
+ logger.error(NOTIFY_OUT_SOCKET_ERROR, addrinfo[0],
+ addrinfo[1], err)
+ return False
+ except addr.InvalidAddress as iae:
+ logger.error(NOTIFY_OUT_INVALID_ADDRESS, addrinfo[0],
+ addrinfo[1], iae)
return False
return True
@@ -446,34 +452,38 @@ class NotifyOut:
msg.add_rrset(Message.SECTION_ANSWER, rrset_soa)
return msg, qid
- def _handle_notify_reply(self, zone_notify_info, msg_data):
+ def _handle_notify_reply(self, zone_notify_info, msg_data, from_addr):
'''Parse the notify reply message.
- TODO, the error message should be refined properly.
rcode will not checked here, If we get the response
from the slave, it means the slaves has got the notify.'''
msg = Message(Message.PARSE)
try:
- errstr = 'notify reply error: '
msg.from_wire(msg_data)
if not msg.get_header_flag(Message.HEADERFLAG_QR):
- self._log_msg('error', errstr + 'bad flags')
+ logger.warn(NOTIFY_OUT_REPLY_QR_NOT_SET, from_addr[0],
+ from_addr[1])
return _BAD_QR
if msg.get_qid() != zone_notify_info.notify_msg_id:
- self._log_msg('error', errstr + 'bad query ID')
+ logger.warn(NOTIFY_OUT_REPLY_BAD_QID, from_addr[0],
+ from_addr[1], msg.get_qid(),
+ zone_notify_info.notify_msg_id)
return _BAD_QUERY_ID
question = msg.get_question()[0]
if question.get_name() != Name(zone_notify_info.zone_name):
- self._log_msg('error', errstr + 'bad query name')
+ logger.warn(NOTIFY_OUT_REPLY_BAD_QUERY_NAME, from_addr[0],
+ from_addr[1], question.get_name().to_text(),
+ Name(zone_notify_info.zone_name).to_text())
return _BAD_QUERY_NAME
if msg.get_opcode() != Opcode.NOTIFY():
- self._log_msg('error', errstr + 'bad opcode')
+ logger.warn(NOTIFY_OUT_REPLY_BAD_OPCODE, from_addr[0],
+ from_addr[1], msg.get_opcode().to_text())
return _BAD_OPCODE
except Exception as err:
# We don't care what exception, just report it?
- self._log_msg('error', errstr + str(err))
+ logger.error(NOTIFY_OUT_REPLY_UNCAUGHT_EXCEPTION, err)
return _BAD_REPLY_PACKET
return _REPLY_OK
@@ -481,14 +491,9 @@ class NotifyOut:
def _get_notify_reply(self, sock, tgt_addr):
try:
msg, addr = sock.recvfrom(512)
- except socket.error:
- self._log_msg('error', "notify to %s failed: can't read notify reply" % addr_to_str(tgt_addr))
+ except socket.error as err:
+ logger.error(NOTIFY_OUT_SOCKET_RECV_ERROR, tgt_addr[0],
+ tgt_addr[1], err)
return None
return msg
-
-
- def _log_msg(self, level, msg):
- if self._log:
- self._log.log_message(level, msg)
-
diff --git a/src/lib/python/isc/notify/notify_out_messages.mes b/src/lib/python/isc/notify/notify_out_messages.mes
new file mode 100644
index 0000000..f9de744
--- /dev/null
+++ b/src/lib/python/isc/notify/notify_out_messages.mes
@@ -0,0 +1,83 @@
+# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC 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.
+
+# No namespace declaration - these constants go in the global namespace
+# of the notify_out_messages python module.
+
+% NOTIFY_OUT_INVALID_ADDRESS invalid address %1#%2: %3
+The notify_out library tried to send a notify message to the given
+address, but it appears to be an invalid address. The configuration
+for secondary nameservers might contain a typographic error, or a
+different BIND 10 module has forgotten to validate its data before
+sending this module a notify command. As such, this should normally
+not happen, and points to an oversight in a different module.
+
+% NOTIFY_OUT_REPLY_BAD_OPCODE bad opcode in notify reply from %1#%2: %3
+The notify_out library sent a notify message to the nameserver at
+the given address, but the response did not have the opcode set to
+NOTIFY. The opcode in the response is printed. Since there was a
+response, no more notifies will be sent to this server for this
+notification event.
+
+% NOTIFY_OUT_REPLY_BAD_QID bad QID in notify reply from %1#%2: got %3, should be %4
+The notify_out library sent a notify message to the nameserver at
+the given address, but the query id in the response does not match
+the one we sent. Since there was a response, no more notifies will
+be sent to this server for this notification event.
+
+% NOTIFY_OUT_REPLY_BAD_QUERY_NAME bad query name in notify reply from %1#%2: got %3, should be %4
+The notify_out library sent a notify message to the nameserver at
+the given address, but the query name in the response does not match
+the one we sent. Since there was a response, no more notifies will
+be sent to this server for this notification event.
+
+% NOTIFY_OUT_REPLY_QR_NOT_SET QR flags set to 0 in reply to notify from %1#%2
+The notify_out library sent a notify message to the namesever at the
+given address, but the reply did not have the QR bit set to one.
+Since there was a response, no more notifies will be sent to this
+server for this notification event.
+
+% NOTIFY_OUT_RETRY_EXCEEDED notify to %1#%2: number of retries (%3) exceeded
+The maximum number of retries for the notify target has been exceeded.
+Either the address of the secondary nameserver is wrong, or it is not
+responding.
+
+% NOTIFY_OUT_SENDING_NOTIFY sending notify to %1#%2
+A notify message is sent to the secondary nameserver at the given
+address.
+
+% NOTIFY_OUT_SOCKET_ERROR socket error sending notify to %1#%2: %3
+There was a network error while trying to send a notify message to
+the given address. The address might be unreachable. The socket
+error is printed and should provide more information.
+
+% NOTIFY_OUT_SOCKET_RECV_ERROR socket error reading notify reply from %1#%2: %3
+There was a network error while trying to read a notify reply
+message from the given address. The socket error is printed and should
+provide more information.
+
+% NOTIFY_OUT_TIMEOUT retry notify to %1#%2
+The notify message to the given address (noted as address#port) has
+timed out, and the message will be resent until the max retry limit
+is reached.
+
+% NOTIFY_OUT_REPLY_UNCAUGHT_EXCEPTION uncaught exception: %1
+There was an uncaught exception in the handling of a notify reply
+message, either in the message parser, or while trying to extract data
+from the parsed message. The error is printed, and notify_out will
+treat the response as a bad message, but this does point to a
+programming error, since all exceptions should have been caught
+explicitely. Please file a bug report. Since there was a response,
+no more notifies will be sent to this server for this notification
+event.
diff --git a/src/lib/python/isc/notify/tests/notify_out_test.py b/src/lib/python/isc/notify/tests/notify_out_test.py
index 0eb77a3..83f6d1a 100644
--- a/src/lib/python/isc/notify/tests/notify_out_test.py
+++ b/src/lib/python/isc/notify/tests/notify_out_test.py
@@ -21,6 +21,7 @@ import time
import socket
from isc.datasrc import sqlite3_ds
from isc.notify import notify_out, SOCK_DATA
+import isc.log
# our fake socket, where we can read and insert messages
class MockSocket():
@@ -79,7 +80,6 @@ class TestZoneNotifyInfo(unittest.TestCase):
self.info.prepare_notify_out()
self.assertEqual(self.info.get_current_notify_target(), ('127.0.0.1', 53))
- self.assertEqual('127.0.0.1#53', notify_out.addr_to_str(('127.0.0.1', 53)))
self.info.set_next_notify_target()
self.assertEqual(self.info.get_current_notify_target(), ('1.1.1.1', 5353))
self.info.set_next_notify_target()
@@ -223,29 +223,30 @@ class TestNotifyOut(unittest.TestCase):
self.assertEqual(0, len(self._notify._waiting_zones))
def test_handle_notify_reply(self):
- self.assertEqual(notify_out._BAD_REPLY_PACKET, self._notify._handle_notify_reply(None, b'badmsg'))
+ fake_address = ('192.0.2.1', 53)
+ self.assertEqual(notify_out._BAD_REPLY_PACKET, self._notify._handle_notify_reply(None, b'badmsg', fake_address))
example_com_info = self._notify._notify_infos[('example.com.', 'IN')]
example_com_info.notify_msg_id = 0X2f18
# test with right notify reply message
data = b'\x2f\x18\xa0\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\03com\x00\x00\x06\x00\x01'
- self.assertEqual(notify_out._REPLY_OK, self._notify._handle_notify_reply(example_com_info, data))
+ self.assertEqual(notify_out._REPLY_OK, self._notify._handle_notify_reply(example_com_info, data, fake_address))
# test with unright query id
data = b'\x2e\x18\xa0\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\03com\x00\x00\x06\x00\x01'
- self.assertEqual(notify_out._BAD_QUERY_ID, self._notify._handle_notify_reply(example_com_info, data))
+ self.assertEqual(notify_out._BAD_QUERY_ID, self._notify._handle_notify_reply(example_com_info, data, fake_address))
# test with unright query name
data = b'\x2f\x18\xa0\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\03net\x00\x00\x06\x00\x01'
- self.assertEqual(notify_out._BAD_QUERY_NAME, self._notify._handle_notify_reply(example_com_info, data))
+ self.assertEqual(notify_out._BAD_QUERY_NAME, self._notify._handle_notify_reply(example_com_info, data, fake_address))
# test with unright opcode
data = b'\x2f\x18\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\03com\x00\x00\x06\x00\x01'
- self.assertEqual(notify_out._BAD_OPCODE, self._notify._handle_notify_reply(example_com_info, data))
+ self.assertEqual(notify_out._BAD_OPCODE, self._notify._handle_notify_reply(example_com_info, data, fake_address))
# test with unright qr
data = b'\x2f\x18\x10\x10\x00\x01\x00\x00\x00\x00\x00\x00\x07example\03com\x00\x00\x06\x00\x01'
- self.assertEqual(notify_out._BAD_QR, self._notify._handle_notify_reply(example_com_info, data))
+ self.assertEqual(notify_out._BAD_QR, self._notify._handle_notify_reply(example_com_info, data, fake_address))
def test_send_notify_message_udp_ipv4(self):
example_com_info = self._notify._notify_infos[('example.net.', 'IN')]
@@ -300,6 +301,15 @@ class TestNotifyOut(unittest.TestCase):
self._notify._zone_notify_handler(example_net_info, notify_out._EVENT_NONE)
self.assertNotEqual(cur_tgt, example_net_info._notify_current)
+ cur_tgt = example_net_info._notify_current
+ example_net_info.create_socket('127.0.0.1')
+ # dns message, will result in bad_qid, but what we are testing
+ # here is whether handle_notify_reply is called correctly
+ example_net_info._sock.remote_end().send(b'\x2f\x18\xa0\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\03com\x00\x00\x06\x00\x01')
+ self._notify._zone_notify_handler(example_net_info, notify_out._EVENT_READ)
+ self.assertNotEqual(cur_tgt, example_net_info._notify_current)
+
+
def _example_net_data_reader(self):
zone_data = [
('example.net.', '1000', 'IN', 'SOA', 'a.dns.example.net. mail.example.net. 1 1 1 1 1'),
@@ -406,6 +416,7 @@ class TestNotifyOut(unittest.TestCase):
self.assertFalse(thread.is_alive())
if __name__== "__main__":
+ isc.log.init("bind10")
unittest.main()
diff --git a/src/lib/resolve/resolve_messages.mes b/src/lib/resolve/resolve_messages.mes
index 97c4d90..f702d9b 100644
--- a/src/lib/resolve/resolve_messages.mes
+++ b/src/lib/resolve/resolve_messages.mes
@@ -123,11 +123,11 @@ called because a nameserver has been found, and that a query is being sent
to the specified nameserver.
% RESLIB_TEST_SERVER setting test server to %1(%2)
-This is an internal debugging message and is only generated in unit tests.
-It indicates that all upstream queries from the resolver are being routed to
-the specified server, regardless of the address of the nameserver to which
-the query would normally be routed. As it should never be seen in normal
-operation, it is a warning message instead of a debug message.
+This is a warning message only generated in unit tests. It indicates
+that all upstream queries from the resolver are being routed to the
+specified server, regardless of the address of the nameserver to which
+the query would normally be routed. If seen during normal operation,
+please submit a bug report.
% RESLIB_TEST_UPSTREAM sending upstream query for <%1> to test server at %2
This is a debug message and should only be seen in unit tests. A query for
@@ -135,8 +135,8 @@ the specified <name, class, type> tuple is being sent to a test nameserver
whose address is given in the message.
% RESLIB_TIMEOUT query <%1> to %2 timed out
-A debug message indicating that the specified query has timed out and as
-there are no retries left, an error will be reported.
+A debug message indicating that the specified upstream query has timed out and
+there are no retries left.
% RESLIB_TIMEOUT_RETRY query <%1> to %2 timed out, re-trying (retries left: %3)
A debug message indicating that the specified query has timed out and that
diff --git a/src/lib/util/filename.cc b/src/lib/util/filename.cc
index 1f2e5db..d7da9c8 100644
--- a/src/lib/util/filename.cc
+++ b/src/lib/util/filename.cc
@@ -132,6 +132,24 @@ Filename::useAsDefault(const string& name) const {
return (retstring);
}
+void
+Filename::setDirectory(const std::string& new_directory) {
+ std::string directory(new_directory);
+
+ if (directory.length() > 0) {
+ // append '/' if necessary
+ size_t sep = directory.rfind('/');
+ if (sep == std::string::npos || sep < directory.size() - 1) {
+ directory += "/";
+ }
+ }
+ // and regenerate the full name
+ std::string full_name = directory + name_ + extension_;
+
+ directory_.swap(directory);
+ full_name_.swap(full_name);
+}
+
} // namespace log
} // namespace isc
diff --git a/src/lib/util/filename.h b/src/lib/util/filename.h
index 984ecb0..c9874ce 100644
--- a/src/lib/util/filename.h
+++ b/src/lib/util/filename.h
@@ -86,6 +86,13 @@ public:
return (directory_);
}
+ /// \brief Set directory for the file
+ ///
+ /// \param new_directory The directory to set. If this is an empty
+ /// string, the directory this filename object currently
+ /// has will be removed.
+ void setDirectory(const std::string& new_directory);
+
/// \return Name of Given File Name
std::string name() const {
return (name_);
diff --git a/src/lib/util/tests/filename_unittest.cc b/src/lib/util/tests/filename_unittest.cc
index 33e6456..be29ff1 100644
--- a/src/lib/util/tests/filename_unittest.cc
+++ b/src/lib/util/tests/filename_unittest.cc
@@ -177,3 +177,40 @@ TEST_F(FilenameTest, UseAsDefault) {
EXPECT_EQ("/s/t/u", fname.useAsDefault("/s/t/u"));
EXPECT_EQ("/a/b/c", fname.useAsDefault(""));
}
+
+TEST_F(FilenameTest, setDirectory) {
+ Filename fname("a.b");
+ EXPECT_EQ("", fname.directory());
+ EXPECT_EQ("a.b", fname.fullName());
+ EXPECT_EQ("a.b", fname.expandWithDefault(""));
+
+ fname.setDirectory("/just/some/dir/");
+ EXPECT_EQ("/just/some/dir/", fname.directory());
+ EXPECT_EQ("/just/some/dir/a.b", fname.fullName());
+ EXPECT_EQ("/just/some/dir/a.b", fname.expandWithDefault(""));
+
+ fname.setDirectory("/just/some/dir");
+ EXPECT_EQ("/just/some/dir/", fname.directory());
+ EXPECT_EQ("/just/some/dir/a.b", fname.fullName());
+ EXPECT_EQ("/just/some/dir/a.b", fname.expandWithDefault(""));
+
+ fname.setDirectory("/");
+ EXPECT_EQ("/", fname.directory());
+ EXPECT_EQ("/a.b", fname.fullName());
+ EXPECT_EQ("/a.b", fname.expandWithDefault(""));
+
+ fname.setDirectory("");
+ EXPECT_EQ("", fname.directory());
+ EXPECT_EQ("a.b", fname.fullName());
+ EXPECT_EQ("a.b", fname.expandWithDefault(""));
+
+ fname = Filename("/first/a.b");
+ EXPECT_EQ("/first/", fname.directory());
+ EXPECT_EQ("/first/a.b", fname.fullName());
+ EXPECT_EQ("/first/a.b", fname.expandWithDefault(""));
+
+ fname.setDirectory("/just/some/dir");
+ EXPECT_EQ("/just/some/dir/", fname.directory());
+ EXPECT_EQ("/just/some/dir/a.b", fname.fullName());
+ EXPECT_EQ("/just/some/dir/a.b", fname.expandWithDefault(""));
+}
More information about the bind10-changes
mailing list