Browse Source

[963] use logging framework for b10-dbutil

Except for when the user is prompted for Yes or No, all output now goes through
the logging framework
Jelte Jansen 13 years ago
parent
commit
ab56098767

+ 11 - 1
src/bin/dbutil/Makefile.am

@@ -3,11 +3,16 @@ SUBDIRS = . tests
 bin_SCRIPTS = b10-dbutil
 bin_SCRIPTS = b10-dbutil
 man_MANS = b10-dbutil.8
 man_MANS = b10-dbutil.8
 
 
+nodist_pylogmessage_PYTHON = $(PYTHON_LOGMSGPKG_DIR)/work/dbutil_messages.py
+pylogmessagedir = $(pyexecdir)/isc/log_messages/
+
 EXTRA_DIST = $(man_MANS) b10-dbutil.xml
 EXTRA_DIST = $(man_MANS) b10-dbutil.xml
 
 
 noinst_SCRIPTS = run_dbutil.sh
 noinst_SCRIPTS = run_dbutil.sh
 
 
 CLEANFILES = b10-dbutil b10-dbutil.pyc
 CLEANFILES = b10-dbutil b10-dbutil.pyc
+CLEANFILES += $(PYTHON_LOGMSGPKG_DIR)/work/dbutil_messages.py
+CLEANFILES += $(PYTHON_LOGMSGPKG_DIR)/work/dbutil_messages.pyc
 
 
 if ENABLE_MAN
 if ENABLE_MAN
 
 
@@ -16,7 +21,12 @@ b10-dbutil.8: b10-dbutil.xml
 
 
 endif
 endif
 
 
-b10-dbutil: dbutil.py
+# Define rule to build logging source files from message file
+$(PYTHON_LOGMSGPKG_DIR)/work/dbutil_messages.py : dbutil_messages.mes
+	$(top_builddir)/src/lib/log/compiler/message \
+	-d $(PYTHON_LOGMSGPKG_DIR)/work -p $(srcdir)/dbutil_messages.mes
+
+b10-dbutil: dbutil.py $(PYTHON_LOGMSGPKG_DIR)/work/dbutil_messages.py
 	$(SED) -e "s|@@PYTHONPATH@@|@pyexecdir@|" \
 	$(SED) -e "s|@@PYTHONPATH@@|@pyexecdir@|" \
 	       -e "s|@@SYSCONFDIR@@|@sysconfdir@|" \
 	       -e "s|@@SYSCONFDIR@@|@sysconfdir@|" \
 	       -e "s|@@LIBEXECDIR@@|$(pkglibexecdir)|" dbutil.py >$@
 	       -e "s|@@LIBEXECDIR@@|$(pkglibexecdir)|" dbutil.py >$@

+ 1 - 1
src/bin/dbutil/b10-dbutil.8

@@ -74,7 +74,7 @@ The upgrade function will upgrade a BIND 10 database \- no matter how old the sc
 .PP
 .PP
 \fB\-\-verbose\fR
 \fB\-\-verbose\fR
 .RS 4
 .RS 4
-Enable verbose mode\&. Each SQL command issued by the utility will be printed to before it is executed\&.
+Enable verbose mode\&. Each SQL command issued by the utility will be printed to stdout before it is executed\&.
 .RE
 .RE
 .PP
 .PP
 \fB\fIdbfile\fR\fR
 \fB\fIdbfile\fR\fR

+ 34 - 83
src/bin/dbutil/dbutil.py.in

@@ -38,7 +38,11 @@ import sys; sys.path.append("@@PYTHONPATH@@")
 import os, sqlite3, shutil
 import os, sqlite3, shutil
 from optparse import OptionParser
 from optparse import OptionParser
 import isc.util.process
 import isc.util.process
+import isc.log
+from isc.log_messages.dbutil_messages import *
 
 
+isc.log.init("b10-dbutil")
+logger = isc.log.Logger("dbutil")
 isc.util.process.rename()
 isc.util.process.rename()
 
 
 # @brief Version String
 # @brief Version String
@@ -55,7 +59,6 @@ EXIT_COMMAND_ERROR = 3
 EXIT_READ_ERROR = 4
 EXIT_READ_ERROR = 4
 EXIT_UPGRADE_ERROR = 5
 EXIT_UPGRADE_ERROR = 5
 
 
-
 # @brief Statements to Update the Database
 # @brief Statements to Update the Database
 # These are in the form of a list of dictionaries, each of which contains the
 # These are in the form of a list of dictionaries, each of which contains the
 # information to perform an incremental upgrade from one version of the
 # information to perform an incremental upgrade from one version of the
@@ -190,55 +193,6 @@ class DbutilException(Exception):
     """
     """
     pass
     pass
 
 
-# Functions for outputting messages in a consistent format.  As this is intended
-# to be an interactive utility, it was not considered necessary to use the full
-# logging framework for messages.
-
-def output(writer, prefix, text, ex = None):
-    """
-    @brief Write error message to output stream
-
-    @param writer Function to do the writing
-    @param prefix Prefix to the message
-    @param text Text to output
-    @param ex Possible exception holding additiona information
-    """
-    writer(prefix + ": " + text)
-    if ex is not None:
-        writer(" - " + str(ex))
-    writer("\n")
-
-
-def error(text, ex = None):
-    """
-    @brief Write error message to stderr.
-
-    @param text Text to output
-    @param ex Possible exception holding additiona information
-    """
-    output(sys.stderr.write, "ERROR", text, ex)
-
-
-def warn(text, ex = None):
-    """
-    @brief Write warning message to stderr.
-
-    @param text Text to output
-    @param ex Possible exception holding additiona information
-    """
-    output(sys.stderr.write, "WARN", text, ex)
-
-
-def info(text, ex = None):
-    """
-    @brief Write informational message to stdout.
-
-    @param text Text to output
-    @param ex Possible exception holding additiona information
-    """
-    output(sys.stdout.write, "INFO", text, ex)
-
-
 class Database:
 class Database:
     """
     """
     @brief Database Encapsulation
     @brief Database Encapsulation
@@ -297,12 +251,12 @@ class Database:
         @param statement SQL statement to execute
         @param statement SQL statement to execute
         """
         """
         if self.verbose:
         if self.verbose:
-            sys.stdout.write(statement + "\n")
+            logger.debug(40, DBUTIL_EXECUTE, statement)
 
 
         try:
         try:
             self.cursor.execute(statement)
             self.cursor.execute(statement)
         except Exception as ex:
         except Exception as ex:
-            error("failed to execute " + statement)
+            logger.error(DBUTIL_STATEMENT_ERROR, statement, ex)
             raise DbutilException(str(ex))
             raise DbutilException(str(ex))
 
 
     def result(self):
     def result(self):
@@ -337,7 +291,7 @@ class Database:
 
 
         # Do the backup
         # Do the backup
         shutil.copyfile(self.db_file, self.backup_file)
         shutil.copyfile(self.db_file, self.backup_file)
-        info("database " + self.db_file + " backed up to " + self.backup_file)
+        logger.info(DBUTIL_BACKUP, self.db_file, self.backup_file)
 
 
 def prompt_user():
 def prompt_user():
     """
     """
@@ -360,7 +314,7 @@ BIND 10 is not running before continuing.
     no_entered = False
     no_entered = False
     while (not yes_entered) and (not no_entered):
     while (not yes_entered) and (not no_entered):
         sys.stdout.write("Enter 'Yes' to proceed with the upgrade, " +
         sys.stdout.write("Enter 'Yes' to proceed with the upgrade, " +
-                         "'No' to exit the program: ")
+                         "'No' to exit the program: \n")
         response = sys.stdin.readline()
         response = sys.stdin.readline()
         if response.lower() == "yes\n":
         if response.lower() == "yes\n":
             yes_entered = True
             yes_entered = True
@@ -466,20 +420,18 @@ def check_version(db):
 
 
     match = compare_versions(current, latest)
     match = compare_versions(current, latest)
     if match == 0:
     if match == 0:
-        info("database version " + version_string(current))
-        info("this is the latest version of the database schema, " +
-             "no upgrade is required")
+        logger.info(DBUTIL_VERSION_CURRENT, version_string(current))
+        logger.info(DBUTIL_CHECK_OK)
         return EXIT_SUCCESS
         return EXIT_SUCCESS
     elif match < 0:
     elif match < 0:
-        info("database version " + version_string(current) +
-             ", latest version is " + version_string(latest))
-        info("re-run this program with the --upgrade switch to upgrade")
+        logger.info(DBUTIL_VERSION_LOW, version_string(current),
+                    version_string(latest))
+        logger.info(DBUTIL_CHECK_UPGRADE_NEEDED)
         return EXIT_NEED_UPDATE
         return EXIT_NEED_UPDATE
     else:
     else:
-        warn("database is at a later version (" + version_string(current) +
-             ") than this program can cope with (" +
-             version_string(get_latest_version()) + ")")
-        info("please get the latest version of b10-dbutil and re-run")
+        logger.warn(DBUTIL_VERSION_HIGH, version_string(current),
+                    version_string(get_latest_version()))
+        logger.info(DBUTIL_UPGRADE_DBUTIL)
         return EXIT_VERSION_TOO_HIGH
         return EXIT_VERSION_TOO_HIGH
 
 
 def perform_upgrade(db, upgrade):
 def perform_upgrade(db, upgrade):
@@ -492,10 +444,8 @@ def perform_upgrade(db, upgrade):
     @param db Database object
     @param db Database object
     @param upgrade Upgrade dictionary, holding "from", "to" and "statements".
     @param upgrade Upgrade dictionary, holding "from", "to" and "statements".
     """
     """
-    increment = (version_string(upgrade['from']) + " to " +
-                 version_string(upgrade['to']))
-    action = "upgrading database from " + increment
-    info(action)
+    logger.info(DBUTIL_UPGRADING, version_string(upgrade['from']),
+         version_string(upgrade['to']))
     for statement in upgrade['statements']:
     for statement in upgrade['statements']:
         db.execute(statement)
         db.execute(statement)
 
 
@@ -516,10 +466,10 @@ def perform_all_upgrades(db):
     """
     """
     match = compare_versions(get_version(db), get_latest_version())
     match = compare_versions(get_version(db), get_latest_version())
     if match == 0:
     if match == 0:
-        info("database already at latest version, no upgrade necessary")
+        logger.info(DBUTIL_UPGRADE_NOT_NEEDED)
 
 
     elif match > 0:
     elif match > 0:
-        warn("database at a later version than this utility can support")
+        logger.warn(DBUTIL_UPGRADE_NOT_POSSIBLE)
 
 
     else:
     else:
         # Work our way through all upgrade increments
         # Work our way through all upgrade increments
@@ -530,7 +480,7 @@ def perform_all_upgrades(db):
                 count = count + 1
                 count = count + 1
 
 
         if count > 0:
         if count > 0:
-            info("database upgrade successfully completed")
+            logger.info(DBUTIL_UPGRADE_SUCCESFUL)
         else:
         else:
             # Should not get here, as we established earlier that the database
             # Should not get here, as we established earlier that the database
             # was not at the latest version so we should have upgraded.
             # was not at the latest version so we should have upgraded.
@@ -567,22 +517,22 @@ def parse_command():
 
 
     # Set the database file on which to operate
     # Set the database file on which to operate
     if (len(args) > 1):
     if (len(args) > 1):
-        error("too many arguments to the command, maximum of one expected")
+        logger.error(DBUTIL_TOO_MANY_ARGUMENTS)
         parser.print_usage()
         parser.print_usage()
         sys.exit(EXIT_COMMAND_ERROR)
         sys.exit(EXIT_COMMAND_ERROR)
     elif len(args) == 0:
     elif len(args) == 0:
-        error("must supply name of the database file to upgrade")
+        logger.error(DBUTIL_NO_FILE)
         parser.print_usage()
         parser.print_usage()
         sys.exit(EXIT_COMMAND_ERROR)
         sys.exit(EXIT_COMMAND_ERROR)
 
 
     # Check for conflicting options.  If some are found, output a suitable
     # Check for conflicting options.  If some are found, output a suitable
     # error message and print the usage.
     # error message and print the usage.
     if options.check and options.upgrade:
     if options.check and options.upgrade:
-        error("--upgrade is not compatible with --check")
+        logger.error(DBUTIL_COMMAND_UPGRADE_CHECK)
     elif (not options.check) and (not options.upgrade):
     elif (not options.check) and (not options.upgrade):
-        error("must select one of --check or --upgrade")
+        logger.error(DBUTIL_COMMAND_NONE)
     elif (options.check and options.noconfirm):
     elif (options.check and options.noconfirm):
-        error("--noconfirm is not compatible with --check")
+        logger.error(DBUTIL_CHECK_NOCONFIRM)
     else:
     else:
         return (options, args)
         return (options, args)
 
 
@@ -596,6 +546,7 @@ if __name__ == "__main__":
     db = Database(args[0], options.verbose)
     db = Database(args[0], options.verbose)
     exit_code = EXIT_SUCCESS
     exit_code = EXIT_SUCCESS
 
 
+    logger.info(DBUTIL_FILE, args[0])
     if options.check:
     if options.check:
         # Check database - open, report, and close
         # Check database - open, report, and close
         try:
         try:
@@ -603,7 +554,7 @@ if __name__ == "__main__":
             exit_code = check_version(db)
             exit_code = check_version(db)
             db.close()
             db.close()
         except Exception as ex:
         except Exception as ex:
-            error("unable to check database version - " + str(ex))
+            logger.error(DBUTIL_CHECK_ERROR, ex)
             exit_code = EXIT_READ_ERROR
             exit_code = EXIT_READ_ERROR
 
 
     elif options.upgrade:
     elif options.upgrade:
@@ -611,7 +562,7 @@ if __name__ == "__main__":
         if not options.noconfirm:
         if not options.noconfirm:
             proceed = prompt_user()
             proceed = prompt_user()
             if not proceed:
             if not proceed:
-                info("upgrade abandoned - database has not been changed\n")
+                logger.info(DBUTIL_UPGRADE_CANCELED)
                 sys.exit(EXIT_SUCCESS)
                 sys.exit(EXIT_SUCCESS)
 
 
         # It is.  Do a backup then do the upgrade.
         # It is.  Do a backup then do the upgrade.
@@ -624,14 +575,14 @@ if __name__ == "__main__":
             db.close()
             db.close()
         except Exception as ex:
         except Exception as ex:
             if in_progress:
             if in_progress:
-                error("upgrade failed - " + str(ex))
-                warn("database may be corrupt, restore it from backup")
+                logger.error(DBUTIL_UPGRADE_FAILED, ex)
+                logger.warn(DBUTIL_DATABASE_MAY_BE_CORRUPTED)
             else:
             else:
-                error("upgrade preparation failed - " + str(ex))
-                info("database upgrade was not attempted")
+                logger.error(DBUTIL_UPGRADE_PREPARATION_FAILED, ex)
+                logger.info(DBUTIL_UPGRADE_NOT_ATTEMPTED)
             exit_code = EXIT_UPGRADE_ERROR
             exit_code = EXIT_UPGRADE_ERROR
     else:
     else:
-        error("internal error, neither --check nor --upgrade selected")
+        logger.error(DBUTIL_NO_ACTION_SPECIFIED)
         exit_code = EXIT_COMMAND_ERROR
         exit_code = EXIT_COMMAND_ERROR
 
 
     sys.exit(exit_code)
     sys.exit(exit_code)

+ 117 - 0
src/bin/dbutil/dbutil_messages.mes

@@ -0,0 +1,117 @@
+# Copyright (C) 2012  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 ddns messages python module.
+
+# When you add a message to this file, it is a good idea to run
+# <topsrcdir>/tools/reorder_message_file.py to make sure the
+# messages are in the correct order.
+
+% DBUTIL_BACKUP created backup of %1 in %2
+A backup for the given database file was created. Same of original file and
+backup are given in the output message.
+
+% DBUTIL_CHECK_ERROR unable to check database version: %1
+There was an error while trying to check the current version of the database
+schema. The error is shown in the message.
+
+% DBUTIL_CHECK_NOCONFIRM --noconfirm is not compatible with --check
+b10-dbutil was called with --check and --noconfirm. --noconfirm only has
+meaning with --upgrade, so this is considered an error.
+
+% DBUTIL_CHECK_OK this is the latest version of the database schema. No upgrade is required
+The database schema version has been checked, and is up to date.
+No action is required.
+
+% DBUTIL_CHECK_UPGRADE_NEEDED re-run this program with the --upgrade switch to upgrade
+The database schema version is not up to date, and an update is required.
+Please run the dbutil tool again, with the --upgrade argument.
+
+% DBUTIL_COMMAND_NONE must select one of --check or --upgrade
+b10-dbutil was called with neither --check nor --upgrade. One action must be
+provided.
+
+% DBUTIL_COMMAND_UPGRADE_CHECK --upgrade is not compatible with --check
+b10-dbutil was called with both the commands --upgrade and --check. Only one
+action can be performed at a time.
+
+% DBUTIL_DATABASE_MAY_BE_CORRUPTED database may be corrupt, restore it from backup
+The upgrade failed while it was in progress; the database may now be in an
+inconsistent state, and it is advised to restore it from the backup that was
+created when b10-dbutil started.
+
+% DBUTIL_EXECUTE Executing SQL statement: %1
+Debug message; the given SQL statement is executed
+
+% DBUTIL_FILE Database file: %1
+The database file that is being checked.
+
+% DBUTIL_NO_ACTION_SPECIFIED Command error: neither --check nor --upgrade selected
+b10-dbutil was called without either --check or --upgrade.
+
+% DBUTIL_NO_FILE must supply name of the database file to upgrade
+b10-dbutil was called without a database file. Currently, it cannot find this
+file on its own, and it must be provided.
+
+% DBUTIL_STATEMENT_ERROR failed to execute %1: %2
+The given database statement failed to execute. The error is shown in the
+message.
+
+% DBUTIL_TOO_MANY_ARGUMENTS too many arguments to the command, maximum of one expected
+There were too many command-line arguments to b10-dbutil
+
+% DBUTIL_UPGRADE_CANCELED upgrade canceled; database has not been changed
+The user aborted the upgrade, and b10-dbutil will now exit.
+
+% DBUTIL_UPGRADE_DBUTIL please get the latest version of b10-dbutil and re-run
+A database schema was found that was newer than this version of dbutil, which
+is apparently out of date and should be upgraded itself.
+
+% DBUTIL_UPGRADE_FAILED upgrade failed: %1
+While the upgrade was in progress, an unexpected error occurred. The error
+is shown in the message.
+
+% DBUTIL_UPGRADE_NOT_ATTEMPTED database upgrade was not attempted
+Due to the earlier failure, the database schema upgrade was not attempted,
+and b10-dbutil will now exit.
+
+% DBUTIL_UPGRADE_NOT_NEEDED database already at latest version, no upgrade necessary
+b10-dbutil was told to upgrade the database schema, but it is already at the
+latest version.
+
+% DBUTIL_UPGRADE_NOT_POSSIBLE database at a later version than this utility can support
+b10-dbutil was told to upgrade the database schema, but it is at a higher
+version than this tool currently supports. Please update b10-dbutil and try
+again.
+
+% DBUTIL_UPGRADE_PREPARATION_FAILED upgrade preparation failed: %1
+An unexpected error occurred while b10-dbutil was preparing to upgrade the
+database schema. The error is shown in the message
+
+% DBUTIL_UPGRADE_SUCCESFUL database upgrade successfully completed
+The database schema update was completed successfully.
+
+% DBUTIL_UPGRADING upgrading database from %1 to %2
+An upgrade is in progress, the versions of the current upgrade action are shown.
+
+% DBUTIL_VERSION_CURRENT database version %1
+The current version of the database schema.
+
+% DBUTIL_VERSION_HIGH database is at a later version (%1) than this program can cope with (%2)
+The database schema is at a higher version than b10-dbutil knows about.
+
+% DBUTIL_VERSION_LOW database version %1, latest version is %2.
+The database schema is not up to date, the current version and the latest
+version are in the message.

+ 2 - 2
src/bin/dbutil/tests/dbutil_test.sh.in

@@ -273,10 +273,10 @@ check_version() {
     then
     then
         fail "version check failed on database $1; return code $?"
         fail "version check failed on database $1; return code $?"
     else
     else
-        ../run_dbutil.sh --check $verfile | grep "$2" > /dev/null
+        ../run_dbutil.sh --check $verfile 2>&1 | grep "$2" > /dev/null
         if [ $? -ne 0 ]
         if [ $? -ne 0 ]
         then
         then
-            fail "database $1 not at expected version $2"
+            fail "database $1 not at expected version $2 (output: $?)"
         else
         else
             succeed
             succeed
         fi
         fi

+ 1 - 0
src/lib/python/isc/log_messages/dbutil_messages.py

@@ -0,0 +1 @@
+from work.dbutil_messages import *