]> Frank Brehm's Git Trees - pixelpark/admin-tools.git/commitdiff
Rewritten Cleaning up
authorFrank Brehm <frank.brehm@pixelpark.com>
Thu, 10 Aug 2017 10:07:08 +0000 (12:07 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Thu, 10 Aug 2017 10:07:08 +0000 (12:07 +0200)
pp_lib/config_named_app.py

index e22b5e7f13da18aabcf865858134497e7eddabf3..ef8dfc1a570bbbac717fac6aac4b852cec0eddf5 100644 (file)
@@ -30,6 +30,7 @@ import shutil
 
 # Third party modules
 import six
+from six import reraise
 import requests
 
 from six.moves.urllib.parse import urlunsplit
@@ -41,7 +42,7 @@ from .cfg_app import PpCfgAppError, PpConfigApplication
 
 from .pidfile import PidFileError, InvalidPidFileError, PidFileInUseError, PidFile
 
-__version__ = '0.6.5'
+__version__ = '0.6.6'
 LOG = logging.getLogger(__name__)
 
 
@@ -281,6 +282,7 @@ class PpConfigNamedApp(PpConfigApplication):
         self.temp_acl_cfg_file = None
         self.temp_log_cfg_file = None
         self.temp_zones_cfg_file = None
+        self.keep_tempdir = False
 
         self.backup_suffix = (
             '.' + datetime.datetime.utcnow().strftime('%Y-%m-%d_%H-%M-%S') + '.bak')
@@ -526,6 +528,13 @@ class PpConfigNamedApp(PpConfigApplication):
             help="Disabling query logging in the named configuration.",
         )
 
+        self.arg_parser.add_argument(
+            '-K', '--keep-tempdir', dest='keep_tempdir', action='store_true',
+            help=(
+                "Keeping the temporary directory instead of removing it at the end "
+                "(e.g. for debugging purposes)"),
+        )
+
     # -------------------------------------------------------------------------
     def perform_config(self):
 
@@ -567,6 +576,8 @@ class PpConfigNamedApp(PpConfigApplication):
         elif hasattr(self.args, 'no_querylog') and self.args.no_querylog:
             self.query_log = False
 
+        self.keep_tempdir = getattr(self.args, 'keep_tempdir', False)
+
     # -------------------------------------------------------------------------
     def set_api_options(self, section, section_name):
 
@@ -833,13 +844,15 @@ class PpConfigNamedApp(PpConfigApplication):
             self.create_temp_files()
             self.compare_files()
             self.check_directories()
-            self.replace_configfiles()
+
+            try:
+                self.replace_configfiles()
+            except Exception:
+                self.restore_configfiles()
+                raise
 
         finally:
-            if self.tempdir:
-                LOG.debug("Destroying temporary directory {!r} ...".format(self.tempdir.name))
-                self.tempdir.cleanup()
-                self.tempdir = None
+            self.cleanup()
             self.pidfile = None
 
     # -------------------------------------------------------------------------
@@ -856,19 +869,19 @@ class PpConfigNamedApp(PpConfigApplication):
     def init_temp_objects(self):
         """Init temporary objects and properties."""
 
-        self.tempdir = tempfile.TemporaryDirectory(
+        self.tempdir = tempfile.mkdtemp(
             prefix=(self.appname + '.'), suffix='.tmp.d'
         )
-        LOG.debug("Temporary directory: {!r}.".format(self.tempdir.name))
+        LOG.debug("Temporary directory: {!r}.".format(self.tempdir))
 
         self.temp_named_conf = os.path.join(
-            self.tempdir.name, self.default_named_conf)
+            self.tempdir, self.default_named_conf)
         self.temp_acl_cfg_file = os.path.join(
-            self.tempdir.name, self.default_named_acl_cfg_file)
+            self.tempdir, self.default_named_acl_cfg_file)
         self.temp_log_cfg_file = os.path.join(
-            self.tempdir.name, self.default_named_log_cfg_file)
+            self.tempdir, self.default_named_log_cfg_file)
         self.temp_zones_cfg_file = os.path.join(
-            self.tempdir.name, self.default_named_zones_cfg_file)
+            self.tempdir, self.default_named_zones_cfg_file)
 
         if self.verbose > 1:
             LOG.debug("Temporary named.conf: {!r}".format(self.temp_named_conf))
@@ -1604,19 +1617,66 @@ class PpConfigNamedApp(PpConfigApplication):
         for tgt_file in self.files2replace.keys():
 
             backup_file = tgt_file + self.backup_suffix
-            self.moved_files[tgt_file] = backup_file
 
             if os.path.exists(tgt_file):
+                self.moved_files[tgt_file] = backup_file
                 LOG.info("Copying {!r} => {!r} ...".format(tgt_file, backup_file))
                 if not self.simulate:
                     shutil.copy2(tgt_file, backup_file)
 
+        if self.verbose > 1:
+            LOG.debug("All backuped config files:\n{}".format(pp(self.moved_files)))
+
         for tgt_file in self.files2replace.keys():
             src_file = self.files2replace[tgt_file]
             LOG.info("Copying {!r} => {!r} ...".format(src_file, tgt_file))
             if not self.simulate:
                 shutil.copy2(src_file, tgt_file)
 
+    # -------------------------------------------------------------------------
+    def restore_configfiles(self):
+
+        LOG.error("Restoring of original config files because of an exception.")
+
+        for tgt_file in self.moved_files.keys():
+            backup_file = self.moved_files[tgt_file]
+            LOG.info("Moving {!r} => {!r} ...".format(backup_file, tgt_file))
+            if not self.simulate:
+                if os.path.exists(backup_file):
+                    os.rename(backup_file, tgt_file)
+                else:
+                    LOG.error("Could not find backup file {!r}.".format(backup_file))
+
+    # -------------------------------------------------------------------------
+    def cleanup(self):
+
+        LOG.info("Cleaning up ...")
+
+        for tgt_file in self.moved_files.keys():
+            backup_file = self.moved_files[tgt_file]
+            LOG.debug("Searching for {!r}.".format(backup_file))
+            if os.path.exists(backup_file):
+                LOG.info("Removing {!r} ...".format(backup_file))
+                if not self.simulate:
+                    os.remove(backup_file)
+
+        # -----------------------
+        def emit_rm_err(function, path, excinfo):
+            LOG.error("Error removing {!r} - {}: {}".format(
+                path, excinfo[1].__class__.__name__, excinfo[1]))
+
+        if self.tempdir:
+            if self.keep_tempdir:
+                msg = (
+                    "Temporary directory {!r} will not be removed. "
+                    "It's on yours to remove it manually.").format(self.tempdir)
+                LOG.warn(msg)
+            else:
+                LOG.debug("Destroying temporary directory {!r} ...".format(self.tempdir))
+                shutil.rmtree(self.tempdir, False, emit_rm_err)
+                self.tempdir = None
+
+
 # =============================================================================
 
 if __name__ == "__main__":