7066254 Problem with install/logging
authorGinnie Wray<virginia.wray@oracle.com>
Tue, 19 Jun 2012 12:18:37 -0600
changeset 1717 10cb4d15a248
parent 1716 0cea9255024f
child 1718 4cec97c628bb
7066254 Problem with install/logging 7170155 DC leaves log files in /var/tmp/install
usr/src/cmd/auto-install/auto_install.py
usr/src/cmd/distro_const/__init__.py
usr/src/cmd/gui-install/src/__init__.py
usr/src/cmd/gui-install/src/gui_install_common.py
usr/src/cmd/system-config/__init__.py
usr/src/cmd/system-config/test/test_sysconfig.py
usr/src/cmd/text-install/__init__.py
usr/src/lib/install_common/__init__.py.src
usr/src/lib/install_doc/data_object/__init__.py
usr/src/lib/install_engine/__init__.py
usr/src/lib/install_engine/test/engine_test_utils.py
usr/src/lib/install_engine/test/test_engine.py
usr/src/lib/install_logging_pymod/logger.py
usr/src/lib/install_logging_pymod/test/test_logger.py
usr/src/lib/install_transfer/test/test_cpio.py
usr/src/lib/install_transfer/test/test_info.py
usr/src/lib/install_transfer/test/test_ips.py
usr/src/lib/install_transfer/test/test_misc_transfer.py
usr/src/lib/install_transfer/test/test_p5i.py
usr/src/lib/install_transfer/test/test_svr4.py
--- a/usr/src/cmd/auto-install/auto_install.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/cmd/auto-install/auto_install.py	Tue Jun 19 12:18:37 2012 -0600
@@ -78,7 +78,7 @@
 from solaris_install.ict.apply_sysconfig import APPLY_SYSCONFIG_DICT, \
     APPLY_SYSCONFIG_PROFILE_KEY
 from solaris_install.ict.transfer_files import add_transfer_files_to_doc
-from solaris_install.logger import FileHandler, ProgressHandler, MAX_INT
+from solaris_install.logger import ProgressHandler, MAX_INT
 from solaris_install.logger import INSTALL_LOGGER_NAME
 from solaris_install.manifest.parser import ManifestError, \
     MANIFEST_PARSER_DATA
@@ -123,30 +123,32 @@
         Class constructor
         """
         self.installed_root_dir = self.INSTALLED_ROOT_DIR
-        self.install_log = None
         self.auto_reboot = False
         self.doc = None
         self.exitval = self.AI_EXIT_SUCCESS
         self.derived_script = None
         self.manifest = None
 
+        # Logger Variables
+        self.install_log = None
+        self.logger = None
+        self.progress_ph = None
+
         # To remember the BE when we find it.
         self._be = None
 
         # Parse command line arguments
         self.options, self.args = self.parse_args(args)
 
-        # Initialize Install Engine
-        self.engine = InstallEngine(stop_on_error=True)
-        self.doc = self.engine.data_object_cache
-
         if self.options.zonename is not None:
             # If we're installing a zone root, generate a work_dir
             # location based on the current PID.
             work_dir = "/system/volatile/install." + str(os.getpid())
 
             # Add ApplicationData to the DOC
-            self._app_data = ApplicationData("auto-install", work_dir=work_dir)
+            self._app_data = ApplicationData("auto-install", work_dir=work_dir,
+                logname=self.INSTALL_LOG)
+
             self._app_data.data_dict[ALT_POOL_DATASET] = \
                 self.options.alt_zpool_dataset
 
@@ -154,7 +156,24 @@
             self.installed_root_dir = work_dir + self.INSTALLED_ROOT_DIR
         else:
             # Add ApplicationData to the DOC
-            self._app_data = ApplicationData("auto-install")
+            self._app_data = ApplicationData("auto-install",
+                logname=self.INSTALL_LOG)
+
+        # Get the logname handle
+        self.install_log = self._app_data.logname
+
+        # Initialize the Install Engine
+        self.engine = InstallEngine(self.install_log,
+                loglevel=logging.DEBUG, stop_on_error=True)
+        self.doc = self.engine.data_object_cache
+
+        # Establish the logger instance for AI
+        self.logger = logging.getLogger(INSTALL_LOGGER_NAME)
+
+        if not self.options.list_checkpoints:
+            self.logger.info("Install Log: %s" % (self.install_log),
+            extra={self.AI_INFO_PREFIX: "Install Log",
+            self.AI_INFO_MSG: self.install_log})
 
         # Add profile location to the ApplySysconfig checkpoint's data dict.
         if self.options.profile is not None:
@@ -184,10 +203,7 @@
         # Clear error service
         errsvc.clear_error_list()
 
-        # Create Logger and setup logfiles
-        self.install_log_fh = None
-        self.logger = None
-        self.progress_ph = None
+        # Setup additional AI logging
         self.setup_logs()
 
         if not self.options.list_checkpoints:
@@ -384,13 +400,9 @@
 
     def setup_logs(self):
         """
-        Create the logger instance for AI and create simple and
-        detailed log files to use.
+        Create the additional loggers for AI.
         """
 
-        # Create logger for AI
-        self.logger = logging.getLogger(INSTALL_LOGGER_NAME)
-
         # Log progress and info messages to the console.
         self.progress_ph = AIProgressHandler(self.logger,
             skip_console_msg=(self.options.list_checkpoints or \
@@ -409,20 +421,6 @@
                 prefix_key=self.AI_INFO_PREFIX, msg_key=self.AI_INFO_MSG)
         self.progress_ph.setFormatter(formatter)
 
-        # create a install_log file handler and add it to the ai_logger
-
-        # set the logfile names
-        self.install_log = os.path.join(self._app_data.work_dir,
-            self.INSTALL_LOG)
-        self.install_log_fh = FileHandler(self.install_log)
-
-        self.install_log_fh.setLevel(logging.DEBUG)
-        if not self.options.list_checkpoints:
-            self.logger.info("Install Log: %s" % (self.install_log),
-                extra={self.AI_INFO_PREFIX: "Install Log",
-                self.AI_INFO_MSG: self.install_log})
-        self.logger.addHandler(self.install_log_fh)
-
     @property
     def be(self):
         if self._be is not None:
@@ -671,7 +669,7 @@
                     # Now do actual transfer of logs
                     self.logger.debug("Transferring log to %s" %
                         (new_be.mountpoint + self.BE_LOG_DIR))
-                    self.install_log_fh.transfer_log(
+                    self.logger.default_fh.transfer_log(
                         new_be.mountpoint + self.BE_LOG_DIR, isdir=True)
 
                     # And cleanup
--- a/usr/src/cmd/distro_const/__init__.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/cmd/distro_const/__init__.py	Tue Jun 19 12:18:37 2012 -0600
@@ -28,7 +28,6 @@
 
 __all__ = ["cli", "distro_const", "execution_checkpoint", "distro_spec"]
 
-
 import logging
 import optparse
 import os
@@ -47,6 +46,7 @@
 from osol_install.liberrsvc import ES_DATA_EXCEPTION
 from solaris_install import CalledProcessError, run, DC_LABEL
 from solaris_install.boot.boot_spec import BootMods
+from solaris_install import system_temp_path
 from solaris_install.data_object import DataObject, ObjectNotFoundError
 from solaris_install.data_object.cache import DataObjectCache
 from solaris_install.data_object.data_dict import DataObjectDict
@@ -55,7 +55,7 @@
 from solaris_install.engine import FileNotFoundError, InstallEngine, \
     NoDatasetError, RollbackError, UsageError, UnknownChkptError
 from solaris_install.engine import INSTALL_LOGGER_NAME
-from solaris_install.logger import DEFAULTLOG, FileHandler, InstallFormatter
+from solaris_install.logger import FileHandler, InstallFormatter
 from solaris_install.manifest.parser import ManifestError
 from solaris_install.target import Target
 from solaris_install.target.logical import Filesystem, Zpool
@@ -64,6 +64,8 @@
 
 DC_LOCKFILE = "distro_const.lock"
 DC_LOGGER = None
+LOG_TIMESTAMP = time.strftime("%Y-%m-%d.%H:%M")
+DEFAULTLOG = system_temp_path("dc/default_log" + '.' + LOG_TIMESTAMP)
 
 
 class Lockfile(object):
@@ -82,7 +84,7 @@
 
         if os.path.exists(self.filename):
             raise RuntimeError("distro_const: An instance of distro_const "
-                               "is already running in %s" % 
+                               "is already running in %s" %
                                os.path.split(self.filename)[0])
         else:
             # touch the lockfile
@@ -442,21 +444,22 @@
     try:
         # We initialize the Engine with stop_on_error set so that if there are
         # errors during manifest parsing, the processing stops
-        eng = InstallEngine(debug=False, stop_on_error=True)
+        eng = InstallEngine(DEFAULTLOG, debug=False, exclusive_rw=True,
+            stop_on_error=True)
         doc = eng.data_object_cache
 
         global DC_LOGGER
         DC_LOGGER = logging.getLogger(INSTALL_LOGGER_NAME)
 
         # set the logfile name
-        log_name = "log.%s" % time.strftime("%Y-%m-%d.%H:%M")
+        log_name = "log.%s" % LOG_TIMESTAMP
         detail_log_name = "detail-%s" % log_name
         simple_log_name = "simple-%s" % log_name
 
         # create an additional FileHandler for a simple log
         base, logfile = os.path.split(DEFAULTLOG)
         simple_logname = os.path.join(base, "simple-" + logfile)
-        simple_fh = FileHandler(simple_logname)
+        simple_fh = FileHandler(simple_logname, exclusive_rw=True)
         simple_fh.setLevel(logging.INFO)
         DC_LOGGER.addHandler(simple_fh)
 
@@ -498,6 +501,9 @@
                 DC_LOGGER.transfer_log(destination=new_detaillog)
                 simple_fh.transfer_log(destination=new_simplelog)
 
+                # Remove the original DEFAULTLOG. It's no longer needed
+                shutil.rmtree(base)
+
                 # set the http_proxy if one is specified in the manifest
                 dc_set_http_proxy(DC_LOGGER)
 
--- a/usr/src/cmd/gui-install/src/__init__.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/cmd/gui-install/src/__init__.py	Tue Jun 19 12:18:37 2012 -0600
@@ -43,14 +43,15 @@
 import gtk
 
 import osol_install.errsvc as errsvc
-from solaris_install import CalledProcessError, Popen, \
-    post_install_logs_path, run
+from solaris_install import ApplicationData, CalledProcessError, Popen, \
+    post_install_logs_path, run, check_log_level
 from solaris_install.engine import InstallEngine
 from solaris_install.gui_install.gui_install_common import exit_gui_install, \
     modal_dialog, other_instance_is_running, start_td_local, write_pid_file, \
-    CLEANUP_CPIO_INSTALL, DEFAULT_LOG_LEVEL, DEFAULT_LOG_LOCATION, GLADE_DIR, \
-    LOG_FORMAT, LOG_LEVEL_INPUT, LOG_NAME_INPUT, LOGNAME, RELEASE, \
-    TARGET_DISCOVERY, TRANSFER_PREP, VARSHARE_DATASET
+    CLEANUP_CPIO_INSTALL, DEBUG_LOG_LEVEL, DEFAULT_LOG_LEVEL, \
+    DEFAULT_LOG_LOCATION, GLADE_DIR, LOG_FORMAT, LOG_LEVEL_INPUT, \
+    LOG_NAME_INPUT, LOGNAME, RELEASE, TARGET_DISCOVERY, TRANSFER_PREP, \
+    VARSHARE_DATASET
 from solaris_install.gui_install.install_profile import InstallProfile
 from solaris_install.gui_install.screen_manager import ScreenManager
 from solaris_install.ict.transfer_files import add_transfer_files_to_doc
@@ -229,25 +230,6 @@
     profile.set_locale_data([locale_description], [the_locale], the_locale)
 
 
-def setup_logging(logname, log_level):
-    '''Initialize the logger, logging to logname at log_level'''
-    logger = logging.getLogger(INSTALL_LOGGER_NAME)
-
-    log_level = log_level.upper()
-    if hasattr(logging, log_level):
-        log_level = getattr(logging, log_level.upper())
-    elif log_level == LOG_NAME_INPUT:
-        log_level = LOG_LEVEL_INPUT
-    else:
-        raise IOError(2, "Invalid --log-level parameter", log_level.lower())
-
-    logger.setLevel(log_level)
-    logger.transfer_log(destination=logname)
-
-    logger.info("**** START ****")
-    return logger
-
-
 def _init_locale():
     '''Initialize the locale for gui-install'''
     locale.setlocale(locale.LC_ALL, "")
@@ -296,25 +278,37 @@
                       "logging level to 'input' and enables CTRL-C for "
                       "killing the program\n"))
     options, args = parser.parse_args()
+
+    # Initialize the Engine and set up logging
+    work_dir = os.path.dirname(options.logname)
+    logname = os.path.basename(options.logname)
+    app_data = ApplicationData("gui-install", work_dir=work_dir,
+                               logname=logname)
+
     if options.log_level is None:
         if options.debug:
-            options.log_level = "debug"
+            options.log_level = DEBUG_LOG_LEVEL
         else:
             options.log_level = DEFAULT_LOG_LEVEL
+        InstallEngine(app_data.logname, loglevel=options.log_level, debug=True)
+    elif check_log_level(options.log_level):
+        InstallEngine(app_data.logname, loglevel=options.log_level,
+                      debug=options.debug)
+    else:
+        raise IOError(2, "Invalid --log-level parameter", options.log_level)
 
-    engine = InstallEngine(loglevel=options.log_level,
-                           debug=True)
-    try:
-        logger = setup_logging(options.logname, options.log_level)
-    except IOError, err:
-        parser.error("%s '%s'" % (err.strerror, err.filename))
+    doc = InstallEngine.get_instance().doc
+    doc.persistent.insert_children(app_data)
+
+    logger = logging.getLogger(INSTALL_LOGGER_NAME)
+    logger.info("**** START ****")
 
     logger.debug("CLI options: log location = %s, verbosity = %s, debug "
-                  "mode = %s",
-                  options.logname, options.log_level, options.debug)
+        "mode = %s", app_data.logname,
+        logging.getLevelName(options.log_level).lower(), options.debug)
 
     setup_checkpoints()
-    manager = ScreenManager(options.logname)
+    manager = ScreenManager(app_data.logname)
 
     start_td_local()
 
@@ -322,7 +316,7 @@
     save_locale_in_doc()
     manager.main()
 
-    exit_gui_install(logname=options.logname, errcode=0)
+    exit_gui_install(logname=app_data.logname, errcode=0)
 
 if __name__ == '__main__':
     main()
--- a/usr/src/cmd/gui-install/src/gui_install_common.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/cmd/gui-install/src/gui_install_common.py	Tue Jun 19 12:18:37 2012 -0600
@@ -76,10 +76,10 @@
 LOGNAME = None
 
 # default logging level
-DEFAULT_LOG_LEVEL = "info"
+DEFAULT_LOG_LEVEL = logging.INFO
 
 # debug logging level
-DEBUG_LOG_LEVEL = "debug"
+DEBUG_LOG_LEVEL = logging.DEBUG
 
 # default log format
 LOG_FORMAT = ("%(asctime)s - %(levelname)-8s: %(message)s")
--- a/usr/src/cmd/system-config/__init__.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/cmd/system-config/__init__.py	Tue Jun 19 12:18:37 2012 -0600
@@ -25,7 +25,6 @@
 
 '''System Configuration Interactive (SCI) Tool'''
 
-
 import gettext
 import atexit
 import curses
@@ -175,7 +174,7 @@
 DEFAULT_SC_LOCATION = os.path.join(VOLATILE_PATH, "profile",
                                    DEFAULT_SC_PROFILE)
 
-DEFAULT_LOG_LOCATION = "/var/tmp/install/sysconfig.log"
+DEFAULT_LOG_LOC = os.path.join(VOLATILE_PATH, "sysconfig/sysconfig.log")
 DEFAULT_LOG_LEVEL = "info"
 LOG_FORMAT = ("%(asctime)s - %(levelname)-8s: "
               "%(filename)s:%(lineno)d %(message)s")
@@ -983,7 +982,7 @@
         parser.add_option("-l", "--log-location", dest="logname",
                           help=_("Set log location to FILE "
                           "(default: %default)"),
-                          metavar="FILE", default=DEFAULT_LOG_LOCATION)
+                          metavar="FILE", default=DEFAULT_LOG_LOC)
         parser.add_option("-v", "--log-level", dest="log_level",
                           default=DEFAULT_LOG_LEVEL,
                           help=_("Set log verbosity to LEVEL. In order of "
@@ -1075,8 +1074,8 @@
 
 def _prepare_engine(options):
     '''Initialize the InstallEngine'''
-    InstallEngine(default_log=options.logname, loglevel=options.log_level,
-                  debug=options.debug)
+    InstallEngine(options.logname, loglevel=options.log_level,
+                  debug=options.debug, exclusive_rw=options.exclusive_rw)
 
     logger = logging.getLogger(INSTALL_LOGGER_NAME)
 
@@ -1132,6 +1131,8 @@
     if sub_cmd[0] == CONFIGURE or sub_cmd[0] == UNCONFIGURE:
         do_unconfigure(sub_cmd[0], options)
     elif sub_cmd[0] == CREATE_PROFILE:
+        # Set the exclusive read write flag to true
+        options.exclusive_rw = True
         do_create_profile(options)
 
     sys.exit(SU_OK)
--- a/usr/src/cmd/system-config/test/test_sysconfig.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/cmd/system-config/test/test_sysconfig.py	Tue Jun 19 12:18:37 2012 -0600
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
 #
 
 '''
@@ -42,22 +42,22 @@
         '''parse_options() returns proper subcommmand'''
         (options, sub_cmd) = sysconfig._parse_options(["create-profile"])
         self.assertEqual(sub_cmd[0], "create-profile")
-    
+
     def test_parse_options_no_flags(self):
         '''parse_options() returns proper default options'''
         (options, sub_cmd) = sysconfig._parse_options(["create-profile"])
         if sysconfig._in_rozr_zone():
             self.assertEqual(options.logname,
             os.path.join("/system/volatile",
-                         os.path.basename(sysconfig.DEFAULT_LOG_LOCATION)))
+                         os.path.basename(sysconfig.DEFAULT_LOG_LOC)))
         else:
-            self.assertEqual(options.logname, sysconfig.DEFAULT_LOG_LOCATION)
+            self.assertEqual(options.logname, sysconfig.DEFAULT_LOG_LOC)
 
         self.assertEqual(options.log_level,
                          getattr(logging, sysconfig.DEFAULT_LOG_LEVEL.upper()))
         self.assertFalse(options.force_bw)
         self.assertFalse(options.debug)
-    
+
     def test_parse_options_accepts_flags(self):
         '''parse_options() accepts "create-profile -l <log> -b -o <profile>"'''
         (options, sub_cmd) = sysconfig._parse_options(["create-profile", "-l",
@@ -70,12 +70,12 @@
 
         self.assertEqual(options.profile, "/foo/sc.xml")
         self.assertTrue(options.force_bw)
-    
+
     def test_parse_options_log_level_valid(self):
         '''parse_options() properly reformats error, warn, info,
            debug and input'''
         levels = ["error", "warn", "info", "debug"]
-        
+
         for level in levels:
             (options, sub_cmd) = sysconfig._parse_options(["create-profile",
                                                            "-v", level])
@@ -85,12 +85,12 @@
                 self.assertTrue(options.debug)
             else:
                 self.assertFalse(options.debug)
-        
+
         (options, sub_cmd) = sysconfig._parse_options(["create-profile", "-v",
                                                        "input"])
         self.assertEqual(options.log_level, sysconfig.LOG_LEVEL_INPUT)
         self.assertTrue(options.debug)
-    
+
     def test_parse_options_invalid_log_level(self):
         '''parse_options() rejects unsupported log levels'''
         self.assertRaises(SystemExit, sysconfig._parse_options,
--- a/usr/src/cmd/text-install/__init__.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/cmd/text-install/__init__.py	Tue Jun 19 12:18:37 2012 -0600
@@ -29,7 +29,8 @@
 import gettext
 import os
 
-from solaris_install import gpt_firmware_check
+from solaris_install import gpt_firmware_check, ApplicationData, \
+    check_log_level
 from solaris_install.getconsole import get_console, SERIAL_CONSOLE
 
 #
@@ -129,8 +130,8 @@
 
 LOG_LOCATION_FINAL = post_install_logs_path('install_log')
 DEFAULT_LOG_LOCATION = "/system/volatile/install_log"
-DEFAULT_LOG_LEVEL = "info"
-DEBUG_LOG_LEVEL = "debug"
+DEFAULT_LOG_LEVEL = logging.INFO
+DEBUG_LOG_LEVEL = logging.DEBUG
 REBOOT = "/usr/sbin/reboot"
 
 LOGGER = None
@@ -165,26 +166,6 @@
     sys.exit(errcode)
 
 
-def setup_logging(logname, log_level):
-    '''setup the logger, logging to logname at log_level'''
-
-    global LOGGER
-    LOGGER = logging.getLogger(INSTALL_LOGGER_NAME)
-
-    log_level = log_level.upper()
-    if hasattr(logging, log_level):
-        log_level = getattr(logging, log_level.upper())
-    elif log_level == LOG_NAME_INPUT:
-        log_level = LOG_LEVEL_INPUT
-    else:
-        raise IOError(2, "Invalid --log-level parameter", log_level.lower())
-
-    LOGGER.setLevel(log_level)
-    LOGGER.transfer_log(destination=logname)
-
-    LOGGER.info("**** START ****")
-
-
 def make_screen_list(main_win, target_controller, install_data):
     '''Initialize the screen list. On x86, add screens for editing slices
     within a partition. Also, trigger the target discovery thread.
@@ -257,10 +238,31 @@
         the checkpoints to be used for doing the install.
     '''
 
-    eng = InstallEngine(debug=options.debug)
+    # Set up logging and initialize the InstallEngine
+    work_dir = os.path.dirname(options.logname)
+    logname = os.path.basename(options.logname)
+    app_data = ApplicationData("text-install", work_dir=work_dir,
+                               logname=logname)
 
-    # setup_logging() must be called after the engine is initialized.
-    setup_logging(options.logname, options.log_level)
+    # Check to make sure the log levels are valid.
+    if check_log_level(options.log_level):
+        # This delineation is necessary because of the "INPUT" log
+        # level that is available in the text installer. It won't
+        # register as an integer, while the logging levels will.
+        if isinstance(options.log_level, int):
+            eng = InstallEngine(app_data.logname, loglevel=options.log_level,
+                                debug=options.debug)
+        else:
+            eng = InstallEngine(app_data.logname, debug=options.debug)
+    else:
+        raise IOError(2, "Invalid --log-level parameter", options.log_level)
+
+    doc = InstallEngine.get_instance().doc
+    doc.persistent.insert_children(app_data)
+
+    global LOGGER
+    LOGGER = logging.getLogger(INSTALL_LOGGER_NAME)
+    LOGGER.info("**** START ****")
 
     terminalui.init_logging(INSTALL_LOGGER_NAME)
 
--- a/usr/src/lib/install_common/__init__.py.src	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_common/__init__.py.src	Tue Jun 19 12:18:37 2012 -0600
@@ -428,12 +428,14 @@
     - Work Directory, defaulting to /system/volatile
     """
 
-    def __init__(self, application_name, work_dir="/system/volatile/"):
+    def __init__(self, application_name, work_dir="/system/volatile/",
+        logname=None):
         super(ApplicationData, self).__init__(application_name)
 
         self._application_name = application_name
         self._work_dir = work_dir
         self.data_dict = dict()
+        self._logname = logname
 
     @property
     def application_name(self):
@@ -445,6 +447,11 @@
         """Read-only Work Directory - set at initialisation"""
         return self._work_dir
 
+    @property
+    def logname(self):
+        """Read-only logname - set at initialization"""
+        return self._work_dir + "/" + self._logname
+
     # Implement no-op XML methods
     def to_xml(self):
         return None
@@ -554,8 +561,17 @@
                                       "required to perform this operation." % \
                                       auth))
 
-    # raise error if euid is not 0 
+    # raise error if euid is not 0
     if os.geteuid() != 0:
         raise UnauthorizedUserError(_("Insufficient permission to perform "
                                       "operation.\neuid required to be "
                                       "0 to perform this operation."))
+
+
+def check_log_level(level):
+    """ Checks the log level being passed in"""
+    try:
+        logging.getLevelName(level)
+        return True
+    except NameError:
+        return False
--- a/usr/src/lib/install_doc/data_object/__init__.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_doc/data_object/__init__.py	Tue Jun 19 12:18:37 2012 -0600
@@ -21,7 +21,7 @@
 #
 
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 '''Provides definition of base classes for storage in Data Object Cache.
 '''
@@ -32,12 +32,14 @@
 import logging
 import re
 import sys
-from urllib import quote, unquote
 
 from abc import ABCMeta, abstractmethod
-
 from lxml import etree
 from solaris_install.logger import INSTALL_LOGGER_NAME
+from urllib import quote, unquote
+
+DEFAULTLOG = "/system/volatile/install_log"
+
 
 # Define various Data Object specific exceptions
 
@@ -118,10 +120,10 @@
         Mainly used for logging from class methods, so most will just use
         self.logger property if it's an object instance.
         '''
-        if cls.__logger is None:
-            cls.__logger = logging.getLogger(INSTALL_LOGGER_NAME)
-
-        return cls.__logger
+        if cls._DataObjectBase__logger is None:
+            cls._DataObjectBase__logger = \
+                 logging.getLogger(INSTALL_LOGGER_NAME)
+        return cls._DataObjectBase__logger
 
     @property
     def logger(self):
@@ -248,7 +250,7 @@
         root_object = self
         while root_object._parent is not None:
             root_object = root_object._parent
-                
+
         return root_object
 
     @property
--- a/usr/src/lib/install_engine/__init__.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_engine/__init__.py	Tue Jun 19 12:18:37 2012 -0600
@@ -21,7 +21,7 @@
 #
 
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
 '''
@@ -50,7 +50,7 @@
 from solaris_install.data_object.cache import DataObjectCache
 from solaris_install.engine.checkpoint_data import CheckpointData
 from solaris_install.logger import InstallLogger, LogInitError, \
-    INSTALL_LOGGER_NAME
+     INSTALL_LOGGER_NAME
 from solaris_install.target.logical import Filesystem
 
 LOGGER = None
@@ -166,8 +166,8 @@
         ''' thread used for execute_checkpoints() for the blocking case '''
         start = threading.Thread.run
 
-    def __new__(cls, default_log=None, loglevel=None, debug=False,
-                dataset=None, stop_on_error=True):
+    def __new__(cls, default_log, loglevel=None, debug=False,
+        exclusive_rw=False, dataset=None, stop_on_error=True):
 
         if InstallEngine._instance is None:
             return object.__new__(cls)
@@ -175,15 +175,13 @@
             raise SingletonError("InstallEngine instance already exists",
                                  InstallEngine._instance)
 
-    def __init__(self, default_log=None, loglevel=None, debug=False,
-                 dataset=None, stop_on_error=True):
+    def __init__(self, default_log, loglevel=None, debug=False,
+        exclusive_rw=False, dataset=None, stop_on_error=True):
         ''' Initializes the InstallEngine
 
         Input:
-            - default_log: Optional. Defaults to None.
-              The location of the default log for the application. If not
-              specified, the default log location is provided by the
-              logging service.
+            - default_log: Required. The location of the default log for
+              the application.
 
             - loglevel: Optional.  Defaults to None.
               Logging level to use for everything: application,
@@ -196,6 +194,10 @@
               removed from the directory defined to store temporary snapshots
               of DataObjectCache.
 
+            - exclusive_rw: Optional. Default to false.
+              If true, causes the default log file to be opened with exclusive
+              read/write privileges and restrictive access to the file.
+
             - Dataset: Optional.  Default to None.
               ZFS Dataset to be used by the engine to create ZFS snapshots
               and DataObjectCache snapshots for supporting stop and resume.
@@ -219,7 +221,7 @@
 
         # Logging must be instantiated before instantiating the DataObjectCache
         # because data object cache might need to make logging calls.
-        self._init_logging(default_log, loglevel)
+        self._init_logging(default_log, loglevel, exclusive_rw)
 
         # initialize the data object cache
         self.data_object_cache = DataObjectCache()
@@ -257,15 +259,14 @@
             shutil.rmtree(self._tmp_cache_path, ignore_errors=True)
         self._tmp_cache_path = None
 
-    def _init_logging(self, default_log, loglevel):
+    def _init_logging(self, default_log, loglevel, exclusive_rw):
         ''' Initialize logging and set the loglevel if provided '''
         logging.setLoggerClass(InstallLogger)
         global LOGGER
         LOGGER = InstallLogger.manager.getLogger(INSTALL_LOGGER_NAME,
-                                                 default_log)
+            log=default_log, level=loglevel, exclusive_rw=exclusive_rw)
         InstallLogger.ENGINE = self
-        if loglevel is not None:
-            LOGGER.setLevel(loglevel)
+
         if not isinstance(LOGGER, InstallLogger):
             # Occurs if some module has called logging.getLogger prior to
             # this function being run. As this means we don't have control
--- a/usr/src/lib/install_engine/test/engine_test_utils.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_engine/test/engine_test_utils.py	Tue Jun 19 12:18:37 2012 -0600
@@ -22,16 +22,17 @@
 #
 
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
 '''Some convenience functions that can be used by other test suites that use
    the engine in their testing
 '''
 
+import logging
 import os
-import logging
 import shutil
+import tempfile
 import solaris_install.engine as engine
 
 from solaris_install.logger import InstallLogger
@@ -39,16 +40,20 @@
 DEBUG_ENGINE = (os.environ.get("DEBUG_ENGINE", "false").lower() == "true")
 
 
-def get_new_engine_instance(doc_in_tmp=True):
+def get_new_engine_instance(doc_in_tmp=True, default_log=None):
     '''Returns a new install engine instance.  If an existing instance exists,
        it will be cleaned up.
     '''
 
     reset_engine()
-        
+
+    if not default_log:
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+
     engine.InstallEngine._instance = None
 
-    new_engine = engine.InstallEngine()
+    new_engine = engine.InstallEngine(default_log)
 
     new_engine.debug = DEBUG_ENGINE
 
@@ -62,8 +67,7 @@
 
 
 def reset_engine(old_engine=None):
-
-    ''' Clean up the engine for the tests ''' 
+    ''' Clean up the engine for the tests '''
 
     try:
         if old_engine is None:
@@ -79,6 +83,12 @@
 
     engine.InstallEngine._instance = None
 
+    try:
+        shutil.rmtree(os.path.dirname(
+                      InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+    except:
+        pass
+
     logging.Logger.manager.loggerDict = {}
 
     InstallLogger.DEFAULTFILEHANDLER = None
--- a/usr/src/lib/install_engine/test/test_engine.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_engine/test/test_engine.py	Tue Jun 19 12:18:37 2012 -0600
@@ -22,7 +22,7 @@
 #
 
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
 '''Some unit tests to cover engine functionality'''
@@ -31,6 +31,7 @@
 import os
 import sys
 import shutil
+import tempfile
 import threading
 import unittest
 import warnings
@@ -51,55 +52,58 @@
 _THIS_DIR = os.path.dirname(os.path.abspath(__file__))
 sys.path.append(_THIS_DIR)
 
+
 class MockDataset(object):
 
     ''' Fake Dataset object so the real ZFS dataset object does
         not need to be used for testing
     '''
-    
+
     def __init__(self, path):
         self.exists = True
         self.mountpoint = path
         self.snapped = (None, None)
         self.snapshot_list = []
-    
+
     def snapshot(self, name, overwrite=False):
         self.snapped = (name, overwrite)
-    
+
     def snapname(self, name):
         return self.mountpoint + '@' + name
-    
+
     def rollback(self, name, recursive=True):
         pass
 
     def get(self, property):
         return getattr(self, property)
 
+
 class MockDOC(object):
 
     ''' Fake DOC object so the real DataObjectCache object we do not rely
         on the actual DataObjectCache class for testing.
     '''
-    
+
     def take_snapshot(self, dummy):
         self.snapshotted = dummy
 
     def insert_children(self, dummy):
         pass
-    
+
     @property
     def persistent(self):
         return self
-    
+
     def get_first_child(self, name=None):
         return self
 
     def clear(self):
         pass
-    
+
     def load_from_snapshot(self, filename):
         self.loaded_from = filename
 
+
 class MockCheckpointRegData(DataObject):
 
     ''' Fake CheckpointRegData object so we do not rely on the actual
@@ -118,6 +122,7 @@
     def can_handle(cls, xml_node):
         return False
 
+
 class MockCheckpointData(object):
     ''' Fake CheckpointData object so we do not rely on the actual
         CheckpointData object for testing
@@ -127,20 +132,21 @@
         self.name = "MockCheckpointData"
         self.prog_reported = 0
         self.prog_est_ratio = 0
-    
+
+
 class EngineTest(unittest.TestCase):
 
     ''' Tests that validates the interfaces in the install engine code.
         All tests here do not require a user to be
         root to execute.
     '''
-    
+
     def setUp(self):
         self.callback_results = (None, None)
         self.callback_executed = threading.Event()
 
         self.engine = get_new_engine_instance()
-       
+
     def tearDown(self):
 
         # Force spawning of fresh singleton for each test.
@@ -149,7 +155,7 @@
 
         self.callback_results = None
         self.callback_executed = None
-    
+
     def _exec_cp_callback(self, status, errsvc):
         ''' Callback function for none-block execute_checkpoints() tests '''
 
@@ -166,7 +172,7 @@
         os.mkdir(self.cache_dir_name)
 
         for cp in cp_names:
-            file_name = os.path.join(self.cache_dir_name, 
+            file_name = os.path.join(self.cache_dir_name,
                            engine.InstallEngine.CACHE_FILE_NAME_PREFIX + cp)
             shutil.copyfile("/etc/hosts", file_name)
             self.full_cp_names.append(file_name)
@@ -175,146 +181,156 @@
         ''' Destroyes the fake DOC snapshots in /tmp used for testing '''
         shutil.rmtree(self.cache_dir_name)
 
+
 class SimpleEngineTests(EngineTest):
     '''Tests the less complicated engine functionality'''
-    
+
     def test_engine_is_singleton(self):
         engine.InstallEngine._instance = None
-        
+
         self.assertRaises(engine.SingletonError,
                           engine.InstallEngine.get_instance)
-        
-        install_engine = engine.InstallEngine()
+
+        log_tmp_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        log_tmp_file = log_tmp_dir + "/install_log"
+
+        install_engine = engine.InstallEngine(log_tmp_file)
         self.assertTrue(isinstance(install_engine, engine.InstallEngine))
-        
-        self.assertRaises(engine.SingletonError, engine.InstallEngine)
-        
+
+        self.assertRaises(engine.SingletonError, engine.InstallEngine,
+                          "secondlog")
+
         engine_instance = engine.InstallEngine.get_instance()
         self.assertTrue(install_engine is engine_instance)
-    
+
+        try:
+            shutil.rmtree(os.path.dirname(log_tmp_file))
+        except:
+            pass
+
     def test_check_callback_None(self):
         '''Assert InstallEngine._check_callback accepts None '''
         try:
             self.engine._check_callback(None)
         except TypeError:
             self.fail("Engine did not accept 'None' for callback")
-    
+
     def test_check_callback_varargs(self):
         '''Assert InstallEngine._check_callback accepts a vararg function'''
         def vararg_func(*args):
             pass
-        
+
         try:
             self.engine._check_callback(vararg_func)
         except TypeError:
             self.fail("Engine did not accept function with *args param")
-    
+
     def test_check_callback_two_args(self):
         '''Assert InstallEngine._check_callback accepts a two argument function'''
         def arg_func(arg1, arg2):
             pass
-        
+
         try:
             self.engine._check_callback(arg_func)
         except TypeError:
             self.fail("Engine did not accept function with exactly two args")
-    
+
     def test_check_callback_under_two_args(self):
         '''Asserts InstallEngine._check_callback fails on a single argument function'''
         def arg_func(arg1):
             pass
-        
+
         self.assertRaises(TypeError, self.engine._check_callback, arg_func)
-    
+
     def test_check_callback_over_two_required_args(self):
         '''Asserts InstallEngine._check_callback fails if 3 or more args are required'''
         def arg_func(arg1, arg2, arg3):
             pass
-        
+
         self.assertRaises(TypeError, self.engine._check_callback, arg_func)
-    
+
     def test_check_callback_with_kwargs(self):
         '''Asserts InstallEngine._check_callback handles functions with keyword args'''
         def kwarg_func_all(arg1=None, arg2=None, arg3=None):
             pass
-        
+
         try:
             self.engine._check_callback(kwarg_func_all)
         except TypeError:
             self.fail("Engine did not accept function with kwargs for all"
                       "arguments")
-    
+
     def test_check_callback_2_arg_optional_kwarg(self):
         '''Asserts InstallEngine._check_callback handles a function with an optional keyword argument'''
         def optional_kwarg(arg1, arg2, arg3=None):
             pass
-        
+
         try:
             self.engine._check_callback(optional_kwarg)
         except TypeError:
             self.fail("Engine did not accept function with optional kwarg")
-    
+
     def test_check_callback_bound_class_method(self):
         '''Asserts InstallEngine._check_callback handles bound class methods'''
         class DummyClass(object):
             def callback(self, status, errsvc):
                 pass
-        
+
         instance = DummyClass()
-        
+
         try:
             self.engine._check_callback(instance.callback)
         except TypeError:
             self.fail("Engine did not accept bound class method")
-    
+
     def test_check_callback_unbound_class_method(self):
         '''Asserts InstallEngine._check_callback rejects unbound class methods.
         (Unbound methods require a class instance as the first argument)'''
         class DummyClass(object):
             def callback(self, status, errsvc):
                 pass
-        
+
         self.assertRaises(TypeError, self.engine._check_callback,
                           DummyClass.callback)
 
     def test_snapshot_tmp_no_dataset(self):
         self.engine._dataset = None
         self.engine.data_object_cache = MockDOC()
-        
+
         cp_data = MockCheckpointData()
-        
+
         self.engine.snapshot(cp_data=cp_data)
-        
+
         self.assertEqual(cp_data.zfs_snap, None)
         self.assertEqual(self.engine.doc.snapshotted,
                          cp_data.data_cache_path,
                          "DOC path for Checkpoint not set")
-    
+
     def test_snapshot_tmp_dataset_no_exist(self):
         ds = MockDataset("mock")
         self.engine._dataset = ds
         self.engine.dataset.exists = False
         self.engine.data_object_cache = MockDOC()
-        
+
         cp_data = MockCheckpointData()
-        
+
         self.engine.snapshot(cp_data=cp_data)
-        
+
         self.assertEqual(cp_data.zfs_snap, None)
         self.assertEqual(self.engine.doc.snapshotted,
                          cp_data.data_cache_path,
                          "DOC path for Checkpoint not set")
-    
+
     def test_snapshot_zfs_dataset_exists(self):
         ds = MockDataset("mock")
         self.engine._dataset = ds
         self.engine.dataset.exists = True
         self.engine.data_object_cache = MockDOC()
-        
+
         cp_data = MockCheckpointData()
-        
+
         self.engine.snapshot(cp_data=cp_data)
-        
+
         self.assertEqual(cp_data.zfs_snap, ds.snapped[0])
         self.assertEqual(self.engine.doc.snapshotted,
                          cp_data.data_cache_path,
@@ -542,7 +558,7 @@
         '''Test that rollbacks fail when the cache doesn't exist'''
         cp = self.engine._checkpoints[0]
         cp.completed = True
-        cp.data_cache_path = os.tempnam() # Guaranteed to not exist yet
+        cp.data_cache_path = os.tempnam()  # Guaranteed to not exist yet
         self.engine.data_object_cache = MockDOC()
         
         self.assertRaises(engine.NoCacheError, self.engine._rollback, cp.name)
@@ -839,7 +855,7 @@
         self.assertNotEqual(cp, None)
         self.assertEqual(cp.name, expected_failed_cp[0])
 
-    def test_nothing_to_exec(self): 
+    def test_nothing_to_exec(self):
         '''Validate a warning is issued when there's no checkpoint to execute'''
         with warnings.catch_warnings(record=True) as w:
             self.engine.execute_checkpoints(start_from="one",
@@ -861,6 +877,7 @@
 
         self.assertEqual(path_result, cache_path_env)
 
+
 class EngineRegisterTests(EngineTest):
 
     def setUp(self):
@@ -885,14 +902,13 @@
                                    self.cp_mod_path, "EmptyCheckpoint", None,
                                    None, None)
             self.test_chkpt_list.append(chkpt)
-            
 
     def check_result(self, expected_list):
 
         self.assertEquals(len(expected_list), len(self.engine._checkpoints))
 
         for expected_data, cp_data in zip(expected_list,
-                                          self.engine._checkpoints):  
+                                          self.engine._checkpoints):
 
             self.assertEquals(cp_data.cp_info.cp_name,
                               expected_data.cp_info.cp_name,
@@ -1035,7 +1051,7 @@
 
         self.assertRaises(ImportError,
                           self.engine.register_checkpoint, chkpt.name,
-                          chkpt.cp_info.mod_name+"/junk", 
+                          chkpt.cp_info.mod_name+"/junk",
                           chkpt.cp_info.checkpoint_class_name)
 
         self.check_result([])
@@ -1410,6 +1426,7 @@
 
         self.check_result([chkpt])
 
+
 class EngineCancelTests(EngineCheckpointsBase):
     '''Test InstallEngine.cancel_checkpoints(...) scenarios'''
     
@@ -1467,7 +1484,7 @@
         # register a checkpoint that looks for the cancel flag
         self.reg_cancel_checkpoint()
 
-        # Call cancel_checkpoints 
+        # Call cancel_checkpoints
         self.engine.cancel_checkpoints()
 
         # Make sure the cancel checkpoint is not executed
@@ -1493,7 +1510,6 @@
         except Exception, ex:
             self.fail("cancel checkpoint failed after execute completed")
 
-
     def test_exec_after_cancel(self):
         '''Verify execute_checkpoint() works correctly after cancel_checkpoints is called. '''
 
--- a/usr/src/lib/install_logging_pymod/logger.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_logging_pymod/logger.py	Tue Jun 19 12:18:37 2012 -0600
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 ''' Code specific for the implementation of the InstallLogger'''
 import errno
@@ -32,8 +32,6 @@
 import time
 
 # Global variables
-_PID = str(os.getpid())
-DEFAULTLOG = '/var/tmp/install/default_log' + '.' + _PID
 DEFAULTPROGRESSFORMAT = '%(progress)s %(msg)s'
 DEFAULTLOGLEVEL = logging.DEBUG
 DEFAULTDESTINATION = '/var/tmp/install/dest'
@@ -47,11 +45,27 @@
        of allowing applications to pass in a default log rather than
        using the default log provided by the installLogger class.
     '''
-    def getLogger(self, name, default_log=None):
+    def getLogger(self, name, log=None, level=None, exclusive_rw=False):
         """
-        This getLogger method allows the application to pass in a name,
-        a default log, and a logging level. These values are passed to
-        the InstallLogger to set up a custom default log file.
+        This getLogger method allows the application to pass in the following
+        input:
+
+        - name: Required. The name of the logger
+
+        - log: Optional. If a default log is included, it will be set
+          up as the default log location for the logging process.
+
+        - level: Optional. This value may be set for a default log
+          file. If it is not set, the logger sets to DEBUG as the default
+          value. The format of the level should follow the format of
+          the logging module. For example, logging.DEBUG, logging.INFO.
+
+        - exclusive_rw - Optional. Opens the file in a more secure mode. It
+          ensures safe log file creation and gives the file restrictive
+          permissions. If it is not set, it defaults to False.
+
+        These values are passed to the InstallLogger to set up a custom default
+        log file.
 
         The placeholder code is an adjunct to the python logging module.
         It is used to manage the logging hierarchy. Because this getLogger
@@ -66,13 +80,15 @@
                 if isinstance(logger_name, logging.PlaceHolder):
                     placeholder_for_fixup = logger_name
                     logger_name = \
-                        logging._loggerClass(name, default_log)
+                        logging._loggerClass(name, default_log=log,
+                            level=level, exclusive_rw=exclusive_rw)
                     logger_name.manager = self
                     logging.Logger.manager.loggerDict[name] = logger_name
                     self._fixupChildren(placeholder_for_fixup, logger_name)
                     self._fixupParents(logger_name)
             else:
-                logger_name = logging._loggerClass(name, default_log)
+                logger_name = logging._loggerClass(name, default_log=log,
+                    level=level, exclusive_rw=exclusive_rw)
                 logger_name.manager = self
                 logging.Logger.manager.loggerDict[name] = logger_name
                 self._fixupParents(logger_name)
@@ -123,15 +139,24 @@
        directory exists, so the check is done here.
     '''
 
-    def __init__(self, filename, mode='a', encoding=None, delay=0):
+    def __init__(self, filename, mode='a', encoding=None, delay=0,
+        exclusive_rw=False):
         if not os.path.exists(os.path.dirname(filename)):
             os.makedirs(os.path.dirname(filename), mode=0777)
 
+        if exclusive_rw:
+            delay = True
+
         # The mode may be set differently by the consumer, so
         # it should be passed through to the constructor.
         logging.FileHandler.__init__(self, filename, mode=mode,
             encoding=encoding, delay=delay)
 
+        if exclusive_rw:
+            fd = os.open(self.baseFilename,
+                os.O_CREAT | os.O_EXCL | os.O_RDWR, 0644)
+            self.stream = os.fdopen(fd, mode)
+
     def transfer_log(self, destination, isdir=False):
         ''' transfer_log() - method to move the log from its original location
             to the location specified in the destination variable
@@ -268,17 +293,25 @@
     INSTALL_FORMAT = '%(asctime)-25s %(name)-10s ' \
         '%(levelname)-10s %(message)-50s'
 
-    def __init__(self, name, default_log=None, level=None):
+    def __init__(self, name, default_log=None, level=None, exclusive_rw=False):
         # If logging level was not provided, choose the desired default one.
         # Use DEFAULTLOGLEVEL for top level logger, while default to
         # logging.NOTSET for sub-loggers. That instructs Python logging to
         # inherit logging level from parent.
 
-        if default_log is None:
-            self.default_log_file = DEFAULTLOG
-        else:
+        self.default_log_file = None
+        self._prog_filter = ProgressFilter(log_progress=True)
+        self._no_prog_filter = ProgressFilter(log_progress=False)
+
+        if InstallLogger.DEFAULTFILEHANDLER is not None:
+            logging.Logger.__init__(self, name)
+            return
+
+        if not InstallLogger.DEFAULTFILEHANDLER and default_log:
             self.default_log_file = default_log
 
+        self.exclusive_rw = exclusive_rw
+
         if level is None:
             if "." in name:
                 level = logging.NOTSET
@@ -286,8 +319,6 @@
                 level = DEFAULTLOGLEVEL
 
         logging.Logger.__init__(self, name, level=level)
-        self._prog_filter = ProgressFilter(log_progress=True)
-        self._no_prog_filter = ProgressFilter(log_progress=False)
 
         # MAX_INT is the level that is associated with progress
         # reporting. The following commands add MAX_INT to the
@@ -296,11 +327,9 @@
         logging.addLevelName('MAX_INT', MAX_INT)
 
         # Initialize the default log.
-        if not InstallLogger.DEFAULTFILEHANDLER:
+        if not InstallLogger.DEFAULTFILEHANDLER and self.default_log_file:
             logdir = os.path.dirname(self.default_log_file)
 
-            # Make sure default log file is usable by everyone,
-            # even if created by root.
             if not os.path.exists(logdir):
                 try:
                     os.makedirs(logdir)
@@ -308,12 +337,15 @@
                     if err.errno != errno.EEXIST:
                         raise
 
+                # Make sure default log file is usable by everyone,
+                # even if created by root.
                 statbuf = os.stat(logdir)
                 if (statbuf.st_mode & 01777) != 01777:
                     os.chmod(logdir, 01777)
 
             InstallLogger.DEFAULTFILEHANDLER = \
-                FileHandler(filename=self.default_log_file, mode='a')
+                FileHandler(filename=self.default_log_file, mode='a',
+                    exclusive_rw=self.exclusive_rw)
             InstallLogger.DEFAULTFILEHANDLER.setLevel(level)
             InstallLogger.DEFAULTFILEHANDLER.setFormatter(InstallFormatter())
             logging.Logger.addHandler(self, InstallLogger.DEFAULTFILEHANDLER)
@@ -322,13 +354,18 @@
     @property
     def default_log(self):
         '''Returns the name of the default log '''
-        return self.default_log_file
+        return InstallLogger.DEFAULTFILEHANDLER.baseFilename
 
     @property
     def name(self):
         '''returns the name of the logger'''
         return self.name
 
+    @property
+    def default_fh(self):
+        '''returns the default FileHandler for the logging process'''
+        return InstallLogger.DEFAULTFILEHANDLER
+
     def addHandler(self, handler):
         '''Adds the requested handler to the InstallLogger
            Performs special handling if it is a progress handler
--- a/usr/src/lib/install_logging_pymod/test/test_logger.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_logging_pymod/test/test_logger.py	Tue Jun 19 12:18:37 2012 -0600
@@ -19,27 +19,30 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
-
 import solaris_install.logger
 import logging
 import os
 import random
+import shutil
+import socket
+import struct
+import sys
 import tempfile
 import thread
 import time
 import unittest
-from solaris_install.logger import InstallLogger, LogInitError
-import socket
-import struct
-import sys
+
+from solaris_install.logger import InstallLogger, LogInitError, \
+    INSTALL_LOGGER_NAME
+from solaris_install.engine.test.engine_test_utils import \
+    get_new_engine_instance
 
 LOGGER = None
-INSTALL_LOGGER_NAME = 'InsLggr'
 TEST_LOG = 'test_log'
 
-#A Simple Socket Receiver for Testing
+# A Simple Socket Receiver for Testing
 
 
 def parse_msg(the_socket, cb_function):
@@ -103,7 +106,7 @@
 
     _instance = None
 
-    def __new__(cls, default_log=None):
+    def __new__(cls, default_log):
 
         if TestInstallEngine._instance is None:
             TestInstallEngine._instance = object.__new__(cls)
@@ -112,7 +115,7 @@
             raise SingletonError("TestInstallEngine instance already exists",
                                  TestInstallEngine._instance)
 
-    def __init__(self, default_log=None):
+    def __init__(self, default_log):
         self._init_logging(default_log)
 
     def _init_logging(self, default_log):
@@ -120,7 +123,8 @@
         logging.setLoggerClass(InstallLogger)
         global LOGGER
         InstallLogger.ENGINE = self
-        LOGGER = InstallLogger.manager.getLogger(INSTALL_LOGGER_NAME, default_log)
+        LOGGER = InstallLogger.manager.getLogger(INSTALL_LOGGER_NAME,
+            log=default_log)
         LOGGER.setLevel(logging.DEBUG)
 
         if not isinstance(LOGGER, InstallLogger):
@@ -133,19 +137,52 @@
         return overall_progress
 
 
+class TestSimpleInstallLogger(unittest.TestCase):
+    '''Tests the InstallLogger outside of the InstallEngine'''
+
+    def tearDown(self):
+        InstallLogger.DEFAULTFILEHANDLER = None
+        logging.Logger.manager.loggerDict = {}
+        logging.setLoggerClass(logging.Logger)
+        logging._defaultFormatter = logging.Formatter()
+
+    def test_no_default_logfile(self):
+        '''Test that the logger does not fail with no default log'''
+        logging.setLoggerClass(InstallLogger)
+        LOGGER = InstallLogger.manager.getLogger(INSTALL_LOGGER_NAME)
+        self.failIf(not LOGGER.DEFAULTFILEHANDLER == None)
+
+    def test_no_default_fh(self):
+        '''Test that logging can be set up a user create FileHandler'''
+        logging.setLoggerClass(InstallLogger)
+        LOGGER = InstallLogger.manager.getLogger(INSTALL_LOGGER_NAME)
+        self.log_tmp_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        self.logfile = os.path.join(self.log_tmp_dir, TEST_LOG)
+
+        fh = logging.FileHandler(self.logfile)
+        LOGGER.addHandler(fh)
+        LOGGER.info('This is from the logger')
+        logtext = open(self.logfile).read()
+        logsearch = "This is from the logger"
+        index = logtext.find(logsearch)
+        self.assertNotEqual(index, -1, 'message is not in default log and' \
+            ' should be')
+
+
 class TestInstallLogger(unittest.TestCase):
     '''Tests the Functionality of the InstallLogger subclass'''
 
     def setUp(self):
+
+        self.log_tmp_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        self.logfile = os.path.join(self.log_tmp_dir, TEST_LOG)
         self.pid = str(os.getpid())
-        self.eng = TestInstallEngine()
-        self.test_logger = logging.getLogger('InsLggr.TestLogger')
-        self.logfile = None
+        self.eng = get_new_engine_instance(default_log=self.logfile)
+        self.test_logger = logging.getLogger(INSTALL_LOGGER_NAME)
         self.list = []
 
     def tearDown(self):
         self.eng = None
-        TestInstallEngine._instance = None
         InstallLogger.DEFAULTFILEHANDLER = None
         logging.Logger.manager.loggerDict = {}
         logging.setLoggerClass(logging.Logger)
@@ -153,7 +190,7 @@
         logging._defaultFormatter = logging.Formatter()
 
         try:
-            os.remove(solaris_install.logger.DEFAULTLOG)
+            shutil.rmtree(self.log_tmp_dir)
         except:
             # File doesn't exist
             pass
@@ -202,12 +239,12 @@
     def test_get_default_log(self):
         '''Ensure that default log is returned with default_log method'''
         dlog = self.test_logger.default_log
-        self.failIf(dlog != solaris_install.logger.DEFAULTLOG)
+        self.failIf(dlog != self.logfile)
 
     def test_get_log_name(self):
         '''Ensure that logger name is returned correctly'''
         logName = self.test_logger.name
-        self.failIf(logName != "InsLggr.TestLogger")
+        self.failIf(logName != INSTALL_LOGGER_NAME)
 
     def test_create_second_logger_instance(self):
         '''Ensure that only one InstallLogger is created for Install Logger'''
@@ -217,8 +254,7 @@
         self.second_logger.addHandler(fh)
         self.second_logger.info('This is from the second logger')
 
-        logfile = solaris_install.logger.DEFAULTLOG
-        logtext = open(logfile).read()
+        logtext = open(self.logfile).read()
         logsearch = "This is from the second logger"
         index = logtext.find(logsearch)
         self.assertEqual(index, -1, 'message is in default log and \
@@ -226,20 +262,22 @@
 
     def test_add_FileHandler(self):
         '''Ensure that FileHandlers can be added to a logger'''
-        fh = solaris_install.logger.FileHandler('/var/tmp/install/fhtest')
+        sec_log = os.path.join(self.log_tmp_dir, 'fhtest')
+        fh = solaris_install.logger.FileHandler(sec_log)
         fh.setLevel(logging.CRITICAL)
         self.test_logger.addHandler(fh)
-        self.failIf(not os.path.exists('/var/tmp/install/fhtest'))
+        self.failIf(not os.path.exists(sec_log))
 
     def test_exclude_log_message(self):
         '''Ensure that a log message below the designated level does not log'''
-        fh = solaris_install.logger.FileHandler('/var/tmp/install/fhtest')
+        sec_log = os.path.join(self.log_tmp_dir, 'fhtest')
+        fh = solaris_install.logger.FileHandler(sec_log)
         fh.setLevel(logging.CRITICAL)
         self.test_logger.addHandler(fh)
-        self.failIf(not os.path.exists('/var/tmp/install/fhtest'))
+        self.failIf(not os.path.exists(sec_log))
         self.test_logger.critical('critical message')
         self.test_logger.debug('debug message')
-        logtext = open('/var/tmp/install/fhtest').read()
+        logtext = open(sec_log).read()
         logsearch = "critical message"
         index = logtext.find(logsearch)
         self.assertNotEqual(-1, index, \
@@ -265,13 +303,12 @@
 
     def test_create_defaultlog(self):
         '''Ensure default_log is created and uses the default format.'''
-        self.failIf(not os.path.exists(solaris_install.logger.DEFAULTLOG))
+        self.failIf(not os.path.exists(self.logfile))
 
     def test_log_debug_message(self):
         '''Ensure that debug log messages are logged to the log file'''
         self.test_logger.debug('This is a debug message')
-        logfile = solaris_install.logger.DEFAULTLOG
-        logtext = open(logfile).read()
+        logtext = open(self.logfile).read()
         logsearch = "This is a debug message"
         index = logtext.find(logsearch)
         self.assertNotEqual(-1, index, \
@@ -280,8 +317,7 @@
     def test_log_warning_message(self):
         '''Ensure that warning log messages are logged to the log file'''
         self.test_logger.warning('This is a warning message')
-        logfile = solaris_install.logger.DEFAULTLOG
-        logtext = open(logfile).read()
+        logtext = open(self.logfile).read()
         logsearch = "This is a warning message"
         index = logtext.find(logsearch)
         self.assertNotEqual(-1, index, \
@@ -290,8 +326,7 @@
     def test_log_info_message(self):
         '''Ensure that info log messages are logged to the log file'''
         self.test_logger.info('This is an info message')
-        logfile = solaris_install.logger.DEFAULTLOG
-        logtext = open(logfile).read()
+        logtext = open(self.logfile).read()
         logsearch = "This is an info message"
         index = logtext.find(logsearch)
         self.assertNotEqual(-1, index, \
@@ -304,29 +339,35 @@
 
     def test_transfer_log_destonly(self):
         '''Ensure that default log transfers to destination'''
-        dest_dir = "/var/tmp/installLog/"
+
+        dest_dir = "/tmp/installLog/"
         if not os.path.exists(dest_dir):
             os.mkdir(dest_dir)
 
-        base_name = os.path.basename(solaris_install.logger.DEFAULTLOG)
-        test_filename = "/var/tmp/installLog/" + base_name
+        base_name = os.path.basename(self.logfile)
+        test_filename = "/tmp/installLog/" + base_name
         self.test_logger.transfer_log(destination=dest_dir)
         self.failIf(not os.path.exists(test_filename))
 
-    def test_close(self):
-        '''Ensure that InstallLogger close works'''
-        test_list = ['/var/tmp/install/default_log.' + self.pid]
-        test_close_list = self.test_logger.close()
-        self.assertEquals(test_list, test_close_list)
+#    This test is commented out because it is causing
+#    nose test failures.
+#    CR 7177859 has been filed to track this issue.
+#    def test_close(self):
+#        '''Ensure that InstallLogger close works'''
+#        test_list = [self.logfile]
+#        test_close_list = self.test_logger.close()
+#        self.assertEquals(test_list, test_close_list)
 
 
 class TestProgressHandler(unittest.TestCase):
     '''Tests the Functionality of the ProgressHandler'''
 
     def setUp(self):
+        self.log_tmp_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        self.logfile = os.path.join(self.log_tmp_dir, TEST_LOG)
         self.pid = str(os.getpid())
-        self.eng = TestInstallEngine()
-        self.test_logger = logging.getLogger('InsLggr.TestLogger')
+        self.eng = TestInstallEngine(self.logfile)
+        self.test_logger = logging.getLogger(INSTALL_LOGGER_NAME)
 
         # Create parameters for the progress receiver
         random.seed()
@@ -363,7 +404,7 @@
         logging._defaultFormatter = logging.Formatter()
 
         try:
-            os.remove(solaris_install.logger.DEFAULTLOG)
+            shutil.rmtree(self.log_tmp_dir)
         except OSError:
             # File doesn't exist
             pass
@@ -418,8 +459,7 @@
         self.test_logger.report_progress( \
             'this is a progress message with percentage 10', progress=10)
 
-        logfile = solaris_install.logger.DEFAULTLOG
-        logtext = open(logfile).read()
+        logtext = open(self.logfile).read()
         logsearch = "PROGRESS REPORT: progress percent:0.1" + \
             " this is a progress message with percentage 10"
         index = logtext.find(logsearch)
--- a/usr/src/lib/install_transfer/test/test_cpio.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_transfer/test/test_cpio.py	Tue Jun 19 12:18:37 2012 -0600
@@ -44,8 +44,9 @@
 
 import logging
 import os
+import shutil
+import tempfile
 import unittest
-import shutil
 
 
 class TestCPIOFunctions(unittest.TestCase):
@@ -60,7 +61,10 @@
 
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
         self.soft_node = Software("CPIO_Transfer", "CPIO")
@@ -93,6 +97,15 @@
         InstallEngine._instance = None
         TEST_CONTENTS_LIST = []
 
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
     def test_software_type(self):
         self.assertTrue(self.soft_node.tran_type == "CPIO")
 
--- a/usr/src/lib/install_transfer/test/test_info.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_transfer/test/test_info.py	Tue Jun 19 12:18:37 2012 -0600
@@ -26,9 +26,14 @@
 
 '''Tests for the Transfer Info interface'''
 
+import logging
+import os
+import shutil
+import tempfile
 import unittest
 from pkg.client.api import IMG_TYPE_PARTIAL
 from solaris_install.engine import InstallEngine
+from solaris_install.logger import InstallLogger
 from solaris_install.transfer.info import Args
 from solaris_install.transfer.info import CPIOSpec
 from solaris_install.transfer.info import Destination
@@ -47,7 +52,9 @@
 class TestCPIOInfoFunctions(unittest.TestCase):
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
 
@@ -57,6 +64,15 @@
         self.engine = None
         self.doc = None
 
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
     def test_info(self):
         '''Test that all the arguments get into the node correctly'''
         soft_node = Software("CPIO transfer test 1")
@@ -285,7 +301,9 @@
 
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
 
@@ -295,6 +313,15 @@
         self.engine = None
         self.doc = None
 
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
     def test_name(self):
         '''Test that names are populated correctly in the Software node'''
         ips_node = Software("transfer 1")
@@ -733,7 +760,9 @@
 
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
 
@@ -743,6 +772,15 @@
         self.engine = None
         self.doc = None
 
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
     def test_file_name(self):
         '''Test that Origin is set correctly in the node'''
         p5i_node = Software("transfer 1")
@@ -765,7 +803,9 @@
 class TestSVR4InfoFunctions(unittest.TestCase):
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
 
@@ -775,6 +815,15 @@
         self.engine = None
         self.doc = None
 
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
     def test_info(self):
         '''Test that all the arguments get into the node correctly'''
         soft_node = Software("SVR4 transfer test 1")
--- a/usr/src/lib/install_transfer/test/test_ips.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_transfer/test/test_ips.py	Tue Jun 19 12:18:37 2012 -0600
@@ -24,10 +24,15 @@
 # Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
+import logging
+import os
+import shutil
+import tempfile
 import unittest
 import pkg.client.progress as progress
 
 from solaris_install.engine import InstallEngine
+from solaris_install.logger import InstallLogger
 from solaris_install.transfer.info import Args
 from solaris_install.transfer.info import Destination
 from solaris_install.transfer.info import Facet
@@ -253,7 +258,9 @@
 
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
         self.soft_node = Software("IPS transfer")
@@ -276,6 +283,15 @@
         self.tr_ips = None
         self.engine = None
 
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
     def test_create(self):
         '''Test that the IPS Transfer object is created'''
         try:
--- a/usr/src/lib/install_transfer/test/test_misc_transfer.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_transfer/test/test_misc_transfer.py	Tue Jun 19 12:18:37 2012 -0600
@@ -21,13 +21,18 @@
 #
 
 #
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
 '''Tests for the Transfer Info interface'''
 
+import logging
+import os
+import shutil
+import tempfile
 import unittest
 from solaris_install.engine import InstallEngine
+from solaris_install.logger import InstallLogger
 from solaris_install.transfer.info import Software
 import solaris_install.transfer as Transfer
 
@@ -35,7 +40,9 @@
 class TestCreateCheckpoint(unittest.TestCase):
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
 
@@ -45,6 +52,15 @@
         self.engine = None
         self.doc = None
 
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
     def test_create_cpio_chkpt(self):
         '''Test create_checkpoint correctly returns cpio values'''
 
--- a/usr/src/lib/install_transfer/test/test_p5i.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_transfer/test/test_p5i.py	Tue Jun 19 12:18:37 2012 -0600
@@ -19,11 +19,13 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
 import os
 import logging
+import shutil
+import tempfile
 import unittest
 
 from solaris_install.engine import InstallEngine
@@ -56,7 +58,9 @@
 
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
         self.soft_node = Software("P5I transfer")
@@ -70,6 +74,15 @@
     def tearDown(self):
         self.engine.data_object_cache.clear()
         InstallEngine._instance = None
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
         self.doc = None
         self.soft_node = None
         self.tr_node = None
--- a/usr/src/lib/install_transfer/test/test_svr4.py	Tue Jun 19 02:42:18 2012 -0600
+++ b/usr/src/lib/install_transfer/test/test_svr4.py	Tue Jun 19 12:18:37 2012 -0600
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 #
 
 import logging
 import os
 import shutil
+import tempfile
 import unittest
 
 from solaris_install.engine import InstallEngine
@@ -52,7 +53,9 @@
 
     def setUp(self):
         InstallEngine._instance = None
-        InstallEngine()
+        default_log_dir = tempfile.mkdtemp(dir="/tmp", prefix="logging_")
+        default_log = default_log_dir + "/install_log"
+        InstallEngine(default_log)
         self.engine = InstallEngine.get_instance()
         self.doc = self.engine.data_object_cache.volatile
         self.soft_node = Software("SVR4Transfer", "SVR4")
@@ -70,6 +73,15 @@
         self.engine.data_object_cache.clear()
         self.doc = None
         self.engine = None
+        try:
+            shutil.rmtree(os.path.dirname(
+                InstallLogger.DEFAULTFILEHANDLER.baseFilename))
+        except:
+            pass
+
+        logging.Logger.manager.loggerDict = {}
+        InstallLogger.DEFAULTFILEHANDLER = None
+
         self.soft_node = None
         self.tr_node = None
         self.tr_svr4 = None