|
|
0201d8 |
From 0dfae3e9f16d91116a6769e25bbbee0ef1e485d2 Mon Sep 17 00:00:00 2001
|
|
|
0201d8 |
From: David Kupka <dkupka@redhat.com>
|
|
|
0201d8 |
Date: Wed, 4 Mar 2015 10:06:47 -0500
|
|
|
0201d8 |
Subject: [PATCH] Restore default.conf and use it to build API.
|
|
|
0201d8 |
|
|
|
0201d8 |
When restoring ipa after uninstallation we need to extract and load
|
|
|
0201d8 |
configuration of the restored environment.
|
|
|
0201d8 |
|
|
|
0201d8 |
https://fedorahosted.org/freeipa/ticket/4896
|
|
|
0201d8 |
|
|
|
0201d8 |
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
|
|
|
0201d8 |
---
|
|
|
0201d8 |
ipaserver/install/ipa_restore.py | 64 ++++++++++++++++++++++++++++++----------
|
|
|
0201d8 |
1 file changed, 48 insertions(+), 16 deletions(-)
|
|
|
0201d8 |
|
|
|
0201d8 |
diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
|
|
|
0201d8 |
index efe3b9b1c0c10775b3a72b9d843924263526209a..a5ecd5f62bc85918fe697d98109bd3a82120f355 100644
|
|
|
0201d8 |
--- a/ipaserver/install/ipa_restore.py
|
|
|
0201d8 |
+++ b/ipaserver/install/ipa_restore.py
|
|
|
0201d8 |
@@ -27,7 +27,7 @@ from ConfigParser import SafeConfigParser
|
|
|
0201d8 |
import ldif
|
|
|
0201d8 |
import itertools
|
|
|
0201d8 |
|
|
|
0201d8 |
-from ipalib import api, errors
|
|
|
0201d8 |
+from ipalib import api, errors, constants
|
|
|
0201d8 |
from ipapython import version, ipautil, certdb, dogtag
|
|
|
0201d8 |
from ipapython.ipautil import run, user_input
|
|
|
0201d8 |
from ipapython import admintool
|
|
|
0201d8 |
@@ -203,15 +203,12 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
options = self.options
|
|
|
0201d8 |
super(Restore, self).run()
|
|
|
0201d8 |
|
|
|
0201d8 |
- api.bootstrap(in_server=False, context='restore')
|
|
|
0201d8 |
- api.finalize()
|
|
|
0201d8 |
-
|
|
|
0201d8 |
self.backup_dir = self.args[0]
|
|
|
0201d8 |
if not os.path.isabs(self.backup_dir):
|
|
|
0201d8 |
self.backup_dir = os.path.join(BACKUP_DIR, self.backup_dir)
|
|
|
0201d8 |
|
|
|
0201d8 |
self.log.info("Preparing restore from %s on %s",
|
|
|
0201d8 |
- self.backup_dir, api.env.host)
|
|
|
0201d8 |
+ self.backup_dir, constants.FQDN)
|
|
|
0201d8 |
|
|
|
0201d8 |
self.header = os.path.join(self.backup_dir, 'header')
|
|
|
0201d8 |
|
|
|
0201d8 |
@@ -225,9 +222,6 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
else:
|
|
|
0201d8 |
restore_type = self.backup_type
|
|
|
0201d8 |
|
|
|
0201d8 |
- instances = [realm_to_serverid(api.env.realm), 'PKI-IPA']
|
|
|
0201d8 |
- backends = ['userRoot', 'ipaca']
|
|
|
0201d8 |
-
|
|
|
0201d8 |
# These checks would normally be in the validate method but
|
|
|
0201d8 |
# we need to know the type of backup we're dealing with.
|
|
|
0201d8 |
if restore_type == 'FULL':
|
|
|
0201d8 |
@@ -241,6 +235,8 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
else:
|
|
|
0201d8 |
installutils.check_server_configuration()
|
|
|
0201d8 |
|
|
|
0201d8 |
+ self.init_api()
|
|
|
0201d8 |
+
|
|
|
0201d8 |
if options.instance:
|
|
|
0201d8 |
instance_dir = (paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE %
|
|
|
0201d8 |
options.instance)
|
|
|
0201d8 |
@@ -248,10 +244,10 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
raise admintool.ScriptError(
|
|
|
0201d8 |
"Instance %s does not exist" % options.instance)
|
|
|
0201d8 |
|
|
|
0201d8 |
- instances = [options.instance]
|
|
|
0201d8 |
+ self.instances = [options.instance]
|
|
|
0201d8 |
|
|
|
0201d8 |
if options.backend:
|
|
|
0201d8 |
- for instance in instances:
|
|
|
0201d8 |
+ for instance in self.instances:
|
|
|
0201d8 |
db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
|
|
|
0201d8 |
(instance, options.backend))
|
|
|
0201d8 |
if os.path.exists(db_dir):
|
|
|
0201d8 |
@@ -260,9 +256,10 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
raise admintool.ScriptError(
|
|
|
0201d8 |
"Backend %s does not exist" % options.backend)
|
|
|
0201d8 |
|
|
|
0201d8 |
- backends = [options.backend]
|
|
|
0201d8 |
+ self.backends = [options.backend]
|
|
|
0201d8 |
|
|
|
0201d8 |
- for instance, backend in itertools.product(instances, backends):
|
|
|
0201d8 |
+ for instance, backend in itertools.product(self.instances,
|
|
|
0201d8 |
+ self.backends):
|
|
|
0201d8 |
db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
|
|
|
0201d8 |
(instance, backend))
|
|
|
0201d8 |
if os.path.exists(db_dir):
|
|
|
0201d8 |
@@ -274,10 +271,10 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
self.log.info("Performing %s restore from %s backup" %
|
|
|
0201d8 |
(restore_type, self.backup_type))
|
|
|
0201d8 |
|
|
|
0201d8 |
- if self.backup_host != api.env.host:
|
|
|
0201d8 |
+ if self.backup_host != constants.FQDN:
|
|
|
0201d8 |
raise admintool.ScriptError(
|
|
|
0201d8 |
"Host name %s does not match backup name %s" %
|
|
|
0201d8 |
- (api.env.host, self.backup_host))
|
|
|
0201d8 |
+ (constants.FQDN, self.backup_host))
|
|
|
0201d8 |
|
|
|
0201d8 |
if self.backup_ipa_version != str(version.VERSION):
|
|
|
0201d8 |
self.log.warning(
|
|
|
0201d8 |
@@ -307,9 +304,13 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
|
|
|
0201d8 |
self.extract_backup(options.gpg_keyring)
|
|
|
0201d8 |
|
|
|
0201d8 |
+ if restore_type == 'FULL':
|
|
|
0201d8 |
+ self.restore_default_conf()
|
|
|
0201d8 |
+ self.init_api(confdir=self.dir + paths.ETC_IPA)
|
|
|
0201d8 |
+
|
|
|
0201d8 |
databases = []
|
|
|
0201d8 |
- for instance in instances:
|
|
|
0201d8 |
- for backend in backends:
|
|
|
0201d8 |
+ for instance in self.instances:
|
|
|
0201d8 |
+ for backend in self.backends:
|
|
|
0201d8 |
database = (instance, backend)
|
|
|
0201d8 |
ldiffile = os.path.join(self.dir, '%s-%s.ldif' % database)
|
|
|
0201d8 |
if os.path.exists(ldiffile):
|
|
|
0201d8 |
@@ -607,6 +608,30 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
self.log.critical("bak2db failed: %s" % stderr)
|
|
|
0201d8 |
|
|
|
0201d8 |
|
|
|
0201d8 |
+ def restore_default_conf(self):
|
|
|
0201d8 |
+ '''
|
|
|
0201d8 |
+ Restore paths.IPA_DEFAULT_CONF to temporary directory.
|
|
|
0201d8 |
+
|
|
|
0201d8 |
+ Primary purpose of this method is to get cofiguration for api
|
|
|
0201d8 |
+ finalization when restoring ipa after uninstall.
|
|
|
0201d8 |
+ '''
|
|
|
0201d8 |
+ cwd = os.getcwd()
|
|
|
0201d8 |
+ os.chdir(self.dir)
|
|
|
0201d8 |
+ args = ['tar',
|
|
|
0201d8 |
+ '--xattrs',
|
|
|
0201d8 |
+ '--selinux',
|
|
|
0201d8 |
+ '-xzf',
|
|
|
0201d8 |
+ os.path.join(self.dir, 'files.tar'),
|
|
|
0201d8 |
+ paths.IPA_DEFAULT_CONF[1:],
|
|
|
0201d8 |
+ ]
|
|
|
0201d8 |
+
|
|
|
0201d8 |
+ (stdout, stderr, rc) = run(args, raiseonerr=False)
|
|
|
0201d8 |
+ if rc != 0:
|
|
|
0201d8 |
+ self.log.critical('Restoring %s failed: %s' %
|
|
|
0201d8 |
+ (paths.IPA_DEFAULT_CONF, stderr))
|
|
|
0201d8 |
+ os.chdir(cwd)
|
|
|
0201d8 |
+
|
|
|
0201d8 |
+
|
|
|
0201d8 |
def file_restore(self, nologs=False):
|
|
|
0201d8 |
'''
|
|
|
0201d8 |
Restore all the files in the tarball.
|
|
|
0201d8 |
@@ -803,3 +828,10 @@ class Restore(admintool.AdminTool):
|
|
|
0201d8 |
tasks.reload_systemwide_ca_store()
|
|
|
0201d8 |
|
|
|
0201d8 |
services.knownservices.certmonger.restart()
|
|
|
0201d8 |
+
|
|
|
0201d8 |
+ def init_api(self, **overrides):
|
|
|
0201d8 |
+ api.bootstrap(in_server=False, context='restore', **overrides)
|
|
|
0201d8 |
+ api.finalize()
|
|
|
0201d8 |
+
|
|
|
0201d8 |
+ self.instances = [realm_to_serverid(api.env.realm), 'PKI-IPA']
|
|
|
0201d8 |
+ self.backends = ['userRoot', 'ipaca']
|
|
|
0201d8 |
--
|
|
|
0201d8 |
2.1.0
|
|
|
0201d8 |
|