diff --git a/cli/__init__.py b/cli/__init__.py
index e97fe3e..2548f24 100644
--- a/cli/__init__.py
+++ b/cli/__init__.py
@@ -19,9 +19,11 @@
 import shlex
 import subprocess
 
-from tempest.openstack.common import cfg
+from oslo.config import cfg
+
 import tempest.test
 
+
 LOG = logging.getLogger(__name__)
 
 cli_opts = [
diff --git a/cli/simple_read_only/test_compute.py b/cli/simple_read_only/test_compute.py
index 849ed6f..bcdd2c5 100644
--- a/cli/simple_read_only/test_compute.py
+++ b/cli/simple_read_only/test_compute.py
@@ -18,11 +18,11 @@
 import logging
 import subprocess
 
+from oslo.config import cfg
 import testtools
 
 import cli
-
-from tempest.openstack.common import cfg
+from tempest import config
 
 
 CONF = cfg.CONF
diff --git a/openstack-common.conf b/openstack-common.conf
index 0c9e43e..501328c 100644
--- a/openstack-common.conf
+++ b/openstack-common.conf
@@ -1,7 +1,7 @@
 [DEFAULT]
 
 # The list of modules to copy from openstack-common
-modules=setup,cfg,iniparser,install_venv_common
+modules=setup,install_venv_common
 
 # The base module to hold the copy of openstack.common
 base=tempest
diff --git a/tempest/clients.py b/tempest/clients.py
index 16f73d3..b3b5906 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -53,6 +53,7 @@
 from tempest.services.identity.xml.identity_client import IdentityClientXML
 from tempest.services.identity.xml.identity_client import TokenClientXML
 from tempest.services.image.v1.json.image_client import ImageClientJSON
+from tempest.services.image.v2.json.image_client import ImageClientV2JSON
 from tempest.services.network.json.network_client import NetworkClient
 from tempest.services.object_storage.account_client import AccountClient
 from tempest.services.object_storage.account_client import \
@@ -225,6 +226,7 @@
         self.hosts_client = HostsClientJSON(*client_args)
         self.account_client = AccountClient(*client_args)
         self.image_client = ImageClientJSON(*client_args)
+        self.image_client_v2 = ImageClientV2JSON(*client_args)
         self.container_client = ContainerClient(*client_args)
         self.object_client = ObjectClient(*client_args)
         self.ec2api_client = botoclients.APIClientEC2(*client_args)
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
index 151060f..be6fe27 100644
--- a/tempest/common/ssh.py
+++ b/tempest/common/ssh.py
@@ -106,6 +106,7 @@
         ssh = self._get_ssh_connection()
         transport = ssh.get_transport()
         channel = transport.open_session()
+        channel.fileno()  # Register event pipe
         channel.exec_command(cmd)
         channel.shutdown_write()
         out_data = []
diff --git a/tempest/config.py b/tempest/config.py
index 2f4ce6a..3a4a8c9 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -19,8 +19,9 @@
 import os
 import sys
 
+from oslo.config import cfg
+
 from tempest.common.utils.misc import singleton
-from tempest.openstack.common import cfg
 
 LOG = logging.getLogger(__name__)
 
diff --git a/tempest/openstack/common/cfg.py b/tempest/openstack/common/cfg.py
deleted file mode 100644
index cae4ecc..0000000
--- a/tempest/openstack/common/cfg.py
+++ /dev/null
@@ -1,1749 +0,0 @@
-# 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.
-
-r"""
-Configuration options which may be set on the command line or in config files.
-
-The schema for each option is defined using the Opt sub-classes, e.g.:
-
-::
-
-    common_opts = [
-        cfg.StrOpt('bind_host',
-                   default='0.0.0.0',
-                   help='IP address to listen on'),
-        cfg.IntOpt('bind_port',
-                   default=9292,
-                   help='Port number to listen on')
-    ]
-
-Options can be strings, integers, floats, booleans, lists or 'multi strings'::
-
-    enabled_apis_opt = cfg.ListOpt('enabled_apis',
-                                   default=['ec2', 'osapi_compute'],
-                                   help='List of APIs to enable by default')
-
-    DEFAULT_EXTENSIONS = [
-        'nova.api.openstack.compute.contrib.standard_extensions'
-    ]
-    osapi_compute_extension_opt = cfg.MultiStrOpt('osapi_compute_extension',
-                                                  default=DEFAULT_EXTENSIONS)
-
-Option schemas are registered with the config manager at runtime, but before
-the option is referenced::
-
-    class ExtensionManager(object):
-
-        enabled_apis_opt = cfg.ListOpt(...)
-
-        def __init__(self, conf):
-            self.conf = conf
-            self.conf.register_opt(enabled_apis_opt)
-            ...
-
-        def _load_extensions(self):
-            for ext_factory in self.conf.osapi_compute_extension:
-                ....
-
-A common usage pattern is for each option schema to be defined in the module or
-class which uses the option::
-
-    opts = ...
-
-    def add_common_opts(conf):
-        conf.register_opts(opts)
-
-    def get_bind_host(conf):
-        return conf.bind_host
-
-    def get_bind_port(conf):
-        return conf.bind_port
-
-An option may optionally be made available via the command line. Such options
-must registered with the config manager before the command line is parsed (for
-the purposes of --help and CLI arg validation)::
-
-    cli_opts = [
-        cfg.BoolOpt('verbose',
-                    short='v',
-                    default=False,
-                    help='Print more verbose output'),
-        cfg.BoolOpt('debug',
-                    short='d',
-                    default=False,
-                    help='Print debugging output'),
-    ]
-
-    def add_common_opts(conf):
-        conf.register_cli_opts(cli_opts)
-
-The config manager has two CLI options defined by default, --config-file
-and --config-dir::
-
-    class ConfigOpts(object):
-
-        def __call__(self, ...):
-
-            opts = [
-                MultiStrOpt('config-file',
-                        ...),
-                StrOpt('config-dir',
-                       ...),
-            ]
-
-            self.register_cli_opts(opts)
-
-Option values are parsed from any supplied config files using
-openstack.common.iniparser. If none are specified, a default set is used
-e.g. glance-api.conf and glance-common.conf::
-
-    glance-api.conf:
-      [DEFAULT]
-      bind_port = 9292
-
-    glance-common.conf:
-      [DEFAULT]
-      bind_host = 0.0.0.0
-
-Option values in config files override those on the command line. Config files
-are parsed in order, with values in later files overriding those in earlier
-files.
-
-The parsing of CLI args and config files is initiated by invoking the config
-manager e.g.::
-
-    conf = ConfigOpts()
-    conf.register_opt(BoolOpt('verbose', ...))
-    conf(sys.argv[1:])
-    if conf.verbose:
-        ...
-
-Options can be registered as belonging to a group::
-
-    rabbit_group = cfg.OptGroup(name='rabbit',
-                                title='RabbitMQ options')
-
-    rabbit_host_opt = cfg.StrOpt('host',
-                                 default='localhost',
-                                 help='IP/hostname to listen on'),
-    rabbit_port_opt = cfg.IntOpt('port',
-                                 default=5672,
-                                 help='Port number to listen on')
-
-    def register_rabbit_opts(conf):
-        conf.register_group(rabbit_group)
-        # options can be registered under a group in either of these ways:
-        conf.register_opt(rabbit_host_opt, group=rabbit_group)
-        conf.register_opt(rabbit_port_opt, group='rabbit')
-
-If it no group attributes are required other than the group name, the group
-need not be explicitly registered e.g.
-
-    def register_rabbit_opts(conf):
-        # The group will automatically be created, equivalent calling::
-        #   conf.register_group(OptGroup(name='rabbit'))
-        conf.register_opt(rabbit_port_opt, group='rabbit')
-
-If no group is specified, options belong to the 'DEFAULT' section of config
-files::
-
-    glance-api.conf:
-      [DEFAULT]
-      bind_port = 9292
-      ...
-
-      [rabbit]
-      host = localhost
-      port = 5672
-      use_ssl = False
-      userid = guest
-      password = guest
-      virtual_host = /
-
-Command-line options in a group are automatically prefixed with the
-group name::
-
-    --rabbit-host localhost --rabbit-port 9999
-
-Option values in the default group are referenced as attributes/properties on
-the config manager; groups are also attributes on the config manager, with
-attributes for each of the options associated with the group::
-
-    server.start(app, conf.bind_port, conf.bind_host, conf)
-
-    self.connection = kombu.connection.BrokerConnection(
-        hostname=conf.rabbit.host,
-        port=conf.rabbit.port,
-        ...)
-
-Option values may reference other values using PEP 292 string substitution::
-
-    opts = [
-        cfg.StrOpt('state_path',
-                   default=os.path.join(os.path.dirname(__file__), '../'),
-                   help='Top-level directory for maintaining nova state'),
-        cfg.StrOpt('sqlite_db',
-                   default='nova.sqlite',
-                   help='file name for sqlite'),
-        cfg.StrOpt('sql_connection',
-                   default='sqlite:///$state_path/$sqlite_db',
-                   help='connection string for sql database'),
-    ]
-
-Note that interpolation can be avoided by using '$$'.
-
-Options may be declared as required so that an error is raised if the user
-does not supply a value for the option.
-
-Options may be declared as secret so that their values are not leaked into
-log files::
-
-     opts = [
-        cfg.StrOpt('s3_store_access_key', secret=True),
-        cfg.StrOpt('s3_store_secret_key', secret=True),
-        ...
-     ]
-
-This module also contains a global instance of the ConfigOpts class
-in order to support a common usage pattern in OpenStack::
-
-    from tempest.openstack.common import cfg
-
-    opts = [
-        cfg.StrOpt('bind_host', default='0.0.0.0'),
-        cfg.IntOpt('bind_port', default=9292),
-    ]
-
-    CONF = cfg.CONF
-    CONF.register_opts(opts)
-
-    def start(server, app):
-        server.start(app, CONF.bind_port, CONF.bind_host)
-
-Positional command line arguments are supported via a 'positional' Opt
-constructor argument::
-
-    >>> conf = ConfigOpts()
-    >>> conf.register_cli_opt(MultiStrOpt('bar', positional=True))
-    True
-    >>> conf(['a', 'b'])
-    >>> conf.bar
-    ['a', 'b']
-
-It is also possible to use argparse "sub-parsers" to parse additional
-command line arguments using the SubCommandOpt class:
-
-    >>> def add_parsers(subparsers):
-    ...     list_action = subparsers.add_parser('list')
-    ...     list_action.add_argument('id')
-    ...
-    >>> conf = ConfigOpts()
-    >>> conf.register_cli_opt(SubCommandOpt('action', handler=add_parsers))
-    True
-    >>> conf(args=['list', '10'])
-    >>> conf.action.name, conf.action.id
-    ('list', '10')
-
-"""
-
-import argparse
-import collections
-import copy
-import functools
-import glob
-import os
-import string
-import sys
-
-from tempest.openstack.common import iniparser
-
-
-class Error(Exception):
-    """Base class for cfg exceptions."""
-
-    def __init__(self, msg=None):
-        self.msg = msg
-
-    def __str__(self):
-        return self.msg
-
-
-class ArgsAlreadyParsedError(Error):
-    """Raised if a CLI opt is registered after parsing."""
-
-    def __str__(self):
-        ret = "arguments already parsed"
-        if self.msg:
-            ret += ": " + self.msg
-        return ret
-
-
-class NoSuchOptError(Error, AttributeError):
-    """Raised if an opt which doesn't exist is referenced."""
-
-    def __init__(self, opt_name, group=None):
-        self.opt_name = opt_name
-        self.group = group
-
-    def __str__(self):
-        if self.group is None:
-            return "no such option: %s" % self.opt_name
-        else:
-            return "no such option in group %s: %s" % (self.group.name,
-                                                       self.opt_name)
-
-
-class NoSuchGroupError(Error):
-    """Raised if a group which doesn't exist is referenced."""
-
-    def __init__(self, group_name):
-        self.group_name = group_name
-
-    def __str__(self):
-        return "no such group: %s" % self.group_name
-
-
-class DuplicateOptError(Error):
-    """Raised if multiple opts with the same name are registered."""
-
-    def __init__(self, opt_name):
-        self.opt_name = opt_name
-
-    def __str__(self):
-        return "duplicate option: %s" % self.opt_name
-
-
-class RequiredOptError(Error):
-    """Raised if an option is required but no value is supplied by the user."""
-
-    def __init__(self, opt_name, group=None):
-        self.opt_name = opt_name
-        self.group = group
-
-    def __str__(self):
-        if self.group is None:
-            return "value required for option: %s" % self.opt_name
-        else:
-            return "value required for option: %s.%s" % (self.group.name,
-                                                         self.opt_name)
-
-
-class TemplateSubstitutionError(Error):
-    """Raised if an error occurs substituting a variable in an opt value."""
-
-    def __str__(self):
-        return "template substitution error: %s" % self.msg
-
-
-class ConfigFilesNotFoundError(Error):
-    """Raised if one or more config files are not found."""
-
-    def __init__(self, config_files):
-        self.config_files = config_files
-
-    def __str__(self):
-        return ('Failed to read some config files: %s' %
-                string.join(self.config_files, ','))
-
-
-class ConfigFileParseError(Error):
-    """Raised if there is an error parsing a config file."""
-
-    def __init__(self, config_file, msg):
-        self.config_file = config_file
-        self.msg = msg
-
-    def __str__(self):
-        return 'Failed to parse %s: %s' % (self.config_file, self.msg)
-
-
-class ConfigFileValueError(Error):
-    """Raised if a config file value does not match its opt type."""
-    pass
-
-
-def _fixpath(p):
-    """Apply tilde expansion and absolutization to a path."""
-    return os.path.abspath(os.path.expanduser(p))
-
-
-def _get_config_dirs(project=None):
-    """Return a list of directors where config files may be located.
-
-    :param project: an optional project name
-
-    If a project is specified, following directories are returned::
-
-      ~/.${project}/
-      ~/
-      /etc/${project}/
-      /etc/
-
-    Otherwise, these directories::
-
-      ~/
-      /etc/
-    """
-    cfg_dirs = [
-        _fixpath(os.path.join('~', '.' + project)) if project else None,
-        _fixpath('~'),
-        os.path.join('/etc', project) if project else None,
-        '/etc'
-    ]
-
-    return filter(bool, cfg_dirs)
-
-
-def _search_dirs(dirs, basename, extension=""):
-    """Search a list of directories for a given filename.
-
-    Iterator over the supplied directories, returning the first file
-    found with the supplied name and extension.
-
-    :param dirs: a list of directories
-    :param basename: the filename, e.g. 'glance-api'
-    :param extension: the file extension, e.g. '.conf'
-    :returns: the path to a matching file, or None
-    """
-    for d in dirs:
-        path = os.path.join(d, '%s%s' % (basename, extension))
-        if os.path.exists(path):
-            return path
-
-
-def find_config_files(project=None, prog=None, extension='.conf'):
-    """Return a list of default configuration files.
-
-    :param project: an optional project name
-    :param prog: the program name, defaulting to the basename of sys.argv[0]
-    :param extension: the type of the config file
-
-    We default to two config files: [${project}.conf, ${prog}.conf]
-
-    And we look for those config files in the following directories::
-
-      ~/.${project}/
-      ~/
-      /etc/${project}/
-      /etc/
-
-    We return an absolute path for (at most) one of each the default config
-    files, for the topmost directory it exists in.
-
-    For example, if project=foo, prog=bar and /etc/foo/foo.conf, /etc/bar.conf
-    and ~/.foo/bar.conf all exist, then we return ['/etc/foo/foo.conf',
-    '~/.foo/bar.conf']
-
-    If no project name is supplied, we only look for ${prog.conf}.
-    """
-    if prog is None:
-        prog = os.path.basename(sys.argv[0])
-
-    cfg_dirs = _get_config_dirs(project)
-
-    config_files = []
-    if project:
-        config_files.append(_search_dirs(cfg_dirs, project, extension))
-    config_files.append(_search_dirs(cfg_dirs, prog, extension))
-
-    return filter(bool, config_files)
-
-
-def _is_opt_registered(opts, opt):
-    """Check whether an opt with the same name is already registered.
-
-    The same opt may be registered multiple times, with only the first
-    registration having any effect. However, it is an error to attempt
-    to register a different opt with the same name.
-
-    :param opts: the set of opts already registered
-    :param opt: the opt to be registered
-    :returns: True if the opt was previously registered, False otherwise
-    :raises: DuplicateOptError if a naming conflict is detected
-    """
-    if opt.dest in opts:
-        if opts[opt.dest]['opt'] != opt:
-            raise DuplicateOptError(opt.name)
-        return True
-    else:
-        return False
-
-
-def set_defaults(opts, **kwargs):
-    for opt in opts:
-        if opt.dest in kwargs:
-            opt.default = kwargs[opt.dest]
-            break
-
-
-class Opt(object):
-
-    """Base class for all configuration options.
-
-    An Opt object has no public methods, but has a number of public string
-    properties:
-
-      name:
-        the name of the option, which may include hyphens
-      dest:
-        the (hyphen-less) ConfigOpts property which contains the option value
-      short:
-        a single character CLI option name
-      default:
-        the default value of the option
-      positional:
-        True if the option is a positional CLI argument
-      metavar:
-        the name shown as the argument to a CLI option in --help output
-      help:
-        an string explaining how the options value is used
-    """
-    multi = False
-
-    def __init__(self, name, dest=None, short=None, default=None,
-                 positional=False, metavar=None, help=None,
-                 secret=False, required=False, deprecated_name=None):
-        """Construct an Opt object.
-
-        The only required parameter is the option's name. However, it is
-        common to also supply a default and help string for all options.
-
-        :param name: the option's name
-        :param dest: the name of the corresponding ConfigOpts property
-        :param short: a single character CLI option name
-        :param default: the default value of the option
-        :param positional: True if the option is a positional CLI argument
-        :param metavar: the option argument to show in --help
-        :param help: an explanation of how the option is used
-        :param secret: true iff the value should be obfuscated in log output
-        :param required: true iff a value must be supplied for this option
-        :param deprecated_name: deprecated name option.  Acts like an alias
-        """
-        self.name = name
-        if dest is None:
-            self.dest = self.name.replace('-', '_')
-        else:
-            self.dest = dest
-        self.short = short
-        self.default = default
-        self.positional = positional
-        self.metavar = metavar
-        self.help = help
-        self.secret = secret
-        self.required = required
-        if deprecated_name is not None:
-            self.deprecated_name = deprecated_name.replace('-', '_')
-        else:
-            self.deprecated_name = None
-
-    def __ne__(self, another):
-        return vars(self) != vars(another)
-
-    def _get_from_config_parser(self, cparser, section):
-        """Retrieves the option value from a MultiConfigParser object.
-
-        This is the method ConfigOpts uses to look up the option value from
-        config files. Most opt types override this method in order to perform
-        type appropriate conversion of the returned value.
-
-        :param cparser: a ConfigParser object
-        :param section: a section name
-        """
-        return self._cparser_get_with_deprecated(cparser, section)
-
-    def _cparser_get_with_deprecated(self, cparser, section):
-        """If cannot find option as dest try deprecated_name alias."""
-        if self.deprecated_name is not None:
-            return cparser.get(section, [self.dest, self.deprecated_name])
-        return cparser.get(section, [self.dest])
-
-    def _add_to_cli(self, parser, group=None):
-        """Makes the option available in the command line interface.
-
-        This is the method ConfigOpts uses to add the opt to the CLI interface
-        as appropriate for the opt type. Some opt types may extend this method,
-        others may just extend the helper methods it uses.
-
-        :param parser: the CLI option parser
-        :param group: an optional OptGroup object
-        """
-        container = self._get_argparse_container(parser, group)
-        kwargs = self._get_argparse_kwargs(group)
-        prefix = self._get_argparse_prefix('', group)
-        self._add_to_argparse(container, self.name, self.short, kwargs, prefix,
-                              self.positional, self.deprecated_name)
-
-    def _add_to_argparse(self, container, name, short, kwargs, prefix='',
-                         positional=False, deprecated_name=None):
-        """Add an option to an argparse parser or group.
-
-        :param container: an argparse._ArgumentGroup object
-        :param name: the opt name
-        :param short: the short opt name
-        :param kwargs: the keyword arguments for add_argument()
-        :param prefix: an optional prefix to prepend to the opt name
-        :param position: whether the optional is a positional CLI argument
-        :raises: DuplicateOptError if a naming confict is detected
-        """
-        def hyphen(arg):
-            return arg if not positional else ''
-
-        args = [hyphen('--') + prefix + name]
-        if short:
-            args.append(hyphen('-') + short)
-        if deprecated_name:
-            args.append(hyphen('--') + prefix + deprecated_name)
-
-        try:
-            container.add_argument(*args, **kwargs)
-        except argparse.ArgumentError as e:
-            raise DuplicateOptError(e)
-
-    def _get_argparse_container(self, parser, group):
-        """Returns an argparse._ArgumentGroup.
-
-        :param parser: an argparse.ArgumentParser
-        :param group: an (optional) OptGroup object
-        :returns: an argparse._ArgumentGroup if group is given, else parser
-        """
-        if group is not None:
-            return group._get_argparse_group(parser)
-        else:
-            return parser
-
-    def _get_argparse_kwargs(self, group, **kwargs):
-        """Build a dict of keyword arguments for argparse's add_argument().
-
-        Most opt types extend this method to customize the behaviour of the
-        options added to argparse.
-
-        :param group: an optional group
-        :param kwargs: optional keyword arguments to add to
-        :returns: a dict of keyword arguments
-        """
-        if not self.positional:
-            dest = self.dest
-            if group is not None:
-                dest = group.name + '_' + dest
-            kwargs['dest'] = dest
-        else:
-            kwargs['nargs'] = '?'
-        kwargs.update({'default': None,
-                       'metavar': self.metavar,
-                       'help': self.help, })
-        return kwargs
-
-    def _get_argparse_prefix(self, prefix, group):
-        """Build a prefix for the CLI option name, if required.
-
-        CLI options in a group are prefixed with the group's name in order
-        to avoid conflicts between similarly named options in different
-        groups.
-
-        :param prefix: an existing prefix to append to (e.g. 'no' or '')
-        :param group: an optional OptGroup object
-        :returns: a CLI option prefix including the group name, if appropriate
-        """
-        if group is not None:
-            return group.name + '-' + prefix
-        else:
-            return prefix
-
-
-class StrOpt(Opt):
-    """
-    String opts do not have their values transformed and are returned as
-    str objects.
-    """
-    pass
-
-
-class BoolOpt(Opt):
-
-    """
-    Bool opts are set to True or False on the command line using --optname or
-    --noopttname respectively.
-
-    In config files, boolean values are case insensitive and can be set using
-    1/0, yes/no, true/false or on/off.
-    """
-
-    _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
-                       '0': False, 'no': False, 'false': False, 'off': False}
-
-    def __init__(self, *args, **kwargs):
-        if 'positional' in kwargs:
-            raise ValueError('positional boolean args not supported')
-        super(BoolOpt, self).__init__(*args, **kwargs)
-
-    def _get_from_config_parser(self, cparser, section):
-        """Retrieve the opt value as a boolean from ConfigParser."""
-        def convert_bool(v):
-            value = self._boolean_states.get(v.lower())
-            if value is None:
-                raise ValueError('Unexpected boolean value %r' % v)
-
-            return value
-
-        return [convert_bool(v) for v in
-                self._cparser_get_with_deprecated(cparser, section)]
-
-    def _add_to_cli(self, parser, group=None):
-        """Extends the base class method to add the --nooptname option."""
-        super(BoolOpt, self)._add_to_cli(parser, group)
-        self._add_inverse_to_argparse(parser, group)
-
-    def _add_inverse_to_argparse(self, parser, group):
-        """Add the --nooptname option to the option parser."""
-        container = self._get_argparse_container(parser, group)
-        kwargs = self._get_argparse_kwargs(group, action='store_false')
-        prefix = self._get_argparse_prefix('no', group)
-        kwargs["help"] = "The inverse of --" + self.name
-        self._add_to_argparse(container, self.name, None, kwargs, prefix,
-                              self.positional, self.deprecated_name)
-
-    def _get_argparse_kwargs(self, group, action='store_true', **kwargs):
-        """Extends the base argparse keyword dict for boolean options."""
-
-        kwargs = super(BoolOpt, self)._get_argparse_kwargs(group, **kwargs)
-
-        # metavar has no effect for BoolOpt
-        if 'metavar' in kwargs:
-            del kwargs['metavar']
-
-        if action != 'store_true':
-            action = 'store_false'
-
-        kwargs['action'] = action
-
-        return kwargs
-
-
-class IntOpt(Opt):
-
-    """Int opt values are converted to integers using the int() builtin."""
-
-    def _get_from_config_parser(self, cparser, section):
-        """Retrieve the opt value as a integer from ConfigParser."""
-        return [int(v) for v in self._cparser_get_with_deprecated(cparser,
-                section)]
-
-    def _get_argparse_kwargs(self, group, **kwargs):
-        """Extends the base argparse keyword dict for integer options."""
-        return super(IntOpt,
-                     self)._get_argparse_kwargs(group, type=int, **kwargs)
-
-
-class FloatOpt(Opt):
-
-    """Float opt values are converted to floats using the float() builtin."""
-
-    def _get_from_config_parser(self, cparser, section):
-        """Retrieve the opt value as a float from ConfigParser."""
-        return [float(v) for v in
-                self._cparser_get_with_deprecated(cparser, section)]
-
-    def _get_argparse_kwargs(self, group, **kwargs):
-        """Extends the base argparse keyword dict for float options."""
-        return super(FloatOpt, self)._get_argparse_kwargs(group,
-                                                          type=float, **kwargs)
-
-
-class ListOpt(Opt):
-
-    """
-    List opt values are simple string values separated by commas. The opt value
-    is a list containing these strings.
-    """
-
-    class _StoreListAction(argparse.Action):
-        """
-        An argparse action for parsing an option value into a list.
-        """
-        def __call__(self, parser, namespace, values, option_string=None):
-            if values is not None:
-                values = [a.strip() for a in values.split(',')]
-            setattr(namespace, self.dest, values)
-
-    def _get_from_config_parser(self, cparser, section):
-        """Retrieve the opt value as a list from ConfigParser."""
-        return [[a.strip() for a in v.split(',')] for v in
-                self._cparser_get_with_deprecated(cparser, section)]
-
-    def _get_argparse_kwargs(self, group, **kwargs):
-        """Extends the base argparse keyword dict for list options."""
-        return Opt._get_argparse_kwargs(self,
-                                        group,
-                                        action=ListOpt._StoreListAction,
-                                        **kwargs)
-
-
-class MultiStrOpt(Opt):
-
-    """
-    Multistr opt values are string opts which may be specified multiple times.
-    The opt value is a list containing all the string values specified.
-    """
-    multi = True
-
-    def _get_argparse_kwargs(self, group, **kwargs):
-        """Extends the base argparse keyword dict for multi str options."""
-        kwargs = super(MultiStrOpt, self)._get_argparse_kwargs(group)
-        if not self.positional:
-            kwargs['action'] = 'append'
-        else:
-            kwargs['nargs'] = '*'
-        return kwargs
-
-    def _cparser_get_with_deprecated(self, cparser, section):
-        """If cannot find option as dest try deprecated_name alias."""
-        if self.deprecated_name is not None:
-            return cparser.get(section, [self.dest, self.deprecated_name],
-                               multi=True)
-        return cparser.get(section, [self.dest], multi=True)
-
-
-class SubCommandOpt(Opt):
-
-    """
-    Sub-command options allow argparse sub-parsers to be used to parse
-    additional command line arguments.
-
-    The handler argument to the SubCommandOpt contructor is a callable
-    which is supplied an argparse subparsers object. Use this handler
-    callable to add sub-parsers.
-
-    The opt value is SubCommandAttr object with the name of the chosen
-    sub-parser stored in the 'name' attribute and the values of other
-    sub-parser arguments available as additional attributes.
-    """
-
-    def __init__(self, name, dest=None, handler=None,
-                 title=None, description=None, help=None):
-        """Construct an sub-command parsing option.
-
-        This behaves similarly to other Opt sub-classes but adds a
-        'handler' argument. The handler is a callable which is supplied
-        an subparsers object when invoked. The add_parser() method on
-        this subparsers object can be used to register parsers for
-        sub-commands.
-
-        :param name: the option's name
-        :param dest: the name of the corresponding ConfigOpts property
-        :param title: title of the sub-commands group in help output
-        :param description: description of the group in help output
-        :param help: a help string giving an overview of available sub-commands
-        """
-        super(SubCommandOpt, self).__init__(name, dest=dest, help=help)
-        self.handler = handler
-        self.title = title
-        self.description = description
-
-    def _add_to_cli(self, parser, group=None):
-        """Add argparse sub-parsers and invoke the handler method."""
-        dest = self.dest
-        if group is not None:
-            dest = group.name + '_' + dest
-
-        subparsers = parser.add_subparsers(dest=dest,
-                                           title=self.title,
-                                           description=self.description,
-                                           help=self.help)
-
-        if self.handler is not None:
-            self.handler(subparsers)
-
-
-class OptGroup(object):
-
-    """
-    Represents a group of opts.
-
-    CLI opts in the group are automatically prefixed with the group name.
-
-    Each group corresponds to a section in config files.
-
-    An OptGroup object has no public methods, but has a number of public string
-    properties:
-
-      name:
-        the name of the group
-      title:
-        the group title as displayed in --help
-      help:
-        the group description as displayed in --help
-    """
-
-    def __init__(self, name, title=None, help=None):
-        """Constructs an OptGroup object.
-
-        :param name: the group name
-        :param title: the group title for --help
-        :param help: the group description for --help
-        """
-        self.name = name
-        if title is None:
-            self.title = "%s options" % title
-        else:
-            self.title = title
-        self.help = help
-
-        self._opts = {}  # dict of dicts of (opt:, override:, default:)
-        self._argparse_group = None
-
-    def _register_opt(self, opt, cli=False):
-        """Add an opt to this group.
-
-        :param opt: an Opt object
-        :param cli: whether this is a CLI option
-        :returns: False if previously registered, True otherwise
-        :raises: DuplicateOptError if a naming conflict is detected
-        """
-        if _is_opt_registered(self._opts, opt):
-            return False
-
-        self._opts[opt.dest] = {'opt': opt, 'cli': cli}
-
-        return True
-
-    def _unregister_opt(self, opt):
-        """Remove an opt from this group.
-
-        :param opt: an Opt object
-        """
-        if opt.dest in self._opts:
-            del self._opts[opt.dest]
-
-    def _get_argparse_group(self, parser):
-        if self._argparse_group is None:
-            """Build an argparse._ArgumentGroup for this group."""
-            self._argparse_group = parser.add_argument_group(self.title,
-                                                             self.help)
-        return self._argparse_group
-
-    def _clear(self):
-        """Clear this group's option parsing state."""
-        self._argparse_group = None
-
-
-class ParseError(iniparser.ParseError):
-    def __init__(self, msg, lineno, line, filename):
-        super(ParseError, self).__init__(msg, lineno, line)
-        self.filename = filename
-
-    def __str__(self):
-        return 'at %s:%d, %s: %r' % (self.filename, self.lineno,
-                                     self.msg, self.line)
-
-
-class ConfigParser(iniparser.BaseParser):
-    def __init__(self, filename, sections):
-        super(ConfigParser, self).__init__()
-        self.filename = filename
-        self.sections = sections
-        self.section = None
-
-    def parse(self):
-        with open(self.filename) as f:
-            return super(ConfigParser, self).parse(f)
-
-    def new_section(self, section):
-        self.section = section
-        self.sections.setdefault(self.section, {})
-
-    def assignment(self, key, value):
-        if not self.section:
-            raise self.error_no_section()
-
-        self.sections[self.section].setdefault(key, [])
-        self.sections[self.section][key].append('\n'.join(value))
-
-    def parse_exc(self, msg, lineno, line=None):
-        return ParseError(msg, lineno, line, self.filename)
-
-    def error_no_section(self):
-        return self.parse_exc('Section must be started before assignment',
-                              self.lineno)
-
-
-class MultiConfigParser(object):
-    def __init__(self):
-        self.parsed = []
-
-    def read(self, config_files):
-        read_ok = []
-
-        for filename in config_files:
-            sections = {}
-            parser = ConfigParser(filename, sections)
-
-            try:
-                parser.parse()
-            except IOError:
-                continue
-            self.parsed.insert(0, sections)
-            read_ok.append(filename)
-
-        return read_ok
-
-    def get(self, section, names, multi=False):
-        rvalue = []
-        for sections in self.parsed:
-            if section not in sections:
-                continue
-            for name in names:
-                if name in sections[section]:
-                    if multi:
-                        rvalue = sections[section][name] + rvalue
-                    else:
-                        return sections[section][name]
-        if multi and rvalue != []:
-            return rvalue
-        raise KeyError
-
-
-class ConfigOpts(collections.Mapping):
-
-    """
-    Config options which may be set on the command line or in config files.
-
-    ConfigOpts is a configuration option manager with APIs for registering
-    option schemas, grouping options, parsing option values and retrieving
-    the values of options.
-    """
-
-    def __init__(self):
-        """Construct a ConfigOpts object."""
-        self._opts = {}  # dict of dicts of (opt:, override:, default:)
-        self._groups = {}
-
-        self._args = None
-
-        self._oparser = None
-        self._cparser = None
-        self._cli_values = {}
-        self.__cache = {}
-        self._config_opts = []
-
-    def _pre_setup(self, project, prog, version, usage, default_config_files):
-        """Initialize a ConfigCliParser object for option parsing."""
-
-        if prog is None:
-            prog = os.path.basename(sys.argv[0])
-
-        if default_config_files is None:
-            default_config_files = find_config_files(project, prog)
-
-        self._oparser = argparse.ArgumentParser(prog=prog, usage=usage)
-        self._oparser.add_argument('--version',
-                                   action='version',
-                                   version=version)
-
-        return prog, default_config_files
-
-    def _setup(self, project, prog, version, usage, default_config_files):
-        """Initialize a ConfigOpts object for option parsing."""
-
-        self._config_opts = [
-            MultiStrOpt('config-file',
-                        default=default_config_files,
-                        metavar='PATH',
-                        help='Path to a config file to use. Multiple config '
-                             'files can be specified, with values in later '
-                             'files taking precedence. The default files '
-                             ' used are: %s' % (default_config_files, )),
-            StrOpt('config-dir',
-                   metavar='DIR',
-                   help='Path to a config directory to pull *.conf '
-                        'files from. This file set is sorted, so as to '
-                        'provide a predictable parse order if individual '
-                        'options are over-ridden. The set is parsed after '
-                        'the file(s), if any, specified via --config-file, '
-                        'hence over-ridden options in the directory take '
-                        'precedence.'),
-        ]
-        self.register_cli_opts(self._config_opts)
-
-        self.project = project
-        self.prog = prog
-        self.version = version
-        self.usage = usage
-        self.default_config_files = default_config_files
-
-    def __clear_cache(f):
-        @functools.wraps(f)
-        def __inner(self, *args, **kwargs):
-            if kwargs.pop('clear_cache', True):
-                self.__cache.clear()
-            return f(self, *args, **kwargs)
-
-        return __inner
-
-    def __call__(self,
-                 args=None,
-                 project=None,
-                 prog=None,
-                 version=None,
-                 usage=None,
-                 default_config_files=None):
-        """Parse command line arguments and config files.
-
-        Calling a ConfigOpts object causes the supplied command line arguments
-        and config files to be parsed, causing opt values to be made available
-        as attributes of the object.
-
-        The object may be called multiple times, each time causing the previous
-        set of values to be overwritten.
-
-        Automatically registers the --config-file option with either a supplied
-        list of default config files, or a list from find_config_files().
-
-        If the --config-dir option is set, any *.conf files from this
-        directory are pulled in, after all the file(s) specified by the
-        --config-file option.
-
-        :param args: command line arguments (defaults to sys.argv[1:])
-        :param project: the toplevel project name, used to locate config files
-        :param prog: the name of the program (defaults to sys.argv[0] basename)
-        :param version: the program version (for --version)
-        :param usage: a usage string (%prog will be expanded)
-        :param default_config_files: config files to use by default
-        :returns: the list of arguments left over after parsing options
-        :raises: SystemExit, ConfigFilesNotFoundError, ConfigFileParseError,
-                 RequiredOptError, DuplicateOptError
-        """
-
-        self.clear()
-
-        prog, default_config_files = self._pre_setup(project,
-                                                     prog,
-                                                     version,
-                                                     usage,
-                                                     default_config_files)
-
-        self._setup(project, prog, version, usage, default_config_files)
-
-        self._cli_values = self._parse_cli_opts(args)
-
-        self._parse_config_files()
-
-        self._check_required_opts()
-
-    def __getattr__(self, name):
-        """Look up an option value and perform string substitution.
-
-        :param name: the opt name (or 'dest', more precisely)
-        :returns: the option value (after string subsititution) or a GroupAttr
-        :raises: NoSuchOptError,ConfigFileValueError,TemplateSubstitutionError
-        """
-        return self._get(name)
-
-    def __getitem__(self, key):
-        """Look up an option value and perform string substitution."""
-        return self.__getattr__(key)
-
-    def __contains__(self, key):
-        """Return True if key is the name of a registered opt or group."""
-        return key in self._opts or key in self._groups
-
-    def __iter__(self):
-        """Iterate over all registered opt and group names."""
-        for key in self._opts.keys() + self._groups.keys():
-            yield key
-
-    def __len__(self):
-        """Return the number of options and option groups."""
-        return len(self._opts) + len(self._groups)
-
-    def reset(self):
-        """Clear the object state and unset overrides and defaults."""
-        self._unset_defaults_and_overrides()
-        self.clear()
-
-    @__clear_cache
-    def clear(self):
-        """Clear the state of the object to before it was called.
-
-        Any subparsers added using the add_cli_subparsers() will also be
-        removed as a side-effect of this method.
-        """
-        self._args = None
-        self._cli_values.clear()
-        self._oparser = argparse.ArgumentParser()
-        self._cparser = None
-        self.unregister_opts(self._config_opts)
-        for group in self._groups.values():
-            group._clear()
-
-    @__clear_cache
-    def register_opt(self, opt, group=None, cli=False):
-        """Register an option schema.
-
-        Registering an option schema makes any option value which is previously
-        or subsequently parsed from the command line or config files available
-        as an attribute of this object.
-
-        :param opt: an instance of an Opt sub-class
-        :param cli: whether this is a CLI option
-        :param group: an optional OptGroup object or group name
-        :return: False if the opt was already register, True otherwise
-        :raises: DuplicateOptError
-        """
-        if group is not None:
-            group = self._get_group(group, autocreate=True)
-            return group._register_opt(opt, cli)
-
-        if _is_opt_registered(self._opts, opt):
-            return False
-
-        self._opts[opt.dest] = {'opt': opt, 'cli': cli}
-
-        return True
-
-    @__clear_cache
-    def register_opts(self, opts, group=None):
-        """Register multiple option schemas at once."""
-        for opt in opts:
-            self.register_opt(opt, group, clear_cache=False)
-
-    @__clear_cache
-    def register_cli_opt(self, opt, group=None):
-        """Register a CLI option schema.
-
-        CLI option schemas must be registered before the command line and
-        config files are parsed. This is to ensure that all CLI options are
-        show in --help and option validation works as expected.
-
-        :param opt: an instance of an Opt sub-class
-        :param group: an optional OptGroup object or group name
-        :return: False if the opt was already register, True otherwise
-        :raises: DuplicateOptError, ArgsAlreadyParsedError
-        """
-        if self._args is not None:
-            raise ArgsAlreadyParsedError("cannot register CLI option")
-
-        return self.register_opt(opt, group, cli=True, clear_cache=False)
-
-    @__clear_cache
-    def register_cli_opts(self, opts, group=None):
-        """Register multiple CLI option schemas at once."""
-        for opt in opts:
-            self.register_cli_opt(opt, group, clear_cache=False)
-
-    def register_group(self, group):
-        """Register an option group.
-
-        An option group must be registered before options can be registered
-        with the group.
-
-        :param group: an OptGroup object
-        """
-        if group.name in self._groups:
-            return
-
-        self._groups[group.name] = copy.copy(group)
-
-    @__clear_cache
-    def unregister_opt(self, opt, group=None):
-        """Unregister an option.
-
-        :param opt: an Opt object
-        :param group: an optional OptGroup object or group name
-        :raises: ArgsAlreadyParsedError, NoSuchGroupError
-        """
-        if self._args is not None:
-            raise ArgsAlreadyParsedError("reset before unregistering options")
-
-        if group is not None:
-            self._get_group(group)._unregister_opt(opt)
-        elif opt.dest in self._opts:
-            del self._opts[opt.dest]
-
-    @__clear_cache
-    def unregister_opts(self, opts, group=None):
-        """Unregister multiple CLI option schemas at once."""
-        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)
-
-    def import_group(self, group, module_str):
-        """Import an option group from a module.
-
-        Import a module and check that a given option group 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 group
-        defined by another module it can use this method to explicitly
-        declare the dependency.
-
-        :param group: an option OptGroup object or group name
-        :param module_str: the name of a module to import
-        :raises: ImportError, NoSuchGroupError
-        """
-        __import__(module_str)
-        self._get_group(group)
-
-    @__clear_cache
-    def set_override(self, name, override, group=None):
-        """Override an opt value.
-
-        Override the command line, config file and default values of a
-        given option.
-
-        :param name: the name/dest of the opt
-        :param override: the override value
-        :param group: an option OptGroup object or group name
-        :raises: NoSuchOptError, NoSuchGroupError
-        """
-        opt_info = self._get_opt_info(name, group)
-        opt_info['override'] = override
-
-    @__clear_cache
-    def set_default(self, name, default, group=None):
-        """Override an opt's default value.
-
-        Override the default value of given option. A command line or
-        config file value will still take precedence over this default.
-
-        :param name: the name/dest of the opt
-        :param default: the default value
-        :param group: an option OptGroup object or group name
-        :raises: NoSuchOptError, NoSuchGroupError
-        """
-        opt_info = self._get_opt_info(name, group)
-        opt_info['default'] = default
-
-    @__clear_cache
-    def clear_override(self, name, group=None):
-        """Clear an override an opt value.
-
-        Clear a previously set override of the command line, config file
-        and default values of a given option.
-
-        :param name: the name/dest of the opt
-        :param group: an option OptGroup object or group name
-        :raises: NoSuchOptError, NoSuchGroupError
-        """
-        opt_info = self._get_opt_info(name, group)
-        opt_info.pop('override', None)
-
-    @__clear_cache
-    def clear_default(self, name, group=None):
-        """Clear an override an opt's default value.
-
-        Clear a previously set override of the default value of given option.
-
-        :param name: the name/dest of the opt
-        :param group: an option OptGroup object or group name
-        :raises: NoSuchOptError, NoSuchGroupError
-        """
-        opt_info = self._get_opt_info(name, group)
-        opt_info.pop('default', None)
-
-    def _all_opt_infos(self):
-        """A generator function for iteration opt infos."""
-        for info in self._opts.values():
-            yield info, None
-        for group in self._groups.values():
-            for info in group._opts.values():
-                yield info, group
-
-    def _all_cli_opts(self):
-        """A generator function for iterating CLI opts."""
-        for info, group in self._all_opt_infos():
-            if info['cli']:
-                yield info['opt'], group
-
-    def _unset_defaults_and_overrides(self):
-        """Unset any default or override on all options."""
-        for info, group in self._all_opt_infos():
-            info.pop('default', None)
-            info.pop('override', None)
-
-    def find_file(self, name):
-        """Locate a file located alongside the config files.
-
-        Search for a file with the supplied basename in the directories
-        which we have already loaded config files from and other known
-        configuration directories.
-
-        The directory, if any, supplied by the config_dir option is
-        searched first. Then the config_file option is iterated over
-        and each of the base directories of the config_files values
-        are searched. Failing both of these, the standard directories
-        searched by the module level find_config_files() function is
-        used. The first matching file is returned.
-
-        :param basename: the filename, e.g. 'policy.json'
-        :returns: the path to a matching file, or None
-        """
-        dirs = []
-        if self.config_dir:
-            dirs.append(_fixpath(self.config_dir))
-
-        for cf in reversed(self.config_file):
-            dirs.append(os.path.dirname(_fixpath(cf)))
-
-        dirs.extend(_get_config_dirs(self.project))
-
-        return _search_dirs(dirs, name)
-
-    def log_opt_values(self, logger, lvl):
-        """Log the value of all registered opts.
-
-        It's often useful for an app to log its configuration to a log file at
-        startup for debugging. This method dumps to the entire config state to
-        the supplied logger at a given log level.
-
-        :param logger: a logging.Logger object
-        :param lvl: the log level (e.g. logging.DEBUG) arg to logger.log()
-        """
-        logger.log(lvl, "*" * 80)
-        logger.log(lvl, "Configuration options gathered from:")
-        logger.log(lvl, "command line args: %s", self._args)
-        logger.log(lvl, "config files: %s", self.config_file)
-        logger.log(lvl, "=" * 80)
-
-        def _sanitize(opt, value):
-            """Obfuscate values of options declared secret."""
-            return value if not opt.secret else '*' * len(str(value))
-
-        for opt_name in sorted(self._opts):
-            opt = self._get_opt_info(opt_name)['opt']
-            logger.log(lvl, "%-30s = %s", opt_name,
-                       _sanitize(opt, getattr(self, opt_name)))
-
-        for group_name in self._groups:
-            group_attr = self.GroupAttr(self, self._get_group(group_name))
-            for opt_name in sorted(self._groups[group_name]._opts):
-                opt = self._get_opt_info(opt_name, group_name)['opt']
-                logger.log(lvl, "%-30s = %s",
-                           "%s.%s" % (group_name, opt_name),
-                           _sanitize(opt, getattr(group_attr, opt_name)))
-
-        logger.log(lvl, "*" * 80)
-
-    def print_usage(self, file=None):
-        """Print the usage message for the current program."""
-        self._oparser.print_usage(file)
-
-    def print_help(self, file=None):
-        """Print the help message for the current program."""
-        self._oparser.print_help(file)
-
-    def _get(self, name, group=None):
-        if isinstance(group, OptGroup):
-            key = (group.name, name)
-        else:
-            key = (group, name)
-        try:
-            return self.__cache[key]
-        except KeyError:
-            value = self._substitute(self._do_get(name, group))
-            self.__cache[key] = value
-            return value
-
-    def _do_get(self, name, group=None):
-        """Look up an option value.
-
-        :param name: the opt name (or 'dest', more precisely)
-        :param group: an OptGroup
-        :returns: the option value, or a GroupAttr object
-        :raises: NoSuchOptError, NoSuchGroupError, ConfigFileValueError,
-                 TemplateSubstitutionError
-        """
-        if group is None and name in self._groups:
-            return self.GroupAttr(self, self._get_group(name))
-
-        info = self._get_opt_info(name, group)
-        opt = info['opt']
-
-        if isinstance(opt, SubCommandOpt):
-            return self.SubCommandAttr(self, group, opt.dest)
-
-        if 'override' in info:
-            return info['override']
-
-        values = []
-        if self._cparser is not None:
-            section = group.name if group is not None else 'DEFAULT'
-            try:
-                value = opt._get_from_config_parser(self._cparser, section)
-            except KeyError:
-                pass
-            except ValueError as ve:
-                raise ConfigFileValueError(str(ve))
-            else:
-                if not opt.multi:
-                    # No need to continue since the last value wins
-                    return value[-1]
-                values.extend(value)
-
-        name = name if group is None else group.name + '_' + name
-        value = self._cli_values.get(name)
-        if value is not None:
-            if not opt.multi:
-                return value
-
-            # argparse ignores default=None for nargs='*'
-            if opt.positional and not value:
-                value = opt.default
-
-            return value + values
-
-        if values:
-            return values
-
-        if 'default' in info:
-            return info['default']
-
-        return opt.default
-
-    def _substitute(self, value):
-        """Perform string template substitution.
-
-        Substitute any template variables (e.g. $foo, ${bar}) in the supplied
-        string value(s) with opt values.
-
-        :param value: the string value, or list of string values
-        :returns: the substituted string(s)
-        """
-        if isinstance(value, list):
-            return [self._substitute(i) for i in value]
-        elif isinstance(value, str):
-            tmpl = string.Template(value)
-            return tmpl.safe_substitute(self.StrSubWrapper(self))
-        else:
-            return value
-
-    def _get_group(self, group_or_name, autocreate=False):
-        """Looks up a OptGroup object.
-
-        Helper function to return an OptGroup given a parameter which can
-        either be the group's name or an OptGroup object.
-
-        The OptGroup object returned is from the internal dict of OptGroup
-        objects, which will be a copy of any OptGroup object that users of
-        the API have access to.
-
-        :param group_or_name: the group's name or the OptGroup object itself
-        :param autocreate: whether to auto-create the group if it's not found
-        :raises: NoSuchGroupError
-        """
-        group = group_or_name if isinstance(group_or_name, OptGroup) else None
-        group_name = group.name if group else group_or_name
-
-        if group_name not in self._groups:
-            if group is not None or not autocreate:
-                raise NoSuchGroupError(group_name)
-
-            self.register_group(OptGroup(name=group_name))
-
-        return self._groups[group_name]
-
-    def _get_opt_info(self, opt_name, group=None):
-        """Return the (opt, override, default) dict for an opt.
-
-        :param opt_name: an opt name/dest
-        :param group: an optional group name or OptGroup object
-        :raises: NoSuchOptError, NoSuchGroupError
-        """
-        if group is None:
-            opts = self._opts
-        else:
-            group = self._get_group(group)
-            opts = group._opts
-
-        if opt_name not in opts:
-            raise NoSuchOptError(opt_name, group)
-
-        return opts[opt_name]
-
-    def _parse_config_files(self):
-        """Parse the config files from --config-file and --config-dir.
-
-        :raises: ConfigFilesNotFoundError, ConfigFileParseError
-        """
-        config_files = list(self.config_file)
-
-        if self.config_dir:
-            config_dir_glob = os.path.join(self.config_dir, '*.conf')
-            config_files += sorted(glob.glob(config_dir_glob))
-
-        config_files = [_fixpath(p) for p in config_files]
-
-        self._cparser = MultiConfigParser()
-
-        try:
-            read_ok = self._cparser.read(config_files)
-        except iniparser.ParseError as pe:
-            raise ConfigFileParseError(pe.filename, str(pe))
-
-        if read_ok != config_files:
-            not_read_ok = filter(lambda f: f not in read_ok, config_files)
-            raise ConfigFilesNotFoundError(not_read_ok)
-
-    def _check_required_opts(self):
-        """Check that all opts marked as required have values specified.
-
-        :raises: RequiredOptError
-        """
-        for info, group in self._all_opt_infos():
-            opt = info['opt']
-
-            if opt.required:
-                if 'default' in info or 'override' in info:
-                    continue
-
-                if self._get(opt.dest, group) is None:
-                    raise RequiredOptError(opt.name, group)
-
-    def _parse_cli_opts(self, args):
-        """Parse command line options.
-
-        Initializes the command line option parser and parses the supplied
-        command line arguments.
-
-        :param args: the command line arguments
-        :returns: a dict of parsed option values
-        :raises: SystemExit, DuplicateOptError
-
-        """
-        self._args = args
-
-        for opt, group in sorted(self._all_cli_opts()):
-            opt._add_to_cli(self._oparser, group)
-
-        return vars(self._oparser.parse_args(args))
-
-    class GroupAttr(collections.Mapping):
-
-        """
-        A helper class representing the option values of a group as a mapping
-        and attributes.
-        """
-
-        def __init__(self, conf, group):
-            """Construct a GroupAttr object.
-
-            :param conf: a ConfigOpts object
-            :param group: an OptGroup object
-            """
-            self._conf = conf
-            self._group = group
-
-        def __getattr__(self, name):
-            """Look up an option value and perform template substitution."""
-            return self._conf._get(name, self._group)
-
-        def __getitem__(self, key):
-            """Look up an option value and perform string substitution."""
-            return self.__getattr__(key)
-
-        def __contains__(self, key):
-            """Return True if key is the name of a registered opt or group."""
-            return key in self._group._opts
-
-        def __iter__(self):
-            """Iterate over all registered opt and group names."""
-            for key in self._group._opts.keys():
-                yield key
-
-        def __len__(self):
-            """Return the number of options and option groups."""
-            return len(self._group._opts)
-
-    class SubCommandAttr(object):
-
-        """
-        A helper class representing the name and arguments of an argparse
-        sub-parser.
-        """
-
-        def __init__(self, conf, group, dest):
-            """Construct a SubCommandAttr object.
-
-            :param conf: a ConfigOpts object
-            :param group: an OptGroup object
-            :param dest: the name of the sub-parser
-            """
-            self._conf = conf
-            self._group = group
-            self._dest = dest
-
-        def __getattr__(self, name):
-            """Look up a sub-parser name or argument value."""
-            if name == 'name':
-                name = self._dest
-                if self._group is not None:
-                    name = self._group.name + '_' + name
-                return self._conf._cli_values[name]
-
-            if name in self._conf:
-                raise DuplicateOptError(name)
-
-            try:
-                return self._conf._cli_values[name]
-            except KeyError:
-                raise NoSuchOptError(name)
-
-    class StrSubWrapper(object):
-
-        """
-        A helper class exposing opt values as a dict for string substitution.
-        """
-
-        def __init__(self, conf):
-            """Construct a StrSubWrapper object.
-
-            :param conf: a ConfigOpts object
-            """
-            self.conf = conf
-
-        def __getitem__(self, key):
-            """Look up an opt value from the ConfigOpts object.
-
-            :param key: an opt name
-            :returns: an opt value
-            :raises: TemplateSubstitutionError if attribute is a group
-            """
-            value = getattr(self.conf, key)
-            if isinstance(value, self.conf.GroupAttr):
-                raise TemplateSubstitutionError(
-                    'substituting group %s not supported' % key)
-            return value
-
-
-CONF = ConfigOpts()
diff --git a/tempest/openstack/common/iniparser.py b/tempest/openstack/common/iniparser.py
deleted file mode 100644
index 9a8762a..0000000
--- a/tempest/openstack/common/iniparser.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack LLC.
-#
-#    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.
-
-
-class ParseError(Exception):
-    def __init__(self, message, lineno, line):
-        self.msg = message
-        self.line = line
-        self.lineno = lineno
-
-    def __str__(self):
-        return 'at line %d, %s: %r' % (self.lineno, self.msg, self.line)
-
-
-class BaseParser(object):
-    lineno = 0
-    parse_exc = ParseError
-
-    def _assignment(self, key, value):
-        self.assignment(key, value)
-        return None, []
-
-    def _get_section(self, line):
-        if line[-1] != ']':
-            return self.error_no_section_end_bracket(line)
-        if len(line) <= 2:
-            return self.error_no_section_name(line)
-
-        return line[1:-1]
-
-    def _split_key_value(self, line):
-        colon = line.find(':')
-        equal = line.find('=')
-        if colon < 0 and equal < 0:
-            return self.error_invalid_assignment(line)
-
-        if colon < 0 or (equal >= 0 and equal < colon):
-            key, value = line[:equal], line[equal + 1:]
-        else:
-            key, value = line[:colon], line[colon + 1:]
-
-        value = value.strip()
-        if ((value and value[0] == value[-1]) and
-                (value[0] == "\"" or value[0] == "'")):
-            value = value[1:-1]
-        return key.strip(), [value]
-
-    def parse(self, lineiter):
-        key = None
-        value = []
-
-        for line in lineiter:
-            self.lineno += 1
-
-            line = line.rstrip()
-            if not line:
-                # Blank line, ends multi-line values
-                if key:
-                    key, value = self._assignment(key, value)
-                continue
-            elif line[0] in (' ', '\t'):
-                # Continuation of previous assignment
-                if key is None:
-                    self.error_unexpected_continuation(line)
-                else:
-                    value.append(line.lstrip())
-                continue
-
-            if key:
-                # Flush previous assignment, if any
-                key, value = self._assignment(key, value)
-
-            if line[0] == '[':
-                # Section start
-                section = self._get_section(line)
-                if section:
-                    self.new_section(section)
-            elif line[0] in '#;':
-                self.comment(line[1:].lstrip())
-            else:
-                key, value = self._split_key_value(line)
-                if not key:
-                    return self.error_empty_key(line)
-
-        if key:
-            # Flush previous assignment, if any
-            self._assignment(key, value)
-
-    def assignment(self, key, value):
-        """Called when a full assignment is parsed."""
-        raise NotImplementedError()
-
-    def new_section(self, section):
-        """Called when a new section is started."""
-        raise NotImplementedError()
-
-    def comment(self, comment):
-        """Called when a comment is parsed."""
-        pass
-
-    def error_invalid_assignment(self, line):
-        raise self.parse_exc("No ':' or '=' found in assignment",
-                             self.lineno, line)
-
-    def error_empty_key(self, line):
-        raise self.parse_exc('Key cannot be empty', self.lineno, line)
-
-    def error_unexpected_continuation(self, line):
-        raise self.parse_exc('Unexpected continuation line',
-                             self.lineno, line)
-
-    def error_no_section_end_bracket(self, line):
-        raise self.parse_exc('Invalid section (must end with ])',
-                             self.lineno, line)
-
-    def error_no_section_name(self, line):
-        raise self.parse_exc('Empty section name', self.lineno, line)
diff --git a/tempest/services/image/v2/__init__.py b/tempest/services/image/v2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/image/v2/__init__.py
diff --git a/tempest/services/image/v2/json/__init__.py b/tempest/services/image/v2/json/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/image/v2/json/__init__.py
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
new file mode 100644
index 0000000..bcae79b
--- /dev/null
+++ b/tempest/services/image/v2/json/image_client.py
@@ -0,0 +1,123 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2013 IBM
+# All Rights Reserved.
+#
+#    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.
+
+import json
+import urllib
+
+import jsonschema
+
+from tempest.common import glance_http
+from tempest.common import rest_client
+from tempest import exceptions
+
+
+class ImageClientV2JSON(rest_client.RestClient):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(ImageClientV2JSON, self).__init__(config, username, password,
+                                                auth_url, tenant_name)
+        self.service = self.config.images.catalog_type
+        self.http = self._get_http()
+
+    def _get_http(self):
+        token, endpoint = self.keystone_auth(self.user, self.password,
+                                             self.auth_url, self.service,
+                                             self.tenant_name)
+        dscv = self.config.identity.disable_ssl_certificate_validation
+        return glance_http.HTTPClient(endpoint=endpoint, token=token,
+                                      insecure=dscv)
+
+    def get_images_schema(self):
+        url = 'v2/schemas/images'
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body
+
+    def get_image_schema(self):
+        url = 'v2/schemas/image'
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body
+
+    def _validate_schema(self, body, type='image'):
+        if type == 'image':
+            resp, schema = self.get_image_schema()
+        elif type == 'images':
+            resp, schema = self.get_images_schema()
+        else:
+            raise ValueError("%s is not a valid schema type" % type)
+
+        jsonschema.validate(body, schema)
+
+    def create_image(self, name, container_format, disk_format, is_public=True,
+                     properties=None):
+        params = {
+            "name": name,
+            "container_format": container_format,
+            "disk_format": disk_format,
+        }
+        if is_public:
+            params["visibility"] = "public"
+        else:
+            params["visibility"] = "private"
+
+        data = json.dumps(params)
+        self._validate_schema(data)
+
+        resp, body = self.post('v2/images', data, self.headers)
+        body = json.loads(body)
+        return resp, body
+
+    def delete_image(self, image_id):
+        url = 'v2/images/%s' % image_id
+        self.delete(url)
+
+    def image_list(self, params=None):
+        url = 'v2/images'
+
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self._validate_schema(body, type='images')
+        return resp, body['images']
+
+    def get_image_metadata(self, image_id):
+        url = 'v2/images/%s' % image_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body
+
+    def is_resource_deleted(self, id):
+        try:
+            self.get_image_metadata(id)
+        except exceptions.NotFound:
+            return True
+        return False
+
+    def store_image(self, image_id, data):
+        url = 'v2/images/%s/file' % image_id
+        headers = {'Content-Type': 'application/octet-stream'}
+        resp, body = self.http.raw_request('PUT', url, headers=headers,
+                                           body=data)
+        return resp, body
+
+    def get_image_file(self, image_id):
+        url = 'v2/images/%s/file' % image_id
+        resp, body = self.get(url)
+        return resp, body
diff --git a/tempest/tests/boto/test_ec2_instance_run.py b/tempest/tests/boto/test_ec2_instance_run.py
index 4ad37b6..3293dea 100644
--- a/tempest/tests/boto/test_ec2_instance_run.py
+++ b/tempest/tests/boto/test_ec2_instance_run.py
@@ -142,7 +142,6 @@
     #NOTE(afazekas): doctored test case,
     # with normal validation it would fail
     @attr("slow", type='smoke')
-    @testtools.skip("Skipped until the Bug #1117555 is resolved")
     def test_integration_1(self):
         # EC2 1. integration test (not strict)
         image_ami = self.ec2_client.get_image(self.images["ami"]["image_id"])
diff --git a/tempest/tests/compute/test_live_block_migration.py b/tempest/tests/compute/test_live_block_migration.py
index f2ec753..abaaf85 100644
--- a/tempest/tests/compute/test_live_block_migration.py
+++ b/tempest/tests/compute/test_live_block_migration.py
@@ -108,7 +108,6 @@
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
         self.assertEquals(target_host, self._get_host_for_server(server_id))
 
-    @testtools.skip('Until bug 1051881 is dealt with.')
     @testtools.skipIf(not live_migration_available,
                       'Block Live migration not available')
     def test_invalid_host_for_migration(self):
diff --git a/tempest/tests/image/v2/__init__.py b/tempest/tests/image/v2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/image/v2/__init__.py
diff --git a/tempest/tests/image/v2/test_images.py b/tempest/tests/image/v2/test_images.py
new file mode 100644
index 0000000..9abf28d
--- /dev/null
+++ b/tempest/tests/image/v2/test_images.py
@@ -0,0 +1,126 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack, LLC
+# All Rights Reserved.
+# Copyright 2013 IBM Corp
+#
+#    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.
+
+import cStringIO as StringIO
+import random
+
+from tempest import clients
+from tempest import exceptions
+import tempest.test
+from tempest.test import attr
+
+
+class CreateRegisterImagesTest(tempest.test.BaseTestCase):
+
+    """
+    Here we test the registration and creation of images
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        cls.os = clients.Manager()
+        cls.client = cls.os.image_client_v2
+        cls.created_images = []
+
+    @classmethod
+    def tearDownClass(cls):
+        for image_id in cls.created_images:
+            cls.client.delete(image_id)
+
+    @attr(type='negative')
+    def test_register_with_invalid_container_format(self):
+        # Negative tests for invalid data supplied to POST /images
+        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+                          'test', 'wrong', 'vhd')
+
+    @attr(type='negative')
+    def test_register_with_invalid_disk_format(self):
+        self.assertRaises(exceptions.BadRequest, self.client.create_image,
+                          'test', 'bare', 'wrong')
+
+    @attr(type='image')
+    def test_register_then_upload(self):
+        # Register, then upload an image
+        resp, body = self.client.create_image('New Name', 'bare', 'raw',
+                                              is_public=True)
+        self.assertTrue('id' in body)
+        image_id = body.get('id')
+        self.created_images.append(image_id)
+        self.assertTrue('name' in body)
+        self.assertEqual('New Name', body.get('name'))
+        self.assertTrue('visibility' in body)
+        self.assertTrue(body.get('visibility') == 'public')
+        self.assertTrue('status' in body)
+        self.assertEqual('queued', body.get('status'))
+
+        # Now try uploading an image file
+        image_file = StringIO.StringIO(('*' * 1024))
+        resp, body = self.client.store_image(image_id, image_file)
+        self.assertEqual(resp.status, 204)
+        resp, body = self.client.get_image_metadata(image_id)
+        self.assertTrue('size' in body)
+        self.assertEqual(1024, body.get('size'))
+
+
+class ListImagesTest(tempest.test.BaseTestCase):
+
+    """
+    Here we test the listing of image information
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        cls.os = clients.Manager()
+        cls.client = cls.os.image_client_v2
+        cls.created_images = []
+
+        # We add a few images here to test the listing functionality of
+        # the images API
+        for x in xrange(0, 10):
+            cls.created_images.append(cls._create_standard_image(x))
+
+    @classmethod
+    def tearDownClass(cls):
+        for image_id in cls.created_images:
+            cls.client.delete_image(image_id)
+            cls.client.wait_for_resource_deletion(image_id)
+
+    @classmethod
+    def _create_standard_image(cls, number):
+        """
+        Create a new standard image and return the ID of the newly-registered
+        image. Note that the size of the new image is a random number between
+        1024 and 4096
+        """
+        image_file = StringIO.StringIO('*' * random.randint(1024, 4096))
+        name = 'New Standard Image %s' % number
+        resp, body = cls.client.create_image(name, 'bare', 'raw',
+                                             is_public=True)
+        image_id = body['id']
+        resp, body = cls.client.store_image(image_id, data=image_file)
+
+        return image_id
+
+    @attr(type='image')
+    def test_index_no_params(self):
+        # Simple test to see all fixture images returned
+        resp, images_list = self.client.image_list()
+        self.assertEqual(resp['status'], '200')
+        image_list = map(lambda x: x['id'], images_list)
+        for image in self.created_images:
+            self.assertTrue(image in image_list)
diff --git a/tools/pip-requires b/tools/pip-requires
index 220f1a6..ee21065 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -13,3 +13,5 @@
 testresources
 keyring
 testrepository
+
+http://tarballs.openstack.org/oslo-config/oslo.config-1.1.0b1.tar.gz#egg=oslo.config
diff --git a/tools/tempest_coverage.py b/tools/tempest_coverage.py
index 267eafa..a46d0fb 100755
--- a/tools/tempest_coverage.py
+++ b/tools/tempest_coverage.py
@@ -20,9 +20,10 @@
 import shutil
 import sys
 
+from oslo.config import cfg
+
 from tempest.common.rest_client import RestClient
 from tempest import config
-from tempest.openstack.common import cfg
 from tempest.tests.compute import base
 
 CONF = config.TempestConfig()
diff --git a/tox.ini b/tox.ini
index 1b18586..92ce6bc 100644
--- a/tox.ini
+++ b/tox.ini
@@ -19,5 +19,4 @@
            python -m tools/tempest_coverage -c report --html
 
 [testenv:pep8]
-deps = pep8==1.3.3
 commands = python tools/hacking.py --ignore=E122,E125,E126 --repeat --show-source --exclude=.venv,.tox,dist,doc,openstack,*egg .
