From 6f0aea966b49ec4c1470d18e91fb2bf95cfb5963 Mon Sep 17 00:00:00 2001
From: Ramamani Yeleswarapu <ramamani.yeleswarapu@intel.com>
Date: Fri, 15 Apr 2016 15:51:42 -0700
Subject: [PATCH] Centralize config options - [DEFAULT]

Nova style refactor of config options in Ironic.

Change-Id: I6baebf1bbc829238441ddd1399f6487fad33a15e
Partial-Bug: #1561100
---
 etc/ironic/ironic.conf.sample         |  37 +++--
 ironic/api/app.py                     |  24 +--
 ironic/cmd/dbsync.py                  |   4 +-
 ironic/common/driver_factory.py       |  41 +-----
 ironic/common/exception.py            |  15 +-
 ironic/common/hash_ring.py            |  33 +----
 ironic/common/images.py               |  23 +--
 ironic/common/paths.py                |  22 +--
 ironic/common/service.py              |  18 +--
 ironic/common/utils.py                |  17 +--
 ironic/conf/__init__.py               |   2 +
 ironic/conf/default.py                | 203 ++++++++++++++++++++++++++
 ironic/conf/opts.py                   |  31 ++--
 ironic/drivers/base.py                |   4 -
 ironic/drivers/modules/agent.py       |   1 -
 ironic/drivers/modules/image_cache.py |  13 +-
 ironic/netconf.py                     |  34 -----
 ironic/tests/base.py                  |   5 +-
 18 files changed, 247 insertions(+), 280 deletions(-)
 create mode 100644 ironic/conf/default.py

diff --git a/etc/ironic/ironic.conf.sample b/etc/ironic/ironic.conf.sample
index 10e7b8ac7b..397e4ceb3f 100644
--- a/etc/ironic/ironic.conf.sample
+++ b/etc/ironic/ironic.conf.sample
@@ -37,7 +37,7 @@
 # recommended set of production-oriented network interfaces. A
 # complete list of network interfaces present on your system
 # may be found by enumerating the
-# "ironic.hardware.interfaces.network" entrypoint.This value
+# "ironic.hardware.interfaces.network" entrypoint. This value
 # must be the same on all ironic-conductor and ironic-api
 # services, because it is used by ironic-api service to
 # validate a new or updated node's network_interface value.
@@ -96,6 +96,15 @@
 # Template file for grub configuration file. (string value)
 #grub_config_template = $pybasedir/common/grub_conf.template
 
+# Run image downloads and raw format conversions in parallel.
+# (boolean value)
+#parallel_image_downloads = false
+
+# IP address of this host. If unset, will determine the IP
+# programmatically. If unable to do so, will use "127.0.0.1".
+# (string value)
+#my_ip = 127.0.0.1
+
 # Directory where the ironic python module is installed.
 # (string value)
 #pybasedir = /usr/lib/python/site-packages/ironic/ironic
@@ -123,15 +132,6 @@
 # (string value)
 #tempdir = /tmp
 
-# Run image downloads and raw format conversions in parallel.
-# (boolean value)
-#parallel_image_downloads = false
-
-# IP address of this host. If unset, will determine the IP
-# programmatically. If unable to do so, will use "127.0.0.1".
-# (string value)
-#my_ip = 127.0.0.1
-
 #
 # From oslo.log
 #
@@ -156,6 +156,7 @@
 # is set in the configuration file and other logging
 # configuration options are ignored (for example,
 # logging_context_format_string). (string value)
+# Note: This option can be changed without restarting.
 # Deprecated group/name - [DEFAULT]/log_config
 #log_config_append = <None>
 
@@ -635,13 +636,13 @@
 # From ironic
 #
 
-# Path to serial console terminal program. Used only by
-# Shell In A Box console. (string value)
+# Path to serial console terminal program. Used only by Shell
+# In A Box console. (string value)
 #terminal = shellinaboxd
 
-# Directory containing the terminal SSL cert(PEM) for serial
-# console access. Used only by Shell In A Box console.
-# (string value)
+# Directory containing the terminal SSL cert (PEM) for serial
+# console access. Used only by Shell In A Box console. (string
+# value)
 #terminal_cert_dir = <None>
 
 # Directory for holding terminal pid files. If not specified,
@@ -736,8 +737,12 @@
 # From oslo.db
 #
 
-# The file name to use with SQLite. (string value)
+# DEPRECATED: The file name to use with SQLite. (string value)
 # Deprecated group/name - [DEFAULT]/sqlite_db
+# This option is deprecated for removal.
+# Its value may be silently ignored in the future.
+# Reason: Should use config option connection or
+# slave_connection to connect the database.
 #sqlite_db = oslo.sqlite
 
 # If True, SQLite uses synchronous mode. (boolean value)
diff --git a/ironic/api/app.py b/ironic/api/app.py
index b390334e12..f81b3e6c61 100644
--- a/ironic/api/app.py
+++ b/ironic/api/app.py
@@ -24,29 +24,7 @@ from ironic.api import config
 from ironic.api.controllers.base import Version
 from ironic.api import hooks
 from ironic.api import middleware
-from ironic.common.i18n import _
-
-api_opts = [
-    cfg.StrOpt(
-        'auth_strategy',
-        default='keystone',
-        choices=['noauth', 'keystone'],
-        help=_('Authentication strategy used by ironic-api. "noauth" should '
-               'not be used in a production environment because all '
-               'authentication will be disabled.')),
-    cfg.BoolOpt('debug_tracebacks_in_api',
-                default=False,
-                help=_('Return server tracebacks in the API response for any '
-                       'error responses. WARNING: this is insecure '
-                       'and should not be used in a production environment.')),
-    cfg.BoolOpt('pecan_debug',
-                default=False,
-                help=_('Enable pecan debug mode. WARNING: this is insecure '
-                       'and should not be used in a production environment.')),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(api_opts)
+from ironic.conf import CONF
 
 
 def get_pecan_config():
diff --git a/ironic/cmd/dbsync.py b/ironic/cmd/dbsync.py
index 732be6c51c..601737a7b5 100644
--- a/ironic/cmd/dbsync.py
+++ b/ironic/cmd/dbsync.py
@@ -25,12 +25,10 @@ from oslo_config import cfg
 
 from ironic.common.i18n import _
 from ironic.common import service
+from ironic.conf import CONF
 from ironic.db import migration
 
 
-CONF = cfg.CONF
-
-
 class DBCommand(object):
 
     def upgrade(self):
diff --git a/ironic/common/driver_factory.py b/ironic/common/driver_factory.py
index 28906f464a..98800c44cc 100644
--- a/ironic/common/driver_factory.py
+++ b/ironic/common/driver_factory.py
@@ -16,57 +16,18 @@
 import collections
 
 from oslo_concurrency import lockutils
-from oslo_config import cfg
 from oslo_log import log
 from stevedore import dispatch
 
 from ironic.common import exception
-from ironic.common.i18n import _
 from ironic.common.i18n import _LI
 from ironic.common.i18n import _LW
+from ironic.conf import CONF
 from ironic.drivers import base as driver_base
 
 
 LOG = log.getLogger(__name__)
 
-driver_opts = [
-    cfg.ListOpt('enabled_drivers',
-                default=['pxe_ipmitool'],
-                help=_('Specify the list of drivers to load during service '
-                       'initialization. Missing drivers, or drivers which '
-                       'fail to initialize, will prevent the conductor '
-                       'service from starting. The option default is a '
-                       'recommended set of production-oriented drivers. A '
-                       'complete list of drivers present on your system may '
-                       'be found by enumerating the "ironic.drivers" '
-                       'entrypoint. An example may be found in the '
-                       'developer documentation online.')),
-    cfg.ListOpt('enabled_network_interfaces',
-                default=['flat', 'noop'],
-                help=_('Specify the list of network interfaces to load during '
-                       'service initialization. Missing network interfaces, '
-                       'or network interfaces which fail to initialize, will '
-                       'prevent the conductor service from starting. The '
-                       'option default is a recommended set of '
-                       'production-oriented network interfaces. A complete '
-                       'list of network interfaces present on your system may '
-                       'be found by enumerating the '
-                       '"ironic.hardware.interfaces.network" entrypoint. '
-                       'This value must be the same on all ironic-conductor '
-                       'and ironic-api services, because it is used by '
-                       'ironic-api service to validate a new or updated '
-                       'node\'s network_interface value.')),
-    cfg.StrOpt('default_network_interface',
-               help=_('Default network interface to be used for nodes that '
-                      'do not have network_interface field set. A complete '
-                      'list of network interfaces present on your system may '
-                      'be found by enumerating the '
-                      '"ironic.hardware.interfaces.network" entrypoint.'))
-]
-
-CONF = cfg.CONF
-CONF.register_opts(driver_opts)
-
 EM_SEMAPHORE = 'extension_manager'
 
 
diff --git a/ironic/common/exception.py b/ironic/common/exception.py
index 10d3ac408c..f93305d21d 100644
--- a/ironic/common/exception.py
+++ b/ironic/common/exception.py
@@ -20,29 +20,16 @@ SHOULD include dedicated exception logging.
 
 """
 
-from oslo_config import cfg
 from oslo_log import log as logging
 import six
 from six.moves import http_client
 
 from ironic.common.i18n import _
 from ironic.common.i18n import _LE
-
+from ironic.conf import CONF
 
 LOG = logging.getLogger(__name__)
 
-exc_log_opts = [
-    cfg.BoolOpt('fatal_exception_format_errors',
-                default=False,
-                help=_('Used if there is a formatting error when generating '
-                       'an exception message (a programming error). If True, '
-                       'raise an exception; if False, use the unformatted '
-                       'message.')),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(exc_log_opts)
-
 
 class IronicException(Exception):
     """Base Ironic Exception
diff --git a/ironic/common/hash_ring.py b/ironic/common/hash_ring.py
index 20304d3942..bf58a1cdab 100644
--- a/ironic/common/hash_ring.py
+++ b/ironic/common/hash_ring.py
@@ -18,44 +18,13 @@ import hashlib
 import threading
 import time
 
-from oslo_config import cfg
 import six
 
 from ironic.common import exception
 from ironic.common.i18n import _
+from ironic.conf import CONF
 from ironic.db import api as dbapi
 
-hash_opts = [
-    cfg.IntOpt('hash_partition_exponent',
-               default=5,
-               help=_('Exponent to determine number of hash partitions to use '
-                      'when distributing load across conductors. Larger '
-                      'values will result in more even distribution of load '
-                      'and less load when rebalancing the ring, but more '
-                      'memory usage. Number of partitions per conductor is '
-                      '(2^hash_partition_exponent). This determines the '
-                      'granularity of rebalancing: given 10 hosts, and an '
-                      'exponent of the 2, there are 40 partitions in the ring.'
-                      'A few thousand partitions should make rebalancing '
-                      'smooth in most cases. The default is suitable for up '
-                      'to a few hundred conductors. Too many partitions has a '
-                      'CPU impact.')),
-    cfg.IntOpt('hash_distribution_replicas',
-               default=1,
-               help=_('[Experimental Feature] '
-                      'Number of hosts to map onto each hash partition. '
-                      'Setting this to more than one will cause additional '
-                      'conductor services to prepare deployment environments '
-                      'and potentially allow the Ironic cluster to recover '
-                      'more quickly if a conductor instance is terminated.')),
-    cfg.IntOpt('hash_ring_reset_interval',
-               default=180,
-               help=_('Interval (in seconds) between hash ring resets.')),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(hash_opts)
-
 
 class HashRing(object):
     """A stable hash ring.
diff --git a/ironic/common/images.py b/ironic/common/images.py
index 682a1a7a29..2505ea53e3 100644
--- a/ironic/common/images.py
+++ b/ironic/common/images.py
@@ -26,7 +26,6 @@ from ironic_lib import disk_utils
 from ironic_lib import utils as ironic_utils
 import jinja2
 from oslo_concurrency import processutils
-from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import fileutils
 
@@ -35,31 +34,11 @@ from ironic.common.glance_service import service_utils as glance_utils
 from ironic.common.i18n import _
 from ironic.common.i18n import _LE
 from ironic.common import image_service as service
-from ironic.common import paths
 from ironic.common import utils
+from ironic.conf import CONF
 
 LOG = logging.getLogger(__name__)
 
-image_opts = [
-    cfg.BoolOpt('force_raw_images',
-                default=True,
-                help=_('If True, convert backing images to "raw" disk image '
-                       'format.')),
-    cfg.StrOpt('isolinux_bin',
-               default='/usr/lib/syslinux/isolinux.bin',
-               help=_('Path to isolinux binary file.')),
-    cfg.StrOpt('isolinux_config_template',
-               default=paths.basedir_def('common/isolinux_config.template'),
-               help=_('Template file for isolinux configuration file.')),
-    cfg.StrOpt('grub_config_template',
-               default=paths.basedir_def('common/grub_conf.template'),
-               help=_('Template file for grub configuration file.')),
-]
-
-
-CONF = cfg.CONF
-CONF.register_opts(image_opts)
-
 
 def _create_root_fs(root_directory, files_info):
     """Creates a filesystem root in given directory.
diff --git a/ironic/common/paths.py b/ironic/common/paths.py
index c35d3f495e..b4118ba36f 100644
--- a/ironic/common/paths.py
+++ b/ironic/common/paths.py
@@ -17,27 +17,7 @@
 
 import os
 
-from oslo_config import cfg
-
-from ironic.common.i18n import _
-
-path_opts = [
-    cfg.StrOpt('pybasedir',
-               default=os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                                    '../')),
-               sample_default='/usr/lib/python/site-packages/ironic/ironic',
-               help=_('Directory where the ironic python module is '
-                      'installed.')),
-    cfg.StrOpt('bindir',
-               default='$pybasedir/bin',
-               help=_('Directory where ironic binaries are installed.')),
-    cfg.StrOpt('state_path',
-               default='$pybasedir',
-               help=_("Top-level directory for maintaining ironic's state.")),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(path_opts)
+from ironic.conf import CONF
 
 
 def basedir_def(*args):
diff --git a/ironic/common/service.py b/ironic/common/service.py
index fa79f8cbde..e2d4d3c456 100644
--- a/ironic/common/service.py
+++ b/ironic/common/service.py
@@ -15,10 +15,8 @@
 # under the License.
 
 import signal
-import socket
 
 from oslo_concurrency import processutils
-from oslo_config import cfg
 from oslo_log import log
 import oslo_messaging as messaging
 from oslo_service import service
@@ -33,26 +31,12 @@ from ironic.common.i18n import _
 from ironic.common.i18n import _LE
 from ironic.common.i18n import _LI
 from ironic.common import rpc
+from ironic.conf import CONF
 from ironic import objects
 from ironic.objects import base as objects_base
 
-
-service_opts = [
-    cfg.StrOpt('host',
-               default=socket.getfqdn(),
-               sample_default='localhost',
-               help=_('Name of this node. This can be an opaque identifier. '
-                      'It is not necessarily a hostname, FQDN, or IP address. '
-                      'However, the node name must be valid within '
-                      'an AMQP key, and if using ZeroMQ, a valid '
-                      'hostname, FQDN, or IP address.')),
-]
-
-CONF = cfg.CONF
 LOG = log.getLogger(__name__)
 
-CONF.register_opts(service_opts)
-
 
 class RPCService(service.Service):
 
diff --git a/ironic/common/utils.py b/ironic/common/utils.py
index ac2642e9ca..e6daf7027d 100644
--- a/ironic/common/utils.py
+++ b/ironic/common/utils.py
@@ -30,7 +30,6 @@ import tempfile
 
 import netaddr
 from oslo_concurrency import processutils
-from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import timeutils
 import paramiko
@@ -41,21 +40,7 @@ from ironic.common import exception
 from ironic.common.i18n import _
 from ironic.common.i18n import _LE
 from ironic.common.i18n import _LW
-
-utils_opts = [
-    cfg.StrOpt('rootwrap_config',
-               default="/etc/ironic/rootwrap.conf",
-               help=_('Path to the rootwrap configuration file to use for '
-                      'running commands as root.')),
-    cfg.StrOpt('tempdir',
-               default=tempfile.gettempdir(),
-               sample_default='/tmp',
-               help=_('Temporary working directory, default is Python temp '
-                      'dir.')),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(utils_opts)
+from ironic.conf import CONF
 
 LOG = logging.getLogger(__name__)
 
diff --git a/ironic/conf/__init__.py b/ironic/conf/__init__.py
index aaccf49338..d172c92054 100644
--- a/ironic/conf/__init__.py
+++ b/ironic/conf/__init__.py
@@ -20,6 +20,7 @@ from ironic.conf import cisco_ucs
 from ironic.conf import conductor
 from ironic.conf import console
 from ironic.conf import database
+from ironic.conf import default
 from ironic.conf import dhcp
 from ironic.conf import glance
 from ironic.conf import iboot
@@ -43,6 +44,7 @@ cisco_ucs.register_opts(CONF)
 conductor.register_opts(CONF)
 console.register_opts(CONF)
 database.register_opts(CONF)
+default.register_opts(CONF)
 dhcp.register_opts(CONF)
 glance.register_opts(CONF)
 iboot.register_opts(CONF)
diff --git a/ironic/conf/default.py b/ironic/conf/default.py
new file mode 100644
index 0000000000..8e4a94309a
--- /dev/null
+++ b/ironic/conf/default.py
@@ -0,0 +1,203 @@
+# Copyright 2016 Intel Corporation
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# Copyright 2013 Red Hat, Inc.
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# 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 os
+import socket
+import tempfile
+
+from oslo_config import cfg
+from oslo_utils import netutils
+
+from ironic.common.i18n import _
+
+api_opts = [
+    cfg.StrOpt(
+        'auth_strategy',
+        default='keystone',
+        choices=['noauth', 'keystone'],
+        help=_('Authentication strategy used by ironic-api. "noauth" should '
+               'not be used in a production environment because all '
+               'authentication will be disabled.')),
+    cfg.BoolOpt('debug_tracebacks_in_api',
+                default=False,
+                help=_('Return server tracebacks in the API response for any '
+                       'error responses. WARNING: this is insecure '
+                       'and should not be used in a production environment.')),
+    cfg.BoolOpt('pecan_debug',
+                default=False,
+                help=_('Enable pecan debug mode. WARNING: this is insecure '
+                       'and should not be used in a production environment.')),
+]
+
+driver_opts = [
+    cfg.ListOpt('enabled_drivers',
+                default=['pxe_ipmitool'],
+                help=_('Specify the list of drivers to load during service '
+                       'initialization. Missing drivers, or drivers which '
+                       'fail to initialize, will prevent the conductor '
+                       'service from starting. The option default is a '
+                       'recommended set of production-oriented drivers. A '
+                       'complete list of drivers present on your system may '
+                       'be found by enumerating the "ironic.drivers" '
+                       'entrypoint. An example may be found in the '
+                       'developer documentation online.')),
+    cfg.ListOpt('enabled_network_interfaces',
+                default=['flat', 'noop'],
+                help=_('Specify the list of network interfaces to load during '
+                       'service initialization. Missing network interfaces, '
+                       'or network interfaces which fail to initialize, will '
+                       'prevent the conductor service from starting. The '
+                       'option default is a recommended set of '
+                       'production-oriented network interfaces. A complete '
+                       'list of network interfaces present on your system may '
+                       'be found by enumerating the '
+                       '"ironic.hardware.interfaces.network" entrypoint. '
+                       'This value must be the same on all ironic-conductor '
+                       'and ironic-api services, because it is used by '
+                       'ironic-api service to validate a new or updated '
+                       'node\'s network_interface value.')),
+    cfg.StrOpt('default_network_interface',
+               help=_('Default network interface to be used for nodes that '
+                      'do not have network_interface field set. A complete '
+                      'list of network interfaces present on your system may '
+                      'be found by enumerating the '
+                      '"ironic.hardware.interfaces.network" entrypoint.'))
+]
+
+exc_log_opts = [
+    cfg.BoolOpt('fatal_exception_format_errors',
+                default=False,
+                help=_('Used if there is a formatting error when generating '
+                       'an exception message (a programming error). If True, '
+                       'raise an exception; if False, use the unformatted '
+                       'message.')),
+]
+
+hash_opts = [
+    cfg.IntOpt('hash_partition_exponent',
+               default=5,
+               help=_('Exponent to determine number of hash partitions to use '
+                      'when distributing load across conductors. Larger '
+                      'values will result in more even distribution of load '
+                      'and less load when rebalancing the ring, but more '
+                      'memory usage. Number of partitions per conductor is '
+                      '(2^hash_partition_exponent). This determines the '
+                      'granularity of rebalancing: given 10 hosts, and an '
+                      'exponent of the 2, there are 40 partitions in the ring.'
+                      'A few thousand partitions should make rebalancing '
+                      'smooth in most cases. The default is suitable for up '
+                      'to a few hundred conductors. Too many partitions has a '
+                      'CPU impact.')),
+    cfg.IntOpt('hash_distribution_replicas',
+               default=1,
+               help=_('[Experimental Feature] '
+                      'Number of hosts to map onto each hash partition. '
+                      'Setting this to more than one will cause additional '
+                      'conductor services to prepare deployment environments '
+                      'and potentially allow the Ironic cluster to recover '
+                      'more quickly if a conductor instance is terminated.')),
+    cfg.IntOpt('hash_ring_reset_interval',
+               default=180,
+               help=_('Interval (in seconds) between hash ring resets.')),
+]
+
+image_opts = [
+    cfg.BoolOpt('force_raw_images',
+                default=True,
+                help=_('If True, convert backing images to "raw" disk image '
+                       'format.')),
+    cfg.StrOpt('isolinux_bin',
+               default='/usr/lib/syslinux/isolinux.bin',
+               help=_('Path to isolinux binary file.')),
+    cfg.StrOpt('isolinux_config_template',
+               default=os.path.join('$pybasedir',
+                                    'common/isolinux_config.template'),
+               help=_('Template file for isolinux configuration file.')),
+    cfg.StrOpt('grub_config_template',
+               default=os.path.join('$pybasedir',
+                                    'common/grub_conf.template'),
+               help=_('Template file for grub configuration file.')),
+]
+
+img_cache_opts = [
+    cfg.BoolOpt('parallel_image_downloads',
+                default=False,
+                help=_('Run image downloads and raw format conversions in '
+                       'parallel.')),
+]
+
+netconf_opts = [
+    cfg.StrOpt('my_ip',
+               default=netutils.get_my_ipv4(),
+               sample_default='127.0.0.1',
+               help=_('IP address of this host. If unset, will determine the '
+                      'IP programmatically. If unable to do so, will use '
+                      '"127.0.0.1".')),
+]
+
+path_opts = [
+    cfg.StrOpt('pybasedir',
+               default=os.path.abspath(os.path.join(os.path.dirname(__file__),
+                                                    '../')),
+               sample_default='/usr/lib/python/site-packages/ironic/ironic',
+               help=_('Directory where the ironic python module is '
+                      'installed.')),
+    cfg.StrOpt('bindir',
+               default='$pybasedir/bin',
+               help=_('Directory where ironic binaries are installed.')),
+    cfg.StrOpt('state_path',
+               default='$pybasedir',
+               help=_("Top-level directory for maintaining ironic's state.")),
+]
+
+service_opts = [
+    cfg.StrOpt('host',
+               default=socket.getfqdn(),
+               sample_default='localhost',
+               help=_('Name of this node. This can be an opaque identifier. '
+                      'It is not necessarily a hostname, FQDN, or IP address. '
+                      'However, the node name must be valid within '
+                      'an AMQP key, and if using ZeroMQ, a valid '
+                      'hostname, FQDN, or IP address.')),
+]
+
+utils_opts = [
+    cfg.StrOpt('rootwrap_config',
+               default="/etc/ironic/rootwrap.conf",
+               help=_('Path to the rootwrap configuration file to use for '
+                      'running commands as root.')),
+    cfg.StrOpt('tempdir',
+               default=tempfile.gettempdir(),
+               sample_default='/tmp',
+               help=_('Temporary working directory, default is Python temp '
+                      'dir.')),
+]
+
+
+def register_opts(conf):
+    conf.register_opts(api_opts)
+    conf.register_opts(driver_opts)
+    conf.register_opts(exc_log_opts)
+    conf.register_opts(hash_opts)
+    conf.register_opts(image_opts)
+    conf.register_opts(img_cache_opts)
+    conf.register_opts(netconf_opts)
+    conf.register_opts(path_opts)
+    conf.register_opts(service_opts)
+    conf.register_opts(utils_opts)
diff --git a/ironic/conf/opts.py b/ironic/conf/opts.py
index 5043cb0070..1be7cd349f 100644
--- a/ironic/conf/opts.py
+++ b/ironic/conf/opts.py
@@ -13,37 +13,26 @@
 import itertools
 
 import ironic.api
-import ironic.api.app
-import ironic.common.driver_factory
-import ironic.common.exception
-import ironic.common.hash_ring
-import ironic.common.images
-import ironic.common.neutron
-import ironic.common.paths
-import ironic.common.service
-import ironic.common.utils
 import ironic.drivers.modules.agent
 import ironic.drivers.modules.agent_base_vendor
 import ironic.drivers.modules.agent_client
 import ironic.drivers.modules.amt.common
 import ironic.drivers.modules.amt.power
 import ironic.drivers.modules.deploy_utils
-import ironic.drivers.modules.image_cache
 import ironic.drivers.modules.iscsi_deploy
 import ironic.drivers.modules.pxe
-import ironic.netconf
 
 _default_opt_lists = [
-    ironic.api.app.api_opts,
-    ironic.common.driver_factory.driver_opts,
-    ironic.common.exception.exc_log_opts,
-    ironic.common.hash_ring.hash_opts,
-    ironic.common.images.image_opts,
-    ironic.common.paths.path_opts,
-    ironic.common.service.service_opts,
-    ironic.common.utils.utils_opts,
-    ironic.drivers.modules.image_cache.img_cache_opts,
-    ironic.netconf.netconf_opts,
+    ironic.conf.default.api_opts,
+    ironic.conf.default.driver_opts,
+    ironic.conf.default.exc_log_opts,
+    ironic.conf.default.hash_opts,
+    ironic.conf.default.image_opts,
+    ironic.conf.default.img_cache_opts,
+    ironic.conf.default.netconf_opts,
+    ironic.conf.default.path_opts,
+    ironic.conf.default.service_opts,
+    ironic.conf.default.utils_opts,
 ]
 
 _opts = [
diff --git a/ironic/drivers/base.py b/ironic/drivers/base.py
index b59c82e14b..63e44f94b6 100644
--- a/ironic/drivers/base.py
+++ b/ironic/drivers/base.py
@@ -24,7 +24,6 @@ import inspect
 import json
 import os
 
-from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import excutils
 import six
@@ -39,9 +38,6 @@ RAID_CONFIG_SCHEMA = os.path.join(os.path.dirname(__file__),
                                   'raid_config_schema.json')
 
 
-CONF = cfg.CONF
-
-
 @six.add_metaclass(abc.ABCMeta)
 class BaseDriver(object):
     """Base class for all drivers.
diff --git a/ironic/drivers/modules/agent.py b/ironic/drivers/modules/agent.py
index 2cf56809f7..eddd81c081 100644
--- a/ironic/drivers/modules/agent.py
+++ b/ironic/drivers/modules/agent.py
@@ -65,7 +65,6 @@ agent_opts = [
 ]
 
 CONF = cfg.CONF
-CONF.import_opt('my_ip', 'ironic.netconf')
 CONF.import_opt('erase_devices_priority',
                 'ironic.drivers.modules.deploy_utils', group='deploy')
 CONF.register_opts(agent_opts, group='agent')
diff --git a/ironic/drivers/modules/image_cache.py b/ironic/drivers/modules/image_cache.py
index 1835425907..533ce75835 100644
--- a/ironic/drivers/modules/image_cache.py
+++ b/ironic/drivers/modules/image_cache.py
@@ -24,33 +24,22 @@ import time
 import uuid
 
 from oslo_concurrency import lockutils
-from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import fileutils
 import six
 
 from ironic.common import exception
 from ironic.common.glance_service import service_utils
-from ironic.common.i18n import _
 from ironic.common.i18n import _LI
 from ironic.common.i18n import _LW
 from ironic.common import image_service
 from ironic.common import images
 from ironic.common import utils
+from ironic.conf import CONF
 
 
 LOG = logging.getLogger(__name__)
 
-img_cache_opts = [
-    cfg.BoolOpt('parallel_image_downloads',
-                default=False,
-                help=_('Run image downloads and raw format conversions in '
-                       'parallel.')),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(img_cache_opts)
-
 # This would contain a sorted list of instances of ImageCache to be
 # considered for cleanup. This list will be kept sorted in non-increasing
 # order of priority.
diff --git a/ironic/netconf.py b/ironic/netconf.py
index bfebd1a55e..e69de29bb2 100644
--- a/ironic/netconf.py
+++ b/ironic/netconf.py
@@ -1,34 +0,0 @@
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-# Copyright 2012 Red Hat, Inc.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from oslo_config import cfg
-from oslo_utils import netutils
-
-from ironic.common.i18n import _
-
-CONF = cfg.CONF
-
-netconf_opts = [
-    cfg.StrOpt('my_ip',
-               default=netutils.get_my_ipv4(),
-               sample_default='127.0.0.1',
-               help=_('IP address of this host. If unset, will determine the '
-                      'IP programmatically. If unable to do so, will use '
-                      '"127.0.0.1".')),
-]
-
-CONF.register_opts(netconf_opts)
diff --git a/ironic/tests/base.py b/ironic/tests/base.py
index 8a205ba631..e46ec07d2b 100644
--- a/ironic/tests/base.py
+++ b/ironic/tests/base.py
@@ -29,7 +29,6 @@ import tempfile
 import eventlet
 eventlet.monkey_patch(os=False)
 import fixtures
-from oslo_config import cfg
 from oslo_config import fixture as config_fixture
 from oslo_log import log as logging
 from oslo_utils import uuidutils
@@ -38,13 +37,11 @@ import testtools
 from ironic.common import config as ironic_config
 from ironic.common import context as ironic_context
 from ironic.common import hash_ring
+from ironic.conf import CONF
 from ironic.objects import base as objects_base
 from ironic.tests.unit import policy_fixture
 
 
-CONF = cfg.CONF
-CONF.import_opt('host', 'ironic.common.service')
-CONF.import_opt('cleaning_network_uuid', 'ironic.common.neutron', 'neutron')
 logging.register_options(CONF)
 logging.setup(CONF, 'ironic')