On 03/04/2015 06:52 PM, David Kupka wrote:
On 03/04/2015 02:11 PM, David Kupka wrote:
https://fedorahosted.org/freeipa/ticket/4896


_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Honza proposed different approach. We can extract default.conf and use
it in to create api object with the right values.
I've implemented it and it works too additionally we don't need to
change the header content for now.



_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Patch updated after offline NACK from Honza.
--
David Kupka
From 5fdcf911cfbf290c727f74c9729d51ad0736983b Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Wed, 4 Mar 2015 10:06:47 -0500
Subject: [PATCH] Restore default.conf and use it to build API.

When restoring ipa after uninstallation we need to extract and load
configuration of the restored environment.

https://fedorahosted.org/freeipa/ticket/4896
---
 ipaserver/install/ipa_restore.py | 64 ++++++++++++++++++++++++++++++----------
 1 file changed, 48 insertions(+), 16 deletions(-)

diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
index efe3b9b1c0c10775b3a72b9d843924263526209a..a5ecd5f62bc85918fe697d98109bd3a82120f355 100644
--- a/ipaserver/install/ipa_restore.py
+++ b/ipaserver/install/ipa_restore.py
@@ -27,7 +27,7 @@ from ConfigParser import SafeConfigParser
 import ldif
 import itertools
 
-from ipalib import api, errors
+from ipalib import api, errors, constants
 from ipapython import version, ipautil, certdb, dogtag
 from ipapython.ipautil import run, user_input
 from ipapython import admintool
@@ -203,15 +203,12 @@ class Restore(admintool.AdminTool):
         options = self.options
         super(Restore, self).run()
 
-        api.bootstrap(in_server=False, context='restore')
-        api.finalize()
-
         self.backup_dir = self.args[0]
         if not os.path.isabs(self.backup_dir):
             self.backup_dir = os.path.join(BACKUP_DIR, self.backup_dir)
 
         self.log.info("Preparing restore from %s on %s",
-                      self.backup_dir, api.env.host)
+                      self.backup_dir, constants.FQDN)
 
         self.header = os.path.join(self.backup_dir, 'header')
 
@@ -225,9 +222,6 @@ class Restore(admintool.AdminTool):
         else:
             restore_type = self.backup_type
 
-        instances = [realm_to_serverid(api.env.realm), 'PKI-IPA']
-        backends = ['userRoot', 'ipaca']
-
         # These checks would normally be in the validate method but
         # we need to know the type of backup we're dealing with.
         if restore_type == 'FULL':
@@ -241,6 +235,8 @@ class Restore(admintool.AdminTool):
         else:
             installutils.check_server_configuration()
 
+            self.init_api()
+
             if options.instance:
                 instance_dir = (paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE %
                                 options.instance)
@@ -248,10 +244,10 @@ class Restore(admintool.AdminTool):
                     raise admintool.ScriptError(
                         "Instance %s does not exist" % options.instance)
 
-                instances = [options.instance]
+                self.instances = [options.instance]
 
             if options.backend:
-                for instance in instances:
+                for instance in self.instances:
                     db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
                               (instance, options.backend))
                     if os.path.exists(db_dir):
@@ -260,9 +256,10 @@ class Restore(admintool.AdminTool):
                     raise admintool.ScriptError(
                         "Backend %s does not exist" % options.backend)
 
-                backends = [options.backend]
+                self.backends = [options.backend]
 
-            for instance, backend in itertools.product(instances, backends):
+            for instance, backend in itertools.product(self.instances,
+                                                       self.backends):
                 db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
                           (instance, backend))
                 if os.path.exists(db_dir):
@@ -274,10 +271,10 @@ class Restore(admintool.AdminTool):
         self.log.info("Performing %s restore from %s backup" %
                       (restore_type, self.backup_type))
 
-        if self.backup_host != api.env.host:
+        if self.backup_host != constants.FQDN:
             raise admintool.ScriptError(
                 "Host name %s does not match backup name %s" %
-                (api.env.host, self.backup_host))
+                (constants.FQDN, self.backup_host))
 
         if self.backup_ipa_version != str(version.VERSION):
             self.log.warning(
@@ -307,9 +304,13 @@ class Restore(admintool.AdminTool):
 
             self.extract_backup(options.gpg_keyring)
 
+            if restore_type == 'FULL':
+                self.restore_default_conf()
+                self.init_api(confdir=self.dir + paths.ETC_IPA)
+
             databases = []
-            for instance in instances:
-                for backend in backends:
+            for instance in self.instances:
+                for backend in self.backends:
                     database = (instance, backend)
                     ldiffile = os.path.join(self.dir, '%s-%s.ldif' % database)
                     if os.path.exists(ldiffile):
@@ -607,6 +608,30 @@ class Restore(admintool.AdminTool):
                 self.log.critical("bak2db failed: %s" % stderr)
 
 
+    def restore_default_conf(self):
+        '''
+        Restore paths.IPA_DEFAULT_CONF to temporary directory.
+
+        Primary purpose of this method is to get cofiguration for api
+        finalization when restoring ipa after uninstall.
+        '''
+        cwd = os.getcwd()
+        os.chdir(self.dir)
+        args = ['tar',
+                '--xattrs',
+                '--selinux',
+                '-xzf',
+                os.path.join(self.dir, 'files.tar'),
+                paths.IPA_DEFAULT_CONF[1:],
+               ]
+
+        (stdout, stderr, rc) = run(args, raiseonerr=False)
+        if rc != 0:
+            self.log.critical('Restoring %s failed: %s' %
+                              (paths.IPA_DEFAULT_CONF, stderr))
+        os.chdir(cwd)
+
+
     def file_restore(self, nologs=False):
         '''
         Restore all the files in the tarball.
@@ -803,3 +828,10 @@ class Restore(admintool.AdminTool):
         tasks.reload_systemwide_ca_store()
 
         services.knownservices.certmonger.restart()
+
+    def init_api(self, **overrides):
+        api.bootstrap(in_server=False, context='restore', **overrides)
+        api.finalize()
+
+        self.instances = [realm_to_serverid(api.env.realm), 'PKI-IPA']
+        self.backends = ['userRoot', 'ipaca']
-- 
2.1.0

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to