diff --git a/.gitignore b/.gitignore
index c16fe78c11..ee78f4f390 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,10 @@
 .tox/
 .buildconf
 
+# Files generated by setup.py
+kolla.egg-info
+build
+
 # Files generated by tools/genenv
 openrc
 openstack.env
diff --git a/etc/oslo-config-generator/kolla-build.conf b/etc/oslo-config-generator/kolla-build.conf
new file mode 100644
index 0000000000..a59c08d7f8
--- /dev/null
+++ b/etc/oslo-config-generator/kolla-build.conf
@@ -0,0 +1,3 @@
+[DEFAULT]
+output_file = etc/kolla/kolla-build.conf
+namespace = kolla
diff --git a/kolla/cmd/build.py b/kolla/cmd/build.py
index 94340c7a33..bf5e5ba4c4 100755
--- a/kolla/cmd/build.py
+++ b/kolla/cmd/build.py
@@ -34,22 +34,19 @@ import docker
 import git
 import jinja2
 from oslo_config import cfg
-from oslo_config import types
 from requests.exceptions import ConnectionError
 import six
 from six.moves import range
 
+from kolla.common import config as common_config
+from kolla import version
+
 logging.basicConfig()
 LOG = logging.getLogger(__name__)
 LOG.setLevel(logging.INFO)
 
 signal.signal(signal.SIGINT, signal.SIG_DFL)
 
-RDO_MIRROR = "http://trunk.rdoproject.org/centos7"
-DELOREAN = "{}/current/delorean.repo".format(RDO_MIRROR)
-DELOREAN_DEPS = "{}/delorean-deps.repo".format(RDO_MIRROR)
-INSTALL_TYPE_CHOICES = ['binary', 'source', 'rdo', 'rhos']
-
 
 class KollaDirNotFoundException(Exception):
     pass
@@ -279,14 +276,6 @@ class WorkerThread(Thread):
             self.push_queue.put(image)
 
 
-def get_kolla_version():
-    local_conf_path = os.path.join(find_base_dir(), "setup.cfg")
-    config = six.moves.configparser.RawConfigParser()
-    config.read(local_conf_path)
-    version = config.get("metadata", "version")
-    return version
-
-
 def find_os_type():
     return platform.linux_distribution()
 
@@ -307,21 +296,6 @@ def find_base_dir():
     )
 
 
-def find_config_file(filename):
-    global_conf_path = os.path.join('/etc/kolla', filename)
-    local_conf_path = os.path.join(find_base_dir(), 'etc', 'kolla', filename)
-
-    if os.access(global_conf_path, os.R_OK):
-        return global_conf_path
-    elif os.access(local_conf_path, os.R_OK):
-        return local_conf_path
-    else:
-        raise KollaDirNotFoundException(
-            'Cant find kolla config. Searched at: %s and %s' %
-            (global_conf_path, local_conf_path)
-        )
-
-
 class KollaWorker(object):
 
     def __init__(self, conf):
@@ -417,6 +391,7 @@ class KollaWorker(object):
         LOG.debug('Set atime and mtime to 0 for all content in working dir')
 
     def create_dockerfiles(self):
+        kolla_version = version.version_info.cached_version_string()
         for path in self.docker_build_paths:
             template_name = "Dockerfile.j2"
             env = jinja2.Environment(loader=jinja2.FileSystemLoader(path))
@@ -429,7 +404,7 @@ class KollaWorker(object):
                       'namespace': self.namespace,
                       'tag': self.tag,
                       'maintainer': self.maintainer,
-                      'kolla_version': get_kolla_version(),
+                      'kolla_version': kolla_version,
                       'rpm_setup': self.rpm_setup}
             if self.include_header:
                 with open(self.include_header, 'r') as f:
@@ -616,128 +591,9 @@ class KollaWorker(object):
         return queue
 
 
-def get_conf():
-    conf = cfg.ConfigOpts()
-
-    _kolla_profile_opts = [
-        cfg.ListOpt('infra',
-                    default=['ceph', 'data', 'mariadb', 'haproxy',
-                             'keepalived', 'kolla-ansible', 'memcached',
-                             'mongodb', 'openvswitch', 'rabbitmq', 'rsyslog']),
-        cfg.ListOpt('main',
-                    default=['cinder', 'ceilometer', 'glance', 'heat',
-                             'horizon', 'keystone', 'neutron', 'nova',
-                             'swift']),
-        cfg.ListOpt('aux',
-                    default=['aodh', 'designate', 'gnocchi', 'ironic',
-                             'magnum', 'mistral', 'trove,' 'zaqar']),
-        cfg.ListOpt('default',
-                    default=['data', 'kolla-ansible', 'glance', 'haproxy',
-                             'heat', 'horizon', 'keepalived', 'keystone',
-                             'memcached', 'mariadb', 'neutron', 'nova',
-                             'openvswitch', 'rabbitmq', 'rsyslog']),
-        cfg.ListOpt('gate',
-                    default=['ceph', 'cinder', 'data', 'dind', 'glance',
-                             'haproxy', 'heat', 'horizon', 'keepalived',
-                             'keystone', 'kolla-ansible', 'mariadb',
-                             'memcached', 'neutron', 'nova', 'openvswitch',
-                             'rabbitmq', 'rsyslog'])
-    ]
-
-    _kolla_cli_opts = [
-        cfg.StrOpt('base', short='b', default='centos',
-                   deprecated_group='kolla-build',
-                   help='The base distro to use when building'),
-        cfg.StrOpt('base_tag', default='latest',
-                   deprecated_group='kolla-build',
-                   help='The base distro image tag'),
-        cfg.BoolOpt('debug', short='d', default=False,
-                    deprecated_group='kolla-build',
-                    help='Turn on debugging log level'),
-        cfg.StrOpt('include-header', short='i',
-                   deprecated_group='kolla-build',
-                   help=('Path to custom file to be added at '
-                         'beginning of base Dockerfile')),
-        cfg.StrOpt('include-footer', short='I',
-                   deprecated_group='kolla-build',
-                   help=('Path to custom file to be added at '
-                         'end of Dockerfiles for final images')),
-        cfg.BoolOpt('keep', default=False,
-                    deprecated_group='kolla-build',
-                    help='Keep failed intermediate containers'),
-        cfg.StrOpt('namespace', short='n', default='kollaglue',
-                   deprecated_group='kolla-build',
-                   help='The Docker namespace name'),
-        cfg.BoolOpt('cache', default=True,
-                    help='Use the Docker cache when building',
-                    ),
-        cfg.BoolOpt('no-cache', default=False,
-                    help='Do not use the Docker cache when building',
-                    deprecated_for_removal=True),
-        cfg.MultiOpt('profile', types.String(), short='p',
-                     deprecated_group='kolla-build',
-                     help=('Build a pre-defined set of images, see [profiles]'
-                           ' section in {}. The default profiles are:'
-                           ' {}'.format(
-                               find_config_file('kolla-build.conf'),
-                               ', '.join(
-                                   [opt.name for opt in _kolla_profile_opts])
-                           ))),
-        cfg.BoolOpt('push', default=False,
-                    deprecated_group='kolla-build',
-                    help='Push images after building'),
-        cfg.IntOpt('push-threads', default=1, min=1,
-                   deprecated_group='kolla-build',
-                   help=('The number of threads to user while pushing'
-                         ' Images. Note: Docker can not handle threading'
-                         ' push properly.')),
-        cfg.IntOpt('retries', short='r', default=3, min=0,
-                   deprecated_group='kolla-build',
-                   help='The number of times to retry while building'),
-        cfg.MultiOpt('regex', types.String(), positional=True,
-                     help=('Build only images matching regex and its'
-                           ' dependencies')),
-        cfg.StrOpt('registry', deprecated_group='kolla-build',
-                   help=('The docker registry host. The default registry host'
-                         ' is Docker Hub')),
-        cfg.StrOpt('type', short='t', default='binary',
-                   choices=INSTALL_TYPE_CHOICES,
-                   dest='install_type', deprecated_group='kolla-build',
-                   help=('The method of the Openstack install. The valid'
-                         ' types are: {}'.format(
-                             ', '.join(INSTALL_TYPE_CHOICES)))),
-        cfg.IntOpt('threads', short='T', default=8, min=1,
-                   deprecated_group='kolla-build',
-                   help=('The number of threads to use while building.'
-                         ' (Note: setting to one will allow real time'
-                         ' logging.)')),
-        cfg.StrOpt('tag', default=get_kolla_version(),
-                   deprecated_group='kolla-build',
-                   help='The Docker tag'),
-        cfg.BoolOpt('template-only', default=False,
-                    deprecated_group='kolla-build',
-                    help=("Don't build images. Generate Dockerfile only")),
-    ]
-
-    _kolla_base_opts = [
-        cfg.StrOpt('maintainer', deprecated_group='kolla-build',
-                   default='Kolla Project (https://launchpad.net/kolla)',
-                   help='The MAINTAINER field'),
-        cfg.ListOpt('rpm_setup_config', default=[DELOREAN, DELOREAN_DEPS],
-                    deprecated_group='kolla-build',
-                    help=('Comma separated list of .rpm or .repo file(s)'
-                          'or URL(s) to install before building containers'))
-    ]
-    conf.register_cli_opts(_kolla_cli_opts)
-    conf.register_opts(_kolla_profile_opts, group='profiles')
-    conf.register_opts(_kolla_base_opts)
-    conf(sys.argv[1:],
-         default_config_files=[find_config_file('kolla-build.conf')])
-    return conf
-
-
 def main():
-    conf = get_conf()
+    conf = cfg.ConfigOpts()
+    common_config.parse(conf, sys.argv[1:], prog='kolla-build')
 
     if conf.debug:
         LOG.setLevel(logging.DEBUG)
diff --git a/kolla/common/__init__.py b/kolla/common/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/kolla/common/config.py b/kolla/common/config.py
new file mode 100644
index 0000000000..68e1f7e5ed
--- /dev/null
+++ b/kolla/common/config.py
@@ -0,0 +1,263 @@
+# 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 itertools
+
+from oslo_config import cfg
+from oslo_config import types
+
+from kolla import version
+
+
+RDO_MIRROR = "http://trunk.rdoproject.org/centos7"
+DELOREAN = "{}/current/delorean.repo".format(RDO_MIRROR)
+DELOREAN_DEPS = "{}/delorean-deps.repo".format(RDO_MIRROR)
+INSTALL_TYPE_CHOICES = ['binary', 'source', 'rdo', 'rhos']
+
+_PROFILE_OPTS = [
+    cfg.ListOpt('infra',
+                default=['ceph', 'data', 'mariadb', 'haproxy',
+                         'keepalived', 'kolla-ansible', 'memcached',
+                         'mongodb', 'openvswitch', 'rabbitmq', 'rsyslog'],
+                help='Infra images'),
+    cfg.ListOpt('main',
+                default=['cinder', 'ceilometer', 'glance', 'heat',
+                         'horizon', 'keystone', 'neutron', 'nova',
+                         'swift'],
+                help='Main images'),
+    cfg.ListOpt('aux',
+                default=['aodh', 'designate', 'gnocchi', 'ironic',
+                         'magnum', 'mistral', 'trove,' 'zaqar'],
+                help='Aux Images'),
+    cfg.ListOpt('default',
+                default=['data', 'kolla-ansible', 'glance', 'haproxy',
+                         'heat', 'horizon', 'keepalived', 'keystone',
+                         'memcached', 'mariadb', 'neutron', 'nova',
+                         'openvswitch', 'rabbitmq', 'rsyslog'],
+                help='Default images'),
+    cfg.ListOpt('gate',
+                default=['ceph', 'cinder', 'data', 'dind', 'glance',
+                         'haproxy', 'heat', 'horizon', 'keepalived',
+                         'keystone', 'kolla-ansible', 'mariadb',
+                         'memcached', 'neutron', 'nova', 'openvswitch',
+                         'rabbitmq', 'rsyslog'],
+                help='Gate images')
+]
+
+_CLI_OPTS = [
+    cfg.StrOpt('base', short='b', default='centos',
+               deprecated_group='kolla-build',
+               help='The base distro to use when building'),
+    cfg.StrOpt('base_tag', default='latest',
+               deprecated_group='kolla-build',
+               help='The base distro image tag'),
+    cfg.BoolOpt('debug', short='d', default=False,
+                deprecated_group='kolla-build',
+                help='Turn on debugging log level'),
+    cfg.StrOpt('include-header', short='i',
+               deprecated_group='kolla-build',
+               help=('Path to custom file to be added at '
+                     'beginning of base Dockerfile')),
+    cfg.StrOpt('include-footer', short='I',
+               deprecated_group='kolla-build',
+               help=('Path to custom file to be added at '
+                     'end of Dockerfiles for final images')),
+    cfg.BoolOpt('keep', default=False,
+                deprecated_group='kolla-build',
+                help='Keep failed intermediate containers'),
+    cfg.StrOpt('namespace', short='n', default='kollaglue',
+               deprecated_group='kolla-build',
+               help='The Docker namespace name'),
+    cfg.BoolOpt('cache', default=True,
+                help='Use the Docker cache when building',
+                ),
+    cfg.BoolOpt('no-cache', default=False,
+                help='Do not use the Docker cache when building',
+                deprecated_for_removal=True),
+    cfg.MultiOpt('profile', types.String(), short='p',
+                 deprecated_group='kolla-build',
+                 help=('Build a pre-defined set of images, see [profiles]'
+                       ' section in config. The default profiles are:'
+                       ' {}'.format(', '.join(
+                           [opt.name for opt in _PROFILE_OPTS])
+                       ))),
+    cfg.BoolOpt('push', default=False,
+                deprecated_group='kolla-build',
+                help='Push images after building'),
+    cfg.IntOpt('push-threads', default=1, min=1,
+               deprecated_group='kolla-build',
+               help=('The number of threads to user while pushing'
+                     ' Images. Note: Docker can not handle threading'
+                     ' push properly.')),
+    cfg.IntOpt('retries', short='r', default=3, min=0,
+               deprecated_group='kolla-build',
+               help='The number of times to retry while building'),
+    cfg.MultiOpt('regex', types.String(), positional=True,
+                 help=('Build only images matching regex and its'
+                       ' dependencies')),
+    cfg.StrOpt('registry', deprecated_group='kolla-build',
+               help=('The docker registry host. The default registry host'
+                     ' is Docker Hub')),
+    cfg.StrOpt('type', short='t', default='binary',
+               choices=INSTALL_TYPE_CHOICES,
+               dest='install_type', deprecated_group='kolla-build',
+               help=('The method of the Openstack install. The valid'
+                     ' types are: {}'.format(
+                         ', '.join(INSTALL_TYPE_CHOICES)))),
+    cfg.IntOpt('threads', short='T', default=8, min=1,
+               deprecated_group='kolla-build',
+               help=('The number of threads to use while building.'
+                     ' (Note: setting to one will allow real time'
+                     ' logging.)')),
+    cfg.StrOpt('tag', default=version.version_info.cached_version_string(),
+               deprecated_group='kolla-build',
+               help='The Docker tag'),
+    cfg.BoolOpt('template-only', default=False,
+                deprecated_group='kolla-build',
+                help=("Don't build images. Generate Dockerfile only")),
+]
+
+_BASE_OPTS = [
+    cfg.StrOpt('maintainer', deprecated_group='kolla-build',
+               default='Kolla Project (https://launchpad.net/kolla)',
+               help='The MAINTAINER field'),
+    cfg.ListOpt('rpm_setup_config', default=[DELOREAN, DELOREAN_DEPS],
+                deprecated_group='kolla-build',
+                help=('Comma separated list of .rpm or .repo file(s)'
+                      'or URL(s) to install before building containers'))
+]
+
+
+SOURCES = {
+    'openstack-base': {
+        'type': 'url',
+        'location': ('https://github.com/openstack/requirements/tarball/'
+                     'master')},
+    'aodh-base': {
+        'type': 'url',
+        'location': 'http://tarballs.openstack.org/aodh/aodh-master.tar.gz'},
+    'ceilometer-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/ceilometer/'
+                     'ceilometer-master.tar.gz')},
+    'cinder-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/cinder/'
+                     'cinder-master.tar.gz')},
+    'designate-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/designate/'
+                     'designate-master.tar.gz')},
+    'glance-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/glance/'
+                     'glance-master.tar.gz')},
+    'gnocchi-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/gnocchi/'
+                     'gnocchi-master.tar.gz')},
+    'heat-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/heat/heat-master.tar.gz')},
+    'horizon': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/horizon/'
+                     'horizon-master.tar.gz')},
+    'ironic-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/ironic/'
+                     'ironic-master.tar.gz')},
+    'keystone': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/keystone/'
+                     'keystone-master.tar.gz')},
+    'magnum-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/magnum/'
+                     'magnum-master.tar.gz')},
+    'mistral-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/mistral/'
+                     'mistral-master.tar.gz')},
+    'murano-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/murano/'
+                     'murano-master.tar.gz')},
+    'neutron-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/neutron/'
+                     'neutron-master.tar.gz')},
+    'nova-base': {
+        'type': 'url',
+        'location': 'http://tarballs.openstack.org/nova/nova-master.tar.gz'},
+    'nova-spicehtml5proxy': {
+        'type': 'url',
+        'location': ('http://github.com/SPICE/spice-html5/tarball/'
+                     'spice-html5-0.1.6')},
+    'nova-novncproxy': {
+        'type': 'url',
+        'location': 'http://github.com/kanaka/noVNC/tarball/v0.5.1'},
+    'swift-base': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/swift/'
+                     'swift-master.tar.gz')},
+    'tempest': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/tempest/'
+                     'tempest-master.tar.gz')},
+    'zaqar': {
+        'type': 'url',
+        'location': ('http://tarballs.openstack.org/zaqar/'
+                     'zaqar-master.tar.gz')}
+
+}
+
+
+def _get_source_opt(type_, location, reference=None):
+    return [cfg.StrOpt('type', choices=['git', 'url'],
+                       default=type_,
+                       help='Source location type'),
+            cfg.StrOpt('location', default=location,
+                       help='The location for source install'),
+            cfg.StrOpt('reference', default=reference,
+                       help=('Git reference to pull, commit sha, tag'
+                             'or branch name'))]
+
+
+def gen_source_opts():
+    for name, params in SOURCES.iteritems():
+        type_ = params['type']
+        location = params['location']
+        reference = params.get('reference')
+        yield name, _get_source_opt(type_, location, reference)
+
+
+def list_opts():
+    return itertools.chain([(None, _CLI_OPTS),
+                            (None, _BASE_OPTS),
+                            ('profiles', _PROFILE_OPTS)],
+                           gen_source_opts(),
+                           )
+
+
+def parse(conf, args, usage=None, prog=None,
+          default_config_files=None):
+    conf.register_cli_opts(_CLI_OPTS)
+    conf.register_opts(_BASE_OPTS)
+    conf.register_opts(_PROFILE_OPTS, group='profiles')
+
+    conf(args=args,
+         project='kolla',
+         usage=usage,
+         prog=prog,
+         version=version.version_info.cached_version_string(),
+         default_config_files=default_config_files)
diff --git a/kolla/opts.py b/kolla/opts.py
new file mode 100644
index 0000000000..0571d7fbe2
--- /dev/null
+++ b/kolla/opts.py
@@ -0,0 +1,17 @@
+# 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 kolla.common import config
+
+
+def list_opts():
+    return config.list_opts()
diff --git a/kolla/version.py b/kolla/version.py
new file mode 100644
index 0000000000..4430b70c55
--- /dev/null
+++ b/kolla/version.py
@@ -0,0 +1,15 @@
+# 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 pbr.version
+
+version_info = pbr.version.VersionInfo('kolla')
diff --git a/setup.cfg b/setup.cfg
index e5196cf201..74bb08c160 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -37,6 +37,8 @@ scripts =
 [entry_points]
 console_scripts =
     kolla-build = kolla.cmd.build:main
+oslo.config.opts =
+    kolla = kolla.opts:list_opts
 
 [global]
 setup-hooks =
diff --git a/tox.ini b/tox.ini
index 5d778cade5..ea86928d50 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,6 +4,7 @@ skipsdist = True
 envlist = functional,pep8
 
 [testenv]
+usedevelop=True
 install_command = pip install -U {opts} {packages}
 deps = -r{toxinidir}/requirements.txt
        -r{toxinidir}/test-requirements.txt
@@ -102,6 +103,11 @@ commands =
   bash -c "if [ ! -d .testrepository ]; then testr init; fi"
   sudo -g docker testr run test_build.BuildTestUbuntuSource
 
+[testenv:genconfig]
+whitelist_externals = which
+commands=
+  oslo-config-generator --config-file etc/oslo-config-generator/kolla-build.conf
+
 [flake8]
 show-source = True
 exclude=.eggs,.git,.tox,doc