Blob Blame History Raw
From 402867038f8664e88e2d9ca42f2c77a46a0be7ae Mon Sep 17 00:00:00 2001
From: Martin Kosek <mkosek@redhat.com>
Date: Mon, 2 Jan 2012 16:49:59 +0100
Subject: [PATCH 1/3] Make sure that install tools log

When any log message is emitted before IPA install tools logging is
configured, it may break and leave install tools log empty. This
happens for example when

ipa-server-install --ip-address=$IP_ADDRESS

is run.

This patch makes sure that logging is right in these cases.

https://fedorahosted.org/freeipa/ticket/2214
---
 install/tools/ipa-ca-install      |    1 +
 install/tools/ipa-dns-install     |    1 +
 install/tools/ipa-replica-install |    1 +
 install/tools/ipa-server-install  |    2 +
 ipaserver/install/installutils.py |   43 +++++++++++++++++++++++++++++++++++++
 5 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 445b0621419b7aa5b4616e154d9f8193a5d517fb..c813659f34f4471132b83fd4159b69b76f5ce487 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -70,6 +70,7 @@ def get_dirman_password():
     return installutils.read_password("Directory Manager (existing master)", confirm=False, validate=False)
 
 def main():
+    installutils.bootstrap_logging()
     safe_options, options, filename = parse_options()
     installutils.standard_logging_setup("/var/log/ipareplica-ca-install.log", options.debug)
     logging.debug('%s was invoked with argument "%s" and options: %s' % (sys.argv[0], filename, safe_options))
diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
index d81b6a2e804a815d5bece8426a286e3190f6dee3..25c1bb0cac251d098e3744afd7b7eeab32a3fe6b 100755
--- a/install/tools/ipa-dns-install
+++ b/install/tools/ipa-dns-install
@@ -82,6 +82,7 @@ def parse_options():
     return safe_options, options
 
 def main():
+    bootstrap_logging()
     safe_options, options = parse_options()
 
     if os.getegid() != 0:
diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index dbc736764f38489df15900c4540a381764d0c261..7310d286292f571ef25b57b29d2a213f4bd855a1 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -286,6 +286,7 @@ def check_bind():
         sys.exit(1)
 
 def main():
+    installutils.bootstrap_logging()
     safe_options, options, filename = parse_options()
     installutils.standard_logging_setup("/var/log/ipareplica-install.log", options.debug)
     logging.debug('%s was invoked with argument "%s" and options: %s' % (sys.argv[0], filename, safe_options))
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 8f156e8dde7fbc4cfde00a0f6a2fc8e23403cc73..755f2772780010c62fdc642125107843bef61668 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -562,6 +562,8 @@ def main():
     global installation_cleanup
     ds = None
 
+    bootstrap_logging()
+
     safe_options, options = parse_options()
 
     if os.getegid() != 0:
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 0a36c354e1d2f901bfdef51c151d035ba8ee64ca..d0f611c611847d02f3d264d669a2e90689f5a87b 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -314,7 +314,47 @@ def port_available(port):
 
     return rv
 
+class BufferingHandler(logging.Handler):
+    log_queue = []
+
+    def __init__(self):
+        logging.Handler.__init__(self)
+        self.level = logging.DEBUG
+
+    def emit(self, record):
+        self.log_queue.append(record)
+
+    def flush(self):
+        pass
+
+def bootstrap_logging():
+    """
+    Bootstrap logging and create special handler which will buffer any log
+    emitted before standard_logging_setup is called. These will be later
+    processed when the logging is set up.
+    """
+    root_logger = logging.getLogger()
+    root_logger.setLevel(logging.DEBUG)
+    root_logger.addHandler(BufferingHandler())
+
 def standard_logging_setup(log_filename, debug=False, filemode='w'):
+    """
+    Set up logging. bootstrap_logging() should be called earlier if there
+    is a chance that a log is emitted before this setup.
+    """
+    root_logger = logging.getLogger()
+    log_queue = []
+
+    if root_logger.handlers:
+        # Remove any handlers that may have been set and which may cause
+        # problems with logging in install utils
+        handler_list = list(logging.getLogger().handlers)
+
+        for handler in handler_list:
+            if isinstance(handler, BufferingHandler):
+                log_queue.extend(handler.log_queue)
+            root_logger.removeHandler(handler)
+
     old_umask = os.umask(077)
     # Always log everything (i.e., DEBUG) to the log
     # file.
@@ -335,6 +375,9 @@ def standard_logging_setup(log_filename, debug=False, filemode='w'):
     console.setFormatter(formatter)
     logging.getLogger('').addHandler(console)
 
+    for log_record in log_queue:
+        root_logger.handle(log_record)
+
 def get_password(prompt):
     if os.isatty(sys.stdin.fileno()):
         return getpass.getpass(prompt)
-- 
1.7.7.5