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 scripts (e.g. servers, installers, and upgrades) set the confdir
explicitly and do not support the env var.

Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
Christian Heimes 2016-10-24 10:35:41 +02:00 committed by Jan Cholasta
parent 64a4be26fe
commit d4916254e9
5 changed files with 68 additions and 3 deletions

View File

@ -186,6 +186,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

View File

@ -43,6 +43,7 @@ from ipapython.dn import DN
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 @@ class Env(object):
self.context = 'default'
# Set confdir:
self.env_confdir = os.environ.get('IPA_CONFDIR')
if 'confdir' not in self:
if self.in_tree:
if self.env_confdir is not None:
if (not path.isabs(self.env_confdir)
or not path.isdir(self.env_confdir)):
raise ScriptError(
"IPA_CONFDIR env var must be an absolute path to an "
"existing directory, got '{}'.".format(
self.env_confdir))
self.confdir = self.env_confdir
elif self.in_tree:
self.confdir = self.dot_ipa
else:
self.confdir = path.join('/', 'etc', 'ipa')

View File

@ -713,6 +713,15 @@ class API(ReadOnly):
self.__doing('finalize')
self.__do_if_not_done('load_plugins')
if self.env.env_confdir is not None:
if self.env.env_confdir == self.env.confdir:
self.log.info(
"IPA_CONFDIR env sets confdir to '%s'.", self.env.confdir)
else:
self.log.warn(
"IPA_CONFDIR env is overridden by an explicit confdir "
"argument.")
for plugin in self.__plugins:
if not self.env.validate_api:
if plugin.full_name not in DEFAULT_PLUGINS:

View File

@ -24,9 +24,13 @@ Test the `ipalib.plugable` module.
# 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 @@ class test_API(ClassChecker):
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')

View File

@ -96,6 +96,12 @@ class TempDir(object):
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):