590d18
From 9b2593e54f12e28a8f1dc502ddb44cf237f0ddec Mon Sep 17 00:00:00 2001
590d18
From: Tomas Babej <tbabej@redhat.com>
590d18
Date: Thu, 17 Sep 2015 17:09:33 +0200
590d18
Subject: [PATCH] ipa-backup: Add mechanism to store empty directory structure
590d18
590d18
Certain subcomponents of IPA, such as Dogtag, cannot function if
590d18
non-critical directories (such as log directories) have not been
590d18
stored in the backup.
590d18
590d18
This patch implements storage of selected empty directories,
590d18
while preserving attributes and SELinux context.
590d18
590d18
https://fedorahosted.org/freeipa/ticket/5297
590d18
590d18
Reviewed-By: Martin Basti <mbasti@redhat.com>
590d18
---
590d18
 freeipa.spec.in                 |  1 +
590d18
 ipaplatform/base/paths.py       |  3 +++
590d18
 ipaserver/install/ipa_backup.py | 50 ++++++++++++++++++++++++++++++++++++++---
590d18
 3 files changed, 51 insertions(+), 3 deletions(-)
590d18
590d18
diff --git a/freeipa.spec.in b/freeipa.spec.in
590d18
index d8e24a5af47fbfca89ccb9c3d07dcfca5a8073d9..a8515487757556f337a4bbfc1cc14e8fb4707ccd 100644
590d18
--- a/freeipa.spec.in
590d18
+++ b/freeipa.spec.in
590d18
@@ -162,6 +162,7 @@ Requires: softhsm >= 2.0.0rc1-1
590d18
 Requires: p11-kit
590d18
 Requires: systemd-python
590d18
 Requires: %{etc_systemd_dir}
590d18
+Requires: gzip
590d18
 
590d18
 Conflicts: %{alt_name}-server
590d18
 Obsoletes: %{alt_name}-server < %{version}
590d18
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
590d18
index 3930c93fcba06959dd34507ecc29f92e33637775..97c330c31844fcf19bec2e96bf2b23cba5f7f3f0 100644
590d18
--- a/ipaplatform/base/paths.py
590d18
+++ b/ipaplatform/base/paths.py
590d18
@@ -328,6 +328,9 @@ class BasePathNamespace(object):
590d18
     TOMCAT_CA_DIR = "/var/log/pki/pki-tomcat/ca"
590d18
     TOMCAT_CA_ARCHIVE_DIR = "/var/log/pki/pki-tomcat/ca/archive"
590d18
     TOMCAT_SIGNEDAUDIT_DIR = "/var/log/pki/pki-tomcat/ca/signedAudit"
590d18
+    TOMCAT_KRA_DIR = "/var/log/pki/pki-tomcat/kra"
590d18
+    TOMCAT_KRA_ARCHIVE_DIR = "/var/log/pki/pki-tomcat/kra/archive"
590d18
+    TOMCAT_KRA_SIGNEDAUDIT_DIR = "/var/log/pki/pki-tomcat/kra/signedAudit"
590d18
     LOG_SECURE = "/var/log/secure"
590d18
     NAMED_RUN = "/var/named/data/named.run"
590d18
     VAR_OPENDNSSEC_DIR = "/var/opendnssec"
590d18
diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
590d18
index 8df1005a222220a0ece95a3691766ed3cd00a0d9..3bd2ef0203c1b5b596e092987acd894491ecae26 100644
590d18
--- a/ipaserver/install/ipa_backup.py
590d18
+++ b/ipaserver/install/ipa_backup.py
590d18
@@ -202,6 +202,16 @@ class Backup(admintool.AdminTool):
590d18
       paths.NAMED_RUN,
590d18
     )
590d18
 
590d18
+    required_dirs=(
590d18
+      paths.TOMCAT_TOPLEVEL_DIR,
590d18
+      paths.TOMCAT_CA_DIR,
590d18
+      paths.TOMCAT_SIGNEDAUDIT_DIR,
590d18
+      paths.TOMCAT_CA_ARCHIVE_DIR,
590d18
+      paths.TOMCAT_KRA_DIR,
590d18
+      paths.TOMCAT_KRA_SIGNEDAUDIT_DIR,
590d18
+      paths.TOMCAT_KRA_ARCHIVE_DIR,
590d18
+    )
590d18
+
590d18
     def __init__(self, options, args):
590d18
         super(Backup, self).__init__(options, args)
590d18
         self._conn = None
590d18
@@ -486,13 +496,15 @@ class Backup(admintool.AdminTool):
590d18
         def verify_directories(dirs):
590d18
             return [s for s in dirs if os.path.exists(s)]
590d18
 
590d18
+        tarfile = os.path.join(self.dir, 'files.tar')
590d18
+
590d18
         self.log.info("Backing up files")
590d18
         args = ['tar',
590d18
                 '--exclude=/var/lib/ipa/backup',
590d18
                 '--xattrs',
590d18
                 '--selinux',
590d18
-                '-czf',
590d18
-                os.path.join(self.dir, 'files.tar')
590d18
+                '-cf',
590d18
+                tarfile
590d18
                ]
590d18
 
590d18
         args.extend(verify_directories(self.dirs))
590d18
@@ -503,7 +515,39 @@ class Backup(admintool.AdminTool):
590d18
 
590d18
         (stdout, stderr, rc) = run(args, raiseonerr=False)
590d18
         if rc != 0:
590d18
-            raise admintool.ScriptError('tar returned non-zero %d: %s' % (rc, stdout))
590d18
+            raise admintool.ScriptError('tar returned non-zero code '
590d18
+                '%d: %s' % (rc, stderr))
590d18
+
590d18
+        # Backup the necessary directory structure. This is a separate
590d18
+        # call since we are using the '--no-recursion' flag to store
590d18
+        # the directory structure only, no files.
590d18
+        missing_directories = verify_directories(self.required_dirs)
590d18
+
590d18
+        if missing_directories:
590d18
+            args = ['tar',
590d18
+                    '--exclude=/var/lib/ipa/backup',
590d18
+                    '--xattrs',
590d18
+                    '--selinux',
590d18
+                    '--no-recursion',
590d18
+                    '-rf',  # -r appends to an existing archive
590d18
+                    tarfile,
590d18
+                   ]
590d18
+            args.extend(missing_directories)
590d18
+
590d18
+            (stdout, stderr, rc) = run(args, raiseonerr=False)
590d18
+            if rc != 0:
590d18
+                raise admintool.ScriptError('tar returned non-zero %d when adding '
590d18
+                    'directory structure: %s' % (rc, stderr))
590d18
+
590d18
+        # Compress the archive. This is done separately, since 'tar' cannot
590d18
+        # append to a compressed archive.
590d18
+        (stdout, stderr, rc) = run(['gzip', tarfile], raiseonerr=False)
590d18
+        if rc != 0:
590d18
+            raise admintool.ScriptError('gzip returned non-zero %d when '
590d18
+                'compressing the backup: %s' % (rc, stderr))
590d18
+
590d18
+        # Rename the archive back to files.tar to preserve compatibility
590d18
+        os.rename(os.path.join(self.dir, 'files.tar.gz'), tarfile)
590d18
 
590d18
 
590d18
     def create_header(self, data_only):
590d18
-- 
590d18
2.4.3
590d18