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 3805dfba1dc222f3cd6cc6299bfe97c70e3e8bae 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                  |  2 +-
 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/install/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, 52 insertions(+), 24 deletions(-)

diff --git a/client/ipa-client-automount b/client/ipa-client-automount
index 0dd15b3..18914bd 100755
--- a/client/ipa-client-automount
+++ b/client/ipa-client-automount
@@ -384,6 +384,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 a0d8a31..e5c2e8c 100755
--- a/install/oddjob/com.redhat.idm.trust-fetch-domains
+++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
@@ -8,6 +8,7 @@ from ipapython.dn import DN
 from ipalib.config import Env
 from ipalib.constants import DEFAULT_CONFIG
 from ipaplatform.constants import constants
+from ipaplatform.paths import paths
 import sys
 import os
 import pwd
@@ -95,7 +96,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 46e4242..bbeae1a 100644
--- a/install/restart_scripts/renew_ca_cert
+++ b/install/restart_scripts/renew_ca_cert
@@ -40,7 +40,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 658204b..4daed6f 100755
--- a/install/share/copy-schema-to-ca.py
+++ b/install/share/copy-schema-to-ca.py
@@ -114,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 544116e..2955519 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 ce4fe02..db8ff62 100755
--- a/install/tools/ipactl
+++ b/install/tools/ipactl
@@ -560,7 +560,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 7bd8404..0954c2b 100644
--- a/ipaclient/install/client.py
+++ b/ipaclient/install/client.py
@@ -2620,6 +2620,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/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py
index 2c55db4..75c5d97 100644
--- a/ipaclient/install/ipa_certupdate.py
+++ b/ipaclient/install/ipa_certupdate.py
@@ -53,7 +53,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 a4261f5..c11120b 100644
--- a/ipaserver/install/ipa_backup.py
+++ b/ipaserver/install/ipa_backup.py
@@ -256,7 +256,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 2987b5a..2fae215 100644
--- a/ipaserver/install/ipa_restore.py
+++ b/ipaserver/install/ipa_restore.py
@@ -841,6 +841,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 576b035..bc2673b 100644
--- a/ipaserver/install/ldapupdate.py
+++ b/ipaserver/install/ldapupdate.py
@@ -308,7 +308,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 1f2e8a4..b30a934 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -566,6 +566,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,
@@ -962,6 +963,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 742848d..f1f7b1b 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -692,7 +692,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)
@@ -731,7 +731,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
@@ -954,12 +956,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
@@ -1056,8 +1060,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 0ee2abb01a52136ed47dc2cf1707089d54db02b0 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 3f66b59..7b5e317 100644
--- a/ipatests/util.py
+++ b/ipatests/util.py
@@ -96,6 +96,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