Improve cfg's argparse sub-parsers support

In order for sub-parsers to be useful, you need some way of knowing
which sub-parser was chosen during argument parsing. It's pretty obvious
from the current sub-parsers test case that we don't have a convenient
interface for this.

One way of doing it is to use the 'dest' argument when adding
sub-parsers:

  >>> subparsers = parser.add_subparsers(dest='cmd')
  >>> subparsers.add_parser('a')
  >>> subparsers.add_parser('b')
  >>> parser.parse_args(['a'])
  Namespace(cmd='a')

The most sensible way to map this into cfg concepts is to register
sub-parsers as an Opt. This way, we can make name and argument values
of the sub-parser as an attribute on the ConfigOpts object:

  >>> def add_parsers(subparsers):
  ...     a = subparsers.add_parser('a')
  ...     a.add_argument('id')
  ...     b = subparsers.add_parser('b')
  ...
  >>> CONF.register_cli_opt(SubCommandOpt('cmd', handler=add_parsers))
  True
  >>> CONF(['a', '10'])
  >>> CONF.cmd.name, CONF.cmd.id
  ('a', '10')

The handler method is a bit awkward, but each time cfg is to parse
command line args it takes all the registered opts and creates a new
argparse parser. So we need to be able to re-add the sub-parsers each
time.

Change-Id: I01bfd01bf8853cf57a9248b1663eb3da142366a4
Add a CLI argument validation utility

blueprint oslo-cliutils

In nova-manage and cinder-manage, we allow command arguments to be
passed as optional or positional arguments.

e.g.

  $> nova-manage floating create 10.0.0.1/28
  $> nova-manage floating create --ip_range 10.0.0.1/28

are equivalent.

Once nova-manage has collected those arguments, it calls the
appropriate command function with them as positional and keyword
arguments. If the user forgets to supply a required argument, they
merely get a TypeError with little useful information.

Improve the usability of these commands using a new utility function
to check that the required arguments have been supplied and raise a
useful exception if not.

Change-Id: If6e4a9f222a30472bbfbcd06859865bd4e37e139
Fixes import nit in test_zmq

Fixes bug #1084821

Change-Id: I1199d264b911036d142c6d1b58a41d740d795dd5
Rename utils.py to strutils.py

Fixes bug #1083956

Change-Id: I681227e9428778adb7824a1930a33cfa5ffa13a1
Use json instead of jsonutils in rpc.impl_fake.

The fake rpc backend uses json just to make sure the data that was
passed in can be serialized.  Our jsonutils module makes this check a
no-op, because it will automatically convert the data we pass in as
primitive types if needed.  Change this module back to using the json
module directly and add a comment about why we don't use jsonutils here.

Also add a test that ensures that non-primitive types raise an exception
in the fake rpc driver.

Change-Id: I61f46242cb98c875a94d86283e30efb24cc580ad
Fixes update.py issue with EOL style on Windows

Fixes Bug #1075230

Files are saved with the OS EOL conversion unless "b" is specified
in open(...). In this case we want to preserve the original EOL
convention.

Change-Id: Id756174d03c3e95db055d512ec4aa5a0eeb768b8
Fix set_default() with boolean CLI options

Porting to argparse broke set_default() with boolean CLI options. The
new test case shows this borkage.

The issue is that, by default, argparse differs subtly from optparse in
its handling of defaults for boolean options. Compare:

  >>> p = optparse.OptionParser()
  >>> p.add_option('--foo', action='store_true')
  >>> p.add_option('--bar', action='store_true', default=False)
  >>> p.parse_args([])
  (<Values at 0x7f28aba066c8: {'foo': None, 'bar': False}>, [])

to:

  >>> p = argparse.ArgumentParser()
  >>> p.add_argument('--foo', action='store_true')
  >>> p.add_argument('--bar', action='store_true', default=False)
  >>> p.add_argument('--blaa', action='store_true', default=None)
  >>> p.parse_args([])
  Namespace(bar=False, blaa=None, foo=False)

i.e. unless you specify a default for a boolean option, optparse
defaults to None whereas argparse defaults to False. To get the
same optparse behaviour with argparse, you need default=None.

Change-Id: Ifc92a834c4ba59e939d80ac5de24d7051232f5b5
Merge "Fixes import nit in test_zmq"
Merge "Fixes update.py issue with EOL style on Windows"
Merge "Rename utils.py to strutils.py"
Merge "Improve cfg's argparse sub-parsers support"
Merge "Fix set_default() with boolean CLI options"
Fixing modulename so eventlet will log properly.

Fixes bug 1086063

Change-Id: I1ebc3243b6db242279b05424c99013dbcf703703
Merge "Fixing modulename so eventlet will log properly."
Merge "Add a CLI argument validation utility"
Fix import order in openstack/common/lockutils.py

Change-Id: Ia1dfa85a81bae6620c2c24c0c28a589d46ed3b04
Fix broken --version command

The code for lazy loading of version string was broken. The way it
breaks in glance and oslo is different. This patch is just for oslo.
Here we end up overriding more methods in our lazy string class to make
argparse happy and added test cases to make sure we don't break again.
we also sure we cache the result of the lookup so we return the same
version everytime and for performance. Added a few test cases as well.

Fixes LP #1085984

Change-Id: I0635899c37fa8e5a7edf282907d2a5e04aa064cb
Allow remote stdlib exceptions to be deserialized

Fixes bug #1086798

Add 'exceptions' to allowed_rpc_exception_modules so that stdlib
exceptions (like NotImplementedError) can be deserialized from a
RemoteError.

Change-Id: I57f40fed2a86cc08fb64b81d648c71cd7db8027c
Fix qpid cast_to_server regression.

This patches addresses a regression in the qpid driver for the
cast_to_server and fanout_cast_to_server methods.  The regression was
introduced in 86952852c1dadd54f1294ae0adba01cfe827b8ce.

There are test cases that cover this code, but unfortunately they are
not being run by jenkins because python-qpid is not available in pypi.

Fix bug 1086848.

Change-Id: I89d4f81149f9a05c578b5ec544c5e34311484c6c
Merge "Fix broken --version command"