Support moving options between groups

Registered by Mark McLoughlin

It's quite a common requirement to want to move an option from e.g. the DEFAULT group to a more specialized group.

When you do so, you want to support existing use of the option in the previous group and issue a deprecation warning when doing so.

It's also quite common to want to rename an option while doing so e.g. CONF.rabbit_host -> CONF.rabbit.host

Right now, you need to do something like this:

  CONF.register_opt(StrOpt('root_helper'))
  CONF.register_opt(StrOpt('root_helper'), group='agent')

  def get_root_helper():
      root_helper = CONF.agent.root_helper
      if root_helper is not None:
          return root_helper

      root_helper = CONF.root_helper:
      if root_helper is not None:
          warn('DEFAULT.root_helper is deprecated!')
          return root_helper

      return 'foo'

but it would be much nicer if you could do e.g.

  rabbit_opts = [
      cfg.StrOpt('host',
                            default='localhost',
                            deprecated_name='DEFAULT', 'rabbit_host')),

  ]

  CONF.register_opt(rabbit_opts, group='rabbit')

What is not ideal about that is that an Opt object doesn't know what group(s) it is registered with, yet here we are encoding information about what group it was *previously* registered with.

Perhaps:

  rabbit_opts = [
      cfg.StrOpt('host',
                            default='localhost'),
  ]

  deprecated_opts = {
      'host': ('DEFAULT', 'rabbit_host'),
  }

  CONF.register_opts(rabbit_opt, group='rabbit')
  CONF.register_deprecated_opts(deprecated_opts, group='rabbit')

and in the singular:

  CONF.register_opt(cfg.StrOpt('host', default='localhost'), group='rabbit')
  CONF.register_deprecated_opt('host', ('DEFAULT', 'rabbot_host'), group='rabbit')

I guess there are three ways you could represent a group and option ...

  1) As a string is nasty but simple

        'DEFAULT.rabbit_host'

  2) As a tuple which is nicer but the semantics of the order of the elements is a little magic:

        ('DEFAULT', 'rabbit_host')

  3) As a dict which is much more clear, but also more verbose:

       dict(name='rabbit_host', group='DEFAULT')

although, in the case of the default group, maybe we can just do 'rabbit_host' and assume DEFAULT because no group is specified. Meh.

Blueprint information

Status:
Complete
Approver:
Mark McLoughlin
Priority:
High
Drafter:
Mark McLoughlin
Direction:
Approved
Assignee:
Mark McLoughlin
Definition:
Approved
Series goal:
Accepted for grizzly
Implementation:
Implemented
Milestone target:
milestone icon 2013.1
Started by
Mark McLoughlin
Completed by
Mark McLoughlin

Related branches

Sprints

(?)

Work Items

This blueprint contains Public information 
Everyone can see this information.