URL: https://github.com/freeipa/freeipa/pull/182
Author: tiran
 Title: #182: Use env var IPA_CONFDIR to get confdir for 'cli' context
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/182/head:pr182
git checkout pr182
From 686ade0be3bffd8bda3795728163d5d27df0b9ad Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Mon, 28 Nov 2016 16:24:33 +0100
Subject: [PATCH 1/2] Set explicit confdir option for global contexts

Some API contexts are used to modify global state (e.g. files in /etc
and /var). These contexts do not support confdir overrides. Initialize
the API with an explicit confdir argument to paths.ETC_IPA.

The special contexts are:

* backup
* cli_installer
* installer
* ipctl
* renew
* restore
* server
* updates

The patch also corrects the context of the ipa-httpd-kdcproxy script to
'server'.

https://fedorahosted.org/freeipa/ticket/6389

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 client/ipa-client-automount                         |  1 +
 install/certmonger/dogtag-ipa-ca-renew-agent-submit |  2 +-
 install/migration/migration.py                      |  3 ++-
 install/oddjob/com.redhat.idm.trust-fetch-domains   |  4 +++-
 install/restart_scripts/renew_ca_cert               |  2 +-
 install/restart_scripts/restart_dirsrv              |  3 ++-
 install/restart_scripts/stop_pkicad                 |  3 ++-
 install/share/copy-schema-to-ca.py                  |  3 ++-
 install/share/wsgi.py                               |  6 ++++--
 install/tools/ipa-httpd-kdcproxy                    |  3 ++-
 install/tools/ipa-replica-conncheck                 |  4 +++-
 install/tools/ipactl                                |  5 ++++-
 ipaclient/install/client.py                         |  1 +
 ipaclient/ipa_certupdate.py                         |  2 +-
 ipaserver/install/ipa_backup.py                     |  2 +-
 ipaserver/install/ipa_ldap_updater.py               |  2 +-
 ipaserver/install/ipa_restore.py                    |  1 +
 ipaserver/install/ipa_server_upgrade.py             |  2 +-
 ipaserver/install/ipa_winsync_migrate.py            |  3 ++-
 ipaserver/install/ldapupdate.py                     |  4 +++-
 ipaserver/install/server/install.py                 |  2 ++
 ipaserver/install/server/replicainstall.py          | 19 +++++++++++++------
 22 files changed, 53 insertions(+), 24 deletions(-)

diff --git a/client/ipa-client-automount b/client/ipa-client-automount
index 53c0537..93b1eaf 100755
--- a/client/ipa-client-automount
+++ b/client/ipa-client-automount
@@ -383,6 +383,7 @@ def main():
 
     cfg = dict(
         context='cli_installer',
+        confdir=paths.ETC_IPA,
         in_server=False,
         debug=options.debug,
         verbose=0,
diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
index 7389a5e..2e137ad 100755
--- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
@@ -494,7 +494,7 @@ def main():
         'ipaCACertRenewal':     renew_ca_cert,
     }
 
-    api.bootstrap(in_server=True, context='renew')
+    api.bootstrap(in_server=True, context='renew', confdir=paths.ETC_IPA)
     api.finalize()
     api.Backend.ldap2.connect()
 
diff --git a/install/migration/migration.py b/install/migration/migration.py
index 4743279..73e4777 100644
--- a/install/migration/migration.py
+++ b/install/migration/migration.py
@@ -24,6 +24,7 @@
 import errno
 from wsgiref.util import request_uri
 
+from ipaplatform.paths import paths
 from ipapython.ipa_log_manager import root_logger
 from ipapython.dn import DN
 from ipapython import ipaldap
@@ -72,7 +73,7 @@ def application(environ, start_response):
 
     # API object only for configuration, finalize() not needed
     api = create_api(mode=None)
-    api.bootstrap(context='server', in_server=True)
+    api.bootstrap(context='server', confdir=paths.ETC_IPA, in_server=True)
     try:
         bind(api.env.ldap_uri, api.env.basedn,
              form_data['username'].value, form_data['password'].value)
diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
index b663daa..073e254 100755
--- a/install/oddjob/com.redhat.idm.trust-fetch-domains
+++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
@@ -9,6 +9,7 @@ from ipalib.config import Env
 from ipalib.constants import DEFAULT_CONFIG
 from ipapython.ipautil import kinit_keytab
 from ipaplatform.constants import constants
+from ipaplatform.paths import paths
 import sys
 import os
 import pwd
@@ -94,7 +95,8 @@ env._bootstrap(debug=options.debug, log=None)
 env._finalize_core(**dict(DEFAULT_CONFIG))
 
 # Initialize the API with the proper debug level
-api.bootstrap(in_server=True, debug=env.debug, log=None, context='server')
+api.bootstrap(in_server=True, debug=env.debug, log=None,
+              context='server', confdir=paths.ETC_IPA)
 api.finalize()
 
 # Only import trust plugin after api is initialized or internal imports
diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert
index 0f0a690..5d8af43 100644
--- a/install/restart_scripts/renew_ca_cert
+++ b/install/restart_scripts/renew_ca_cert
@@ -38,7 +38,7 @@ from ipaplatform.paths import paths
 def _main():
     nickname = sys.argv[1]
 
-    api.bootstrap(in_server=True, context='restart')
+    api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
     api.finalize()
     api.Backend.ldap2.connect()
 
diff --git a/install/restart_scripts/restart_dirsrv b/install/restart_scripts/restart_dirsrv
index 72d3c54..b4c9490 100644
--- a/install/restart_scripts/restart_dirsrv
+++ b/install/restart_scripts/restart_dirsrv
@@ -24,6 +24,7 @@ import syslog
 import traceback
 from ipalib import api
 from ipaplatform import services
+from ipaplatform.paths import paths
 from ipaserver.install import certs
 
 
@@ -33,7 +34,7 @@ def _main():
     except IndexError:
         instance = ""
 
-    api.bootstrap(in_server=True, context='restart')
+    api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
     api.finalize()
 
     syslog.syslog(syslog.LOG_NOTICE, "certmonger restarted dirsrv instance '%s'" % instance)
diff --git a/install/restart_scripts/stop_pkicad b/install/restart_scripts/stop_pkicad
index ae07dcd..133a4ef 100644
--- a/install/restart_scripts/stop_pkicad
+++ b/install/restart_scripts/stop_pkicad
@@ -23,11 +23,12 @@ import syslog
 import traceback
 from ipalib import api
 from ipaplatform import services
+from ipaplatform.paths import paths
 from ipaserver.install import certs
 
 
 def main():
-    api.bootstrap(in_server=True, context='restart')
+    api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
     api.finalize()
 
     dogtag_service = services.knownservices['pki_tomcatd']
diff --git a/install/share/copy-schema-to-ca.py b/install/share/copy-schema-to-ca.py
index 9edc0cd..15e4b8d 100755
--- a/install/share/copy-schema-to-ca.py
+++ b/install/share/copy-schema-to-ca.py
@@ -17,6 +17,7 @@
 
 from hashlib import sha1
 
+from ipaplatform.paths import paths
 from ipapython import ipautil
 from ipapython.ipa_log_manager import root_logger, standard_logging_setup
 from ipaserver.install.dsinstance import schema_dirname
@@ -113,7 +114,7 @@ def main():
     standard_logging_setup(verbose=True)
 
     # In 3.0, restarting needs access to api.env
-    api.bootstrap_with_global_options(context='server')
+    api.bootstrap_with_global_options(context='server', confdir=paths.ETC_IPA)
 
     add_ca_schema()
     restart_pki_ds()
diff --git a/install/share/wsgi.py b/install/share/wsgi.py
index ee9311e..ca97d1e 100644
--- a/install/share/wsgi.py
+++ b/install/share/wsgi.py
@@ -23,6 +23,7 @@
 """
 WSGI appliction for IPA server.
 """
+from ipaplatform.paths import paths
 from ipalib import api
 from ipalib.config import Env
 from ipalib.constants import DEFAULT_CONFIG
@@ -31,11 +32,12 @@
 # by reading in the configuration file(s). The server always reads
 # default.conf and will also read in `context'.conf.
 env = Env()
-env._bootstrap(context='server', log=None)
+env._bootstrap(context='server', log=None, confdir=paths.ETC_IPA)
 env._finalize_core(**dict(DEFAULT_CONFIG))
 
 # Initialize the API with the proper debug level
-api.bootstrap(context='server', debug=env.debug, log=None)
+api.bootstrap(context='server', confdir=paths.ETC_IPA,
+              debug=env.debug, log=None)
 try:
     api.finalize()
 except Exception as e:
diff --git a/install/tools/ipa-httpd-kdcproxy b/install/tools/ipa-httpd-kdcproxy
index 329565c..bb2949b 100755
--- a/install/tools/ipa-httpd-kdcproxy
+++ b/install/tools/ipa-httpd-kdcproxy
@@ -184,7 +184,8 @@ class KDCProxyConfig(object):
 def main(debug=DEBUG, time_limit=TIME_LIMIT):
     # initialize API without file logging
     if not api.isdone('bootstrap'):
-        api.bootstrap(context='ipa-httpd-kdcproxy', log=None, debug=debug)
+        api.bootstrap(context='server', confdir=paths.ETC_IPA,
+                      log=None, debug=debug)
         standard_logging_setup(verbose=True, debug=debug)
 
     try:
diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index 7ec1ef8..7981093 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -480,7 +480,9 @@ def main():
                     else:
                         nss_dir = None
 
-                    api.bootstrap(context='client', xmlrpc_uri=xmlrpc_uri,
+                    api.bootstrap(context='client',
+                                  confdir=paths.ETC_IPA,
+                                  xmlrpc_uri=xmlrpc_uri,
                                   nss_dir=nss_db.secdir)
                     api.finalize()
                     try:
diff --git a/install/tools/ipactl b/install/tools/ipactl
index 13a1a27..f24d64d 100755
--- a/install/tools/ipactl
+++ b/install/tools/ipactl
@@ -561,7 +561,10 @@ def main():
         else:
             raise e
 
-    api.bootstrap(in_server=True, context='ipactl', debug=options.debug)
+    api.bootstrap(in_server=True,
+                  context='ipactl',
+                  confdir=paths.ETC_IPA,
+                  debug=options.debug)
     api.finalize()
 
     if '.' not in api.env.host:
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
index d18d8bb..c5ff75b 100644
--- a/ipaclient/install/client.py
+++ b/ipaclient/install/client.py
@@ -2586,6 +2586,7 @@ def _install(options):
 
     with certdb.NSSDatabase() as tmp_db:
         api.bootstrap(context='cli_installer',
+                      confdir=paths.ETC_IPA,
                       debug=options.debug,
                       delegate=False,
                       nss_dir=tmp_db.secdir)
diff --git a/ipaclient/ipa_certupdate.py b/ipaclient/ipa_certupdate.py
index 6e41de9..159371c 100644
--- a/ipaclient/ipa_certupdate.py
+++ b/ipaclient/ipa_certupdate.py
@@ -52,7 +52,7 @@ def run(self):
             raise admintool.ScriptError(
                 "IPA client is not configured on this system.")
 
-        api.bootstrap(context='cli_installer')
+        api.bootstrap(context='cli_installer', confdir=paths.ETC_IPA)
         api.finalize()
 
         server = urlsplit(api.env.jsonrpc_uri).hostname
diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
index 6fc1870..36d5086 100644
--- a/ipaserver/install/ipa_backup.py
+++ b/ipaserver/install/ipa_backup.py
@@ -257,7 +257,7 @@ def run(self):
         options = self.options
         super(Backup, self).run()
 
-        api.bootstrap(in_server=True, context='backup')
+        api.bootstrap(in_server=True, context='backup', confdir=paths.ETC_IPA)
         api.finalize()
 
         self.log.info("Preparing backup on %s", api.env.host)
diff --git a/ipaserver/install/ipa_ldap_updater.py b/ipaserver/install/ipa_ldap_updater.py
index e6e6b5a..f3e05b8 100644
--- a/ipaserver/install/ipa_ldap_updater.py
+++ b/ipaserver/install/ipa_ldap_updater.py
@@ -89,7 +89,7 @@ def setup_logging(self):
     def run(self):
         super(LDAPUpdater, self).run()
 
-        api.bootstrap(in_server=True, context='updates')
+        api.bootstrap(in_server=True, context='updates', confdir=paths.ETC_IPA)
         api.finalize()
 
     def handle_error(self, exception):
diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
index 3dc6522..c87e427 100644
--- a/ipaserver/install/ipa_restore.py
+++ b/ipaserver/install/ipa_restore.py
@@ -840,6 +840,7 @@ def cert_restore(self):
         services.knownservices.certmonger.restart()
 
     def init_api(self, **overrides):
+        overrides.setdefault('confdir', paths.ETC_IPA)
         api.bootstrap(in_server=True, context='restore', **overrides)
         api.finalize()
 
diff --git a/ipaserver/install/ipa_server_upgrade.py b/ipaserver/install/ipa_server_upgrade.py
index c384704..ef31068 100644
--- a/ipaserver/install/ipa_server_upgrade.py
+++ b/ipaserver/install/ipa_server_upgrade.py
@@ -38,7 +38,7 @@ def setup_logging(self):
     def run(self):
         super(ServerUpgrade, self).run()
 
-        api.bootstrap(in_server=True, context='updates')
+        api.bootstrap(in_server=True, context='updates', confdir=paths.ETC_IPA)
         api.finalize()
 
         try:
diff --git a/ipaserver/install/ipa_winsync_migrate.py b/ipaserver/install/ipa_winsync_migrate.py
index d0653c9..cb77de6 100644
--- a/ipaserver/install/ipa_winsync_migrate.py
+++ b/ipaserver/install/ipa_winsync_migrate.py
@@ -24,6 +24,7 @@
 
 from ipalib import api
 from ipalib import errors
+from ipaplatform.paths import paths
 from ipapython import admintool
 from ipapython.dn import DN
 from ipapython.ipautil import realm_to_suffix, posixify
@@ -346,7 +347,7 @@ def main(cls, argv):
             sys.exit(e)
 
         # Finalize API
-        api.bootstrap(in_server=True, context='server')
+        api.bootstrap(in_server=True, context='server', confdir=paths.ETC_IPA)
         api.finalize()
 
         # Setup LDAP connection
diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py
index 1e49e7a..b11cbc1 100644
--- a/ipaserver/install/ldapupdate.py
+++ b/ipaserver/install/ldapupdate.py
@@ -311,7 +311,9 @@ def __init__(self, dm_password=None, sub_dict={},
             self.sub_dict["TOTAL_EXCLUDES"] = "(objectclass=*) $ EXCLUDE " + \
                 " ".join(constants.REPL_AGMT_TOTAL_EXCLUDES)
         self.api = create_api(mode=None)
-        self.api.bootstrap(in_server=True, context='updates',
+        self.api.bootstrap(in_server=True,
+                           context='updates',
+                           confdir=paths.ETC_IPA,
                            ldap_uri=self.ldapuri)
         self.api.finalize()
         if online:
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index b8a46f5..431ca5c 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -562,6 +562,7 @@ def install_check(installer):
     # we are sure we have the configuration file ready.
     cfg = dict(
         context='installer',
+        confdir=paths.ETC_IPA,
         in_server=True,
         # make sure host name specified by user is used instead of default
         host=host_name,
@@ -958,6 +959,7 @@ def uninstall_check(installer):
     # we are sure we have the configuration file ready.
     cfg = dict(
         context='installer',
+        confdir=paths.ETC_IPA,
         in_server=True,
     )
 
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index f3aa482..b7dba9d 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -690,7 +690,7 @@ def install_check(installer):
     # Note: We must do this before bootstraping and finalizing ipalib.api
     create_ipa_conf(fstore, config, ca_enabled)
 
-    api.bootstrap(in_server=True, context='installer')
+    api.bootstrap(in_server=True, context='installer', confdir=paths.ETC_IPA)
     api.finalize()
 
     installutils.verify_fqdn(config.master_host_name, options.no_host_dns)
@@ -729,7 +729,9 @@ def install_check(installer):
 
     ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name)
     remote_api = create_api(mode=None)
-    remote_api.bootstrap(in_server=True, context='installer',
+    remote_api.bootstrap(in_server=True,
+                         context='installer',
+                         confdir=paths.ETC_IPA,
                          ldap_uri=ldapuri)
     remote_api.finalize()
     conn = remote_api.Backend.ldap2
@@ -952,12 +954,14 @@ def promote_check(installer):
     fstore = sysrestore.FileStore(paths.SYSRESTORE)
 
     env = Env()
-    env._bootstrap(context='installer', log=None)
+    env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None)
     env._finalize_core(**dict(constants.DEFAULT_CONFIG))
 
     # pylint: disable=no-member
     xmlrpc_uri = 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host))
-    api.bootstrap(in_server=True, context='installer',
+    api.bootstrap(in_server=True,
+                  context='installer',
+                  confdir=paths.ETC_IPA,
                   ldap_uri=installutils.realm_to_ldapi_uri(env.realm),
                   xmlrpc_uri=xmlrpc_uri)
     # pylint: enable=no-member
@@ -1054,8 +1058,11 @@ def promote_check(installer):
     xmlrpc_uri = 'https://{}/ipa/xml'.format(
         ipautil.format_netloc(config.master_host_name))
     remote_api = create_api(mode=None)
-    remote_api.bootstrap(in_server=True, context='installer',
-                         ldap_uri=ldapuri, xmlrpc_uri=xmlrpc_uri)
+    remote_api.bootstrap(in_server=True,
+                         context='installer',
+                         confdir=paths.ETC_IPA,
+                         ldap_uri=ldapuri,
+                         xmlrpc_uri=xmlrpc_uri)
     remote_api.finalize()
 
     check_remote_version(remote_api)

From 43040dbd56256f09a438a69c0d1b8d59fcbdaf15 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Mon, 24 Oct 2016 10:35:41 +0200
Subject: [PATCH 2/2] Use env var IPA_CONFDIR to get confdir

The environment variable IPA_CONFDIR overrides the default confdir path.
The value of the environment variable must be an absolute path to an existing
directory. The new variable makes it much simpler to use the 'ipa'
command and ipalib with a local configuration directory.

Some contexts like server, installer, and upgrades set the confdir explicitly
and do not support the env var.

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 client/man/ipa.1                      |  4 ++++
 ipalib/config.py                      | 12 ++++++++++-
 ipalib/plugable.py                    |  4 ++++
 ipatests/test_ipalib/test_plugable.py | 40 +++++++++++++++++++++++++++++++++--
 ipatests/util.py                      |  6 ++++++
 5 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/client/man/ipa.1 b/client/man/ipa.1
index cc5641b..f35f557 100644
--- a/client/man/ipa.1
+++ b/client/man/ipa.1
@@ -190,6 +190,10 @@ The ipa client will determine which server to connect to in this order:
 
 .TP
 If a kerberos error is raised by any of the requests then it will stop processing and display the error message.
+.SH "ENVIRONMENT VARIABLES"
+.TP
+\fBIPA_CONFDIR\fR
+Override path to confdir (default: \fB/etc/ipa\fR).
 .SH "FILES"
 .TP
 \fB/etc/ipa/default.conf\fR
diff --git a/ipalib/config.py b/ipalib/config.py
index 1075d62..c46d033 100644
--- a/ipalib/config.py
+++ b/ipalib/config.py
@@ -43,6 +43,7 @@
 from ipalib.base import check_name
 from ipalib.constants import CONFIG_SECTION
 from ipalib.constants import OVERRIDE_ERROR, SET_ERROR, DEL_ERROR
+from ipapython.admintool import ScriptError
 
 if six.PY3:
     unicode = str
@@ -460,8 +461,17 @@ def _bootstrap(self, **overrides):
             self.context = 'default'
 
         # Set confdir:
+        self.confdir_env = False
         if 'confdir' not in self:
-            if self.in_tree:
+            ipa_confdir = os.environ.get('IPA_CONFDIR')
+            if ipa_confdir is not None:
+                if not path.isabs(ipa_confdir) or not path.isdir(ipa_confdir):
+                    raise ScriptError(
+                        'IPA_CONFDIR env var must be an absolute path to an '
+                        'existing directory.')
+                self.confdir = ipa_confdir
+                self.confdir_env = True
+            elif self.in_tree:
                 self.confdir = self.dot_ipa
             else:
                 self.confdir = path.join('/', 'etc', 'ipa')
diff --git a/ipalib/plugable.py b/ipalib/plugable.py
index 503534f..e9d4c80 100644
--- a/ipalib/plugable.py
+++ b/ipalib/plugable.py
@@ -713,6 +713,10 @@ def finalize(self):
         self.__doing('finalize')
         self.__do_if_not_done('load_plugins')
 
+        if self.env.confdir_env:
+            self.log.info("IPA_CONFDIR env var sets confdir to '%s'.",
+                          self.env.confdir)
+
         for plugin in self.__plugins:
             if not self.env.validate_api:
                 if plugin.full_name not in DEFAULT_PLUGINS:
diff --git a/ipatests/test_ipalib/test_plugable.py b/ipatests/test_ipalib/test_plugable.py
index 1ee1102..ff22446 100644
--- a/ipatests/test_ipalib/test_plugable.py
+++ b/ipatests/test_ipalib/test_plugable.py
@@ -24,9 +24,13 @@
 # FIXME: Pylint errors
 # pylint: disable=no-member
 
+import os
+import textwrap
+
+from ipalib import plugable, errors, create_api
+from ipapython.admintool import ScriptError
 from ipatests.util import raises, read_only
-from ipatests.util import ClassChecker, create_test_api
-from ipalib import plugable, errors
+from ipatests.util import ClassChecker, create_test_api, TempHome
 
 import pytest
 
@@ -272,3 +276,35 @@ def test_load_plugins(self):
         assert o.isdone('load_plugins') is True
         e = raises(Exception, o.load_plugins)
         assert str(e) == 'API.load_plugins() already called'
+
+    def test_ipaconf_env(self):
+        ipa_confdir = os.environ.get('IPA_CONFDIR', None)
+        try:
+            with TempHome() as home:
+                defaultconf = home.join('default.conf')
+                with open(defaultconf, 'w') as f:
+                    f.write(textwrap.dedent("""
+                        [global]
+                        basedn = dc=ipa,dc=test
+                        realm = IPA.TEST
+                        domain = ipa.test
+                        """)
+                    )
+                os.environ['IPA_CONFDIR'] = home.path
+                api = create_api(mode='unit_test')
+                api.bootstrap()
+                api.finalize()
+                assert api.env.confdir == home.path
+                assert api.env.conf_default == defaultconf
+                assert api.env.realm == 'IPA.TEST'
+                assert api.env.domain == 'ipa.test'
+
+                os.environ['IPA_CONFDIR'] = home.join('invalid')
+                api = create_api(mode='unit_test')
+                with pytest.raises(ScriptError):
+                    api.bootstrap()
+        finally:
+            if ipa_confdir:
+                os.environ['IPA_CONFDIR'] = ipa_confdir
+            else:
+                os.environ.pop('IPA_CONFDIR')
diff --git a/ipatests/util.py b/ipatests/util.py
index bca8e9c..38edaf9 100644
--- a/ipatests/util.py
+++ b/ipatests/util.py
@@ -97,6 +97,12 @@ def join(self, *parts):
     def __del__(self):
         self.rmtree()
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.rmtree()
+
 
 class TempHome(TempDir):
     def __init__(self):
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to