diff options
-rw-r--r-- | ipalib/__init__.py | 53 | ||||
-rw-r--r-- | ipalib/config.py | 32 | ||||
-rwxr-xr-x | make-test | 2 | ||||
-rw-r--r-- | tests/test_ipalib/test_config.py | 21 | ||||
-rw-r--r-- | tests/util.py | 4 |
5 files changed, 57 insertions, 55 deletions
diff --git a/ipalib/__init__.py b/ipalib/__init__.py index b9a3c96d..e30b7fed 100644 --- a/ipalib/__init__.py +++ b/ipalib/__init__.py @@ -685,41 +685,40 @@ is configured. Environment variables --------------------- -Plugins access various environment variables and run-time information through -``self.api.env`` (for convenience, ``self.env`` is equivalent). +Plugins access configuration variables and run-time information through +``self.api.env`` (or for convenience, ``self.env`` is equivalent). This +attribute is a refences to the `ipalib.config.Env` instance created in +`plugable.API.__init__()`. -When you create a fresh `plugable.API` instance, its ``env`` attribute is -likewise a freshly created `config.Env` instance, which will already be -populated with certain run-time information. For example: +After `API.bootstrap()` has been called, the `Env` instance will be populated +with all the environment information used by the built-in plugins. +This will be called before any plugins are registered, so plugin authors can +assume these variables will all exist by the time the module containing their +plugin (or plugins) is imported. For example: >>> api = create_api() ->>> list(api.env) -['bin', 'dot_ipa', 'home', 'ipalib', 'mode', 'script', 'site_packages'] - -Here is a quick overview of the run-time information: - -============= ================================ ======================= -Key Source or example value Description -============= ================================ ======================= -bin /usr/bin Dir. containing script -dot_ipa ~/.ipa User config directory -home os.environ['HOME'] User home dir. -ipalib .../site-packages/ipalib Dir. of ipalib package -mode 'production' or 'unit_test' The mode ipalib is in -script sys.argv[0] Path of script -site_packages /usr/lib/python2.5/site-packages Dir. containing ipalib/ -============= ================================ ======================= - -After `plugable.API.bootstrap()` has been called, the env instance will be -populated with all the environment information used by the built-in plugins. -This will typically be called before any plugins are registered. For example: - >>> len(api.env) -7 +1 >>> api.bootstrap(in_server=True) # We want to execute, not forward >>> len(api.env) 35 +`Env._bootstrap()`, which is called by `API.bootstrap()`, will create several +run-time variables that connot be overriden in configuration files or through +command-line options. Here is an overview of this run-time information: + +============= ============================= ======================= +Key Example value Description +============= ============================= ======================= +bin '/usr/bin' Dir. containing script +dot_ipa '/home/jderose/.ipa' User config directory +home os.environ['HOME'] User home dir. +ipalib '.../site-packages/ipalib' Dir. of ipalib package +mode 'unit_test' The mode ipalib is in +script sys.argv[0] Path of script +site_packages '.../python2.5/site-packages' Dir. containing ipalib/ +============= ============================= ======================= + If your plugin requires new environment variables *and* will be included in the freeIPA built-in plugins, you should add the defaults for your variables in `ipalib.constants.DEFAULT_CONFIG`. Also, you should consider whether your diff --git a/ipalib/config.py b/ipalib/config.py index 4631d899..9fe02cb3 100644 --- a/ipalib/config.py +++ b/ipalib/config.py @@ -62,15 +62,18 @@ class Env(object): The variable values can be ``str`` or ``int`` instances, or the ``True``, ``False``, or ``None`` constants. When the value provided is an ``str`` instance, some limited automatic type conversion is performed, which allows - values of specific types to be set easily from configuration files and from + values of specific types to be set easily from configuration files or command-line options. The ``True``, ``False``, and ``None`` constants can be specified with a string that matches what ``repr()`` would return. For example: - >>> env.true = 'True' + >>> env.true = True + >>> env.also_true = 'True' >>> env.true True + >>> env.also_true + True Note that the automatic type conversion is case sensitive. For example: @@ -98,14 +101,14 @@ class Env(object): >>> env.actually_false False - `Env` is set-once, first-one-wins. Once a variable has been set, trying to - override it will raise an ``AttributeError``. For example: + `Env` variables are all set-once (first-one-wins). Once a variable has been + set, trying to override it will raise an ``AttributeError``. For example: - >>> env.my_var = 'first' - >>> env.my_var = 'second' + >>> env.date = 'First' + >>> env.date = 'Second' Traceback (most recent call last): ... - AttributeError: cannot override Env.my_var value 'first' with 'second' + AttributeError: cannot override Env.date value 'First' with 'Second' An `Env` instance can also be *locked*, after which no further variables can be set. Trying to set variables on a locked `Env` instance will also raise @@ -127,12 +130,6 @@ class Env(object): def __init__(self): object.__setattr__(self, '_Env__d', {}) object.__setattr__(self, '_Env__done', set()) - self.ipalib = path.dirname(path.abspath(__file__)) - self.site_packages = path.dirname(self.ipalib) - self.script = path.abspath(sys.argv[0]) - self.bin = path.dirname(self.script) - self.home = path.abspath(os.environ['HOME']) - self.dot_ipa = path.join(self.home, '.ipa') def __setattr__(self, name, value): """ @@ -211,6 +208,15 @@ class Env(object): and the location of the configuration file. """ self.__doing('_bootstrap') + + # Set run-time variables: + self.ipalib = path.dirname(path.abspath(__file__)) + self.site_packages = path.dirname(self.ipalib) + self.script = path.abspath(sys.argv[0]) + self.bin = path.dirname(self.script) + self.home = path.abspath(os.environ['HOME']) + self.dot_ipa = path.join(self.home, '.ipa') + for (key, value) in overrides.iteritems(): self[key] = value if 'in_tree' not in self: @@ -10,7 +10,7 @@ do if [[ -f $executable ]]; then echo "[ $name: Starting tests... ]" ((runs += 1)) - if $executable /usr/bin/nosetests -v --with-doctest --stop + if $executable /usr/bin/nosetests -v --with-doctest then echo "[ $name: Tests OK ]" else diff --git a/tests/test_ipalib/test_config.py b/tests/test_ipalib/test_config.py index 740ef6cf..8884697e 100644 --- a/tests/test_ipalib/test_config.py +++ b/tests/test_ipalib/test_config.py @@ -147,13 +147,9 @@ class test_Env(ClassChecker): Test the `ipalib.config.Env.__init__` method. """ (o, home) = self.new() - ipalib = path.dirname(path.abspath(config.__file__)) - assert o.ipalib == ipalib - assert o.site_packages == path.dirname(ipalib) - assert o.script == path.abspath(sys.argv[0]) - assert o.bin == path.dirname(path.abspath(sys.argv[0])) - assert o.home == home.path - assert o.dot_ipa == home.join('.ipa') + assert list(o) == [] + assert len(o) == 0 + assert o.__islocked__() is False def test_setattr(self): """ @@ -246,10 +242,14 @@ class test_Env(ClassChecker): """ # Test defaults created by _bootstrap(): (o, home) = self.new() - assert 'in_tree' not in o - assert 'context' not in o - assert 'conf' not in o o._bootstrap() + ipalib = path.dirname(path.abspath(config.__file__)) + assert o.ipalib == ipalib + assert o.site_packages == path.dirname(ipalib) + assert o.script == path.abspath(sys.argv[0]) + assert o.bin == path.dirname(path.abspath(sys.argv[0])) + assert o.home == home.path + assert o.dot_ipa == home.join('.ipa') assert o.in_tree is False assert o.context == 'default' assert o.conf == '/etc/ipa/default.conf' @@ -422,6 +422,7 @@ class test_Env(ClassChecker): no_exist = tmp.join('no_exist.conf') assert not path.exists(no_exist) o = self.cls() + o._bootstrap() keys = tuple(o) orig = dict((k, o[k]) for k in o) assert o._merge_config(no_exist) is None diff --git a/tests/util.py b/tests/util.py index 22b8a770..4a74d294 100644 --- a/tests/util.py +++ b/tests/util.py @@ -84,10 +84,6 @@ class TempHome(TempDir): self.__home = os.environ['HOME'] os.environ['HOME'] = self.path - def rmtree(self): - os.environ['HOME'] = self.__home - super(TempHome, self).rmtree() - class ExceptionNotRaised(Exception): """ |