Add import_opt() method to ConfigOpts

Related to blueprint cfg-global-object

When using the global config object pattern, you often have modules
which define options that are referenced in other options.

So, for example if module A defined option 'foo' and module be needed
to reference that option, you might do:

  import A
  print CONF.foo

However, this makes it entirely unclear to the casual reader why
module A was imported.

Nova has a flags.DECLARE() function that helps with this problem
by allowing you to do:

  flags.DECLARE('foo', 'A')

The function simply imports module A and checks that the 'foo'
option is now defined in the global config object.

This is fine, but it is also implicit that this function applies
to the global config object. Instead, let's do the following:

  CONF.import_opt('foo', 'A')

Change-Id: I7b98f5be71068bbde70cc0eab991eaebb577de52
This commit is contained in:
Mark McLoughlin 2012-07-31 12:16:28 +01:00
parent e0134fc3e2
commit 038d59778e
5 changed files with 102 additions and 0 deletions

View File

@ -1156,6 +1156,25 @@ class ConfigOpts(collections.Mapping):
for opt in opts:
self.unregister_opt(opt, group, clear_cache=False)
def import_opt(self, name, module_str, group=None):
"""Import an option definition from a module.
Import a module and check that a given option is registered.
This is intended for use with global configuration objects
like cfg.CONF where modules commonly register options with
CONF at module load time. If one module requires an option
defined by another module it can use this method to explicitly
declare the dependency.
:param name: the name/dest of the opt
:param module_str: the name of a module to import
:param group: an option OptGroup object or group name
:raises: NoSuchOptError, NoSuchGroupError
"""
__import__(module_str)
self._get_opt_info(name, group)
@__clear_cache
def set_override(self, name, override, group=None):
"""Override an opt value.

View File

@ -0,0 +1,15 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

View File

@ -0,0 +1,21 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.common import cfg
CONF = cfg.CONF
CONF.register_opt(cfg.StrOpt('foo'), group='bar')

View File

@ -0,0 +1,21 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.common import cfg
CONF = cfg.CONF
CONF.register_opt(cfg.StrOpt('blaa'))

View File

@ -1111,6 +1111,32 @@ class UnregisterOptTestCase(BaseTestCase):
self.assertFalse(hasattr(self.conf.blaa, 'foo'))
class ImportOptTestCase(BaseTestCase):
def test_import_opt(self):
self.assertFalse(hasattr(CONF, 'blaa'))
CONF.import_opt('blaa', 'tests.testmods.blaa_opt')
self.assertTrue(hasattr(CONF, 'blaa'))
def test_import_opt_in_group(self):
self.assertFalse(hasattr(CONF, 'bar'))
CONF.import_opt('foo', 'tests.testmods.bar_foo_opt', group='bar')
self.assertTrue(hasattr(CONF, 'bar'))
self.assertTrue(hasattr(CONF.bar, 'foo'))
def test_import_opt_import_errror(self):
self.assertRaises(ImportError, CONF.import_opt,
'blaa', 'tests.testmods.blaablaa_opt')
def test_import_opt_no_such_opt(self):
self.assertRaises(NoSuchOptError, CONF.import_opt,
'blaablaa', 'tests.testmods.blaa_opt')
def test_import_opt_no_such_group(self):
self.assertRaises(NoSuchGroupError, CONF.import_opt,
'blaa', 'tests.testmods.blaa_opt', group='blaa')
class RequiredOptsTestCase(BaseTestCase):
def setUp(self):