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