Support more hardware types and deprecate enabled_drivers

Ironic is going to deprecate classic drivers in Queens and remove them in Rocky.
This change enables hardware types ilo and idrac that correspond to already
enabled classic drivers pxe_ilo and pxe_drac. It also adds support for other
common hardware types, but does not enable them by default.

The enabled_drivers option is deprecated.

Partial-Bug: #1690185
Change-Id: Ib505f3512627c49d17d6adcdc2622bdfe580a84f
This commit is contained in:
Dmitry Tantsur 2017-11-03 14:27:36 +01:00
parent 8e37c44fbf
commit 58701fe014
5 changed files with 176 additions and 45 deletions

View File

@ -513,10 +513,13 @@ ironic::conductor::default_boot_option: 'local'
ironic::conductor::enabled_drivers: {{ENABLED_DRIVERS}}
ironic::conductor::enabled_hardware_types: {{ENABLED_HARDWARE_TYPES}}
ironic::drivers::interfaces::default_inspect_interface: inspector
ironic::drivers::interfaces::enabled_boot_interfaces: {{ENABLED_BOOT_INTERFACES}}
ironic::drivers::interfaces::enabled_console_interfaces: ['no-console', 'ipmitool-socat']
ironic::drivers::interfaces::enabled_inspect_interfaces: ['no-inspect', 'inspector']
ironic::drivers::interfaces::enabled_management_interfaces: {{ENABLED_MANAGEMENT_INTERFACES}}
ironic::drivers::interfaces::enabled_power_interfaces: {{ENABLED_POWER_INTERFACES}}
ironic::drivers::interfaces::enabled_raid_interfaces: {{ENABLED_RAID_INTERFACES}}
ironic::drivers::interfaces::enabled_vendor_interfaces: {{ENABLED_VENDOR_INTERFACES}}
ironic::keystone::auth::tenant: 'service'
ironic::keystone::auth::public_url: {{UNDERCLOUD_ENDPOINT_IRONIC_PUBLIC}}
ironic::keystone::auth::internal_url: {{UNDERCLOUD_ENDPOINT_IRONIC_INTERNAL}}

View File

@ -482,19 +482,70 @@ class TestGenerateEnvironment(BaseTestCase):
drivers = json.loads(env['ENABLED_DRIVERS'])
self.assertEqual(sorted(drivers), ['pxe_drac', 'pxe_ilo',
'pxe_ipmitool'])
hw_types = json.loads(env['ENABLED_HARDWARE_TYPES'])
self.assertEqual(sorted(hw_types), ['idrac', 'ilo', 'ipmi', 'redfish'])
self.assertEqual(
sorted(json.loads(env['ENABLED_BOOT_INTERFACES'])),
['ilo-pxe', 'pxe'])
self.assertEqual(
sorted(json.loads(env['ENABLED_POWER_INTERFACES'])),
['fake', 'idrac', 'ilo', 'ipmitool', 'redfish'])
self.assertEqual(
sorted(json.loads(env['ENABLED_MANAGEMENT_INTERFACES'])),
['fake', 'idrac', 'ilo', 'ipmitool', 'redfish'])
self.assertEqual(
sorted(json.loads(env['ENABLED_RAID_INTERFACES'])),
['idrac', 'no-raid'])
self.assertEqual(
sorted(json.loads(env['ENABLED_VENDOR_INTERFACES'])),
['idrac', 'ipmitool', 'no-vendor'])
self.assertEqual(env['INSPECTION_NODE_NOT_FOUND_HOOK'], '')
def test_all_hardware_types(self):
conf = config_fixture.Config()
self.useFixture(conf)
conf.config(enabled_hardware_types=['ipmi', 'redfish', 'ilo',
'idrac', 'irmc', 'snmp',
'cisco-ucs-managed',
'cisco-ucs-standalone'])
env = undercloud._generate_environment('.')
# The list is generated from a set, so we can't rely on ordering.
# Instead make sure that it looks like a valid list by parsing it.
hw_types = json.loads(env['ENABLED_HARDWARE_TYPES'])
self.assertEqual(sorted(hw_types), ['cisco-ucs-managed',
'cisco-ucs-standalone',
'idrac', 'ilo', 'ipmi', 'irmc',
'redfish', 'snmp'])
self.assertEqual(
sorted(json.loads(env['ENABLED_BOOT_INTERFACES'])),
['ilo-pxe', 'irmc-pxe', 'pxe'])
self.assertEqual(
sorted(json.loads(env['ENABLED_POWER_INTERFACES'])),
['cimc', 'fake', 'idrac', 'ilo', 'ipmitool', 'irmc',
'redfish', 'snmp', 'ucsm'])
self.assertEqual(
sorted(json.loads(env['ENABLED_MANAGEMENT_INTERFACES'])),
['cimc', 'fake', 'idrac', 'ilo', 'ipmitool', 'irmc',
'redfish', 'ucsm'])
self.assertEqual(
sorted(json.loads(env['ENABLED_RAID_INTERFACES'])),
['idrac', 'no-raid'])
self.assertEqual(
sorted(json.loads(env['ENABLED_VENDOR_INTERFACES'])),
['idrac', 'ipmitool', 'no-vendor'])
def test_enabled_discovery(self):
conf = config_fixture.Config()
self.useFixture(conf)
conf.config(enable_node_discovery=True,
discovery_default_driver='foobar')
discovery_default_driver='pxe_foobar')
env = undercloud._generate_environment('.')
# The list is generated from a set, so we can't rely on ordering.
# Instead make sure that it looks like a valid list by parsing it.
drivers = json.loads(env['ENABLED_DRIVERS'])
# Discovery requires enabling the default driver
self.assertEqual(sorted(drivers), ['foobar', 'pxe_drac', 'pxe_ilo',
# Discovery requires enabling the default driver. The pxe_ prefix
# designates a classic driver.
self.assertEqual(sorted(drivers), ['pxe_drac', 'pxe_foobar', 'pxe_ilo',
'pxe_ipmitool'])
self.assertEqual(env['INSPECTION_NODE_NOT_FOUND_HOOK'], 'enroll')
@ -503,17 +554,15 @@ class TestGenerateEnvironment(BaseTestCase):
self.useFixture(conf)
conf.config(enable_node_discovery=True,
discovery_default_driver='foobar',
enabled_hardware_types=['ipmi', 'foobar'])
enabled_hardware_types=['ipmi', 'something'])
env = undercloud._generate_environment('.')
# The list is generated from a set, so we can't rely on ordering.
# Instead make sure that it looks like a valid list by parsing it.
drivers = json.loads(env['ENABLED_DRIVERS'])
hw_types = json.loads(env['ENABLED_HARDWARE_TYPES'])
# The driver is already in hardware types, so we don't try adding it to
# the driver list.
self.assertEqual(sorted(drivers), ['pxe_drac', 'pxe_ilo',
'pxe_ipmitool'])
self.assertEqual(sorted(hw_types), ['foobar', 'ipmi'])
self.assertEqual(sorted(hw_types), ['foobar', 'ipmi', 'something'])
def test_docker_registry_mirror(self):
conf = config_fixture.Config()

View File

@ -289,10 +289,11 @@ _opts = [
'information for newly enrolled nodes.')
),
cfg.StrOpt('discovery_default_driver',
default='pxe_ipmitool',
help=('The default driver to use for newly discovered nodes '
'(requires enable_node_discovery set to True). This '
'driver is automatically added to enabled_drivers.')
default='ipmi',
help=('The default driver or hardware type to use for newly '
'discovered nodes (requires enable_node_discovery set to '
'True). It is automatically added to enabled_drivers '
'or enabled_hardware_types accordingly.')
),
cfg.BoolOpt('undercloud_debug',
default=True,
@ -360,9 +361,12 @@ _opts = [
'between deployments and after the introspection.')),
cfg.ListOpt('enabled_drivers',
default=['pxe_ipmitool', 'pxe_drac', 'pxe_ilo'],
help=('List of enabled bare metal drivers.')),
help=('List of enabled bare metal drivers.'),
deprecated_for_removal=True,
deprecated_reason=('Please switch to hardware types and '
'the enabled_hardware_types option.')),
cfg.ListOpt('enabled_hardware_types',
default=['ipmi', 'redfish'],
default=['ipmi', 'redfish', 'ilo', 'idrac'],
help=('List of enabled bare metal hardware types (next '
'generation drivers).')),
cfg.StrOpt('docker_registry_mirror',
@ -1056,7 +1060,8 @@ class InstackEnvironment(dict):
'INSPECTION_NODE_NOT_FOUND_HOOK',
'TRIPLEO_INSTALL_USER', 'TRIPLEO_UNDERCLOUD_CONF_FILE',
'TRIPLEO_UNDERCLOUD_PASSWORD_FILE',
'ENABLED_POWER_INTERFACES',
'ENABLED_BOOT_INTERFACES', 'ENABLED_POWER_INTERFACES',
'ENABLED_RAID_INTERFACES', 'ENABLED_VENDOR_INTERFACES',
'ENABLED_MANAGEMENT_INTERFACES', 'SYSCTL_SETTINGS',
'LOCAL_IP_WRAPPED'}
"""The variables we calculate in _generate_environment call."""
@ -1091,6 +1096,76 @@ def _generate_sysctl_settings():
return json.dumps(sysctl_settings)
def _is_classic_driver(name):
"""Poor man's way to detect if something is a driver or a hardware type.
To be removed when we remove support for classic drivers.
"""
return (name == 'fake' or
name.startswith('fake_') or
name.startswith('pxe_') or
name.startswith('agent_') or
name.startswith('iscsi_'))
def _process_drivers_and_hardware_types(instack_env):
"""Populate the environment with ironic driver information."""
# Ensure correct rendering of the list and uniqueness of the items
enabled_drivers = set(CONF.enabled_drivers)
enabled_hardware_types = set(CONF.enabled_hardware_types)
if CONF.enable_node_discovery:
if _is_classic_driver(CONF.discovery_default_driver):
if CONF.discovery_default_driver not in enabled_drivers:
enabled_drivers.add(CONF.discovery_default_driver)
else:
if CONF.discovery_default_driver not in enabled_hardware_types:
enabled_hardware_types.add(CONF.discovery_default_driver)
instack_env['INSPECTION_NODE_NOT_FOUND_HOOK'] = 'enroll'
else:
instack_env['INSPECTION_NODE_NOT_FOUND_HOOK'] = ''
# In most cases power and management interfaces are called the same, so we
# use one variable for them.
mgmt_interfaces = {'fake', 'ipmitool'}
# TODO(dtantsur): can we somehow avoid hardcoding hardware types here?
for hw_type in ('redfish', 'idrac', 'ilo', 'irmc'):
if hw_type in enabled_hardware_types:
mgmt_interfaces.add(hw_type)
for (hw_type, iface) in [('cisco-ucs-managed', 'ucsm'),
('cisco-ucs-standalone', 'cimc')]:
if hw_type in enabled_hardware_types:
mgmt_interfaces.add(iface)
# Two hardware types use non-default boot interfaces.
boot_interfaces = {'pxe'}
for hw_type in ('ilo', 'irmc'):
if hw_type in enabled_hardware_types:
boot_interfaces.add('%s-pxe' % hw_type)
raid_interfaces = {'no-raid'}
if 'idrac' in enabled_hardware_types:
raid_interfaces.add('idrac')
vendor_interfaces = {'no-vendor'}
for (hw_type, iface) in [('ipmi', 'ipmitool'),
('idrac', 'idrac')]:
if hw_type in enabled_hardware_types:
vendor_interfaces.add(iface)
instack_env['ENABLED_DRIVERS'] = _make_list(enabled_drivers)
instack_env['ENABLED_HARDWARE_TYPES'] = _make_list(enabled_hardware_types)
instack_env['ENABLED_BOOT_INTERFACES'] = _make_list(boot_interfaces)
instack_env['ENABLED_MANAGEMENT_INTERFACES'] = _make_list(mgmt_interfaces)
instack_env['ENABLED_RAID_INTERFACES'] = _make_list(raid_interfaces)
instack_env['ENABLED_VENDOR_INTERFACES'] = _make_list(vendor_interfaces)
# The snmp hardware type uses fake management and snmp power
if 'snmp' in enabled_hardware_types:
mgmt_interfaces.add('snmp')
instack_env['ENABLED_POWER_INTERFACES'] = _make_list(mgmt_interfaces)
def _generate_environment(instack_root):
"""Generate an environment dict for instack
@ -1172,31 +1247,7 @@ def _generate_environment(instack_root):
instack_env['INSPECTION_KERNEL_ARGS'] = ' '.join(inspection_kernel_args)
# Ensure correct rendering of the list and uniqueness of the items
enabled_drivers = set(CONF.enabled_drivers)
enabled_hardware_types = set(CONF.enabled_hardware_types)
if CONF.enable_node_discovery:
if (CONF.discovery_default_driver not in (enabled_drivers |
enabled_hardware_types)):
enabled_drivers.add(CONF.discovery_default_driver)
instack_env['INSPECTION_NODE_NOT_FOUND_HOOK'] = 'enroll'
else:
instack_env['INSPECTION_NODE_NOT_FOUND_HOOK'] = ''
# In most cases power and management interfaces are called the same, so we
# use one variable for them.
enabled_interfaces = set()
if 'ipmi' in enabled_hardware_types:
enabled_interfaces.add('ipmitool')
if 'redfish' in enabled_hardware_types:
enabled_interfaces.add('redfish')
instack_env['ENABLED_DRIVERS'] = _make_list(enabled_drivers)
instack_env['ENABLED_HARDWARE_TYPES'] = _make_list(enabled_hardware_types)
enabled_interfaces = _make_list(enabled_interfaces)
instack_env['ENABLED_POWER_INTERFACES'] = enabled_interfaces
instack_env['ENABLED_MANAGEMENT_INTERFACES'] = enabled_interfaces
_process_drivers_and_hardware_types(instack_env)
instack_env['SYSCTL_SETTINGS'] = _generate_sysctl_settings()

View File

@ -0,0 +1,23 @@
---
features:
- |
The hardware types ``ilo`` and ``idrac`` are now enabled by default.
- |
Added support for the following hardware types: ``cisco-ucs-managed``,
``cisco-ucs-standalone``, ``idrac``, ``ilo``, ``irmc``, ``snmp``.
deprecations:
- |
The ``enabled_drivers`` option is deprecated, please use
``enabled_hardware_types``. Make sure to switch your nodes to hardware
types before disabling drivers.
upgrade:
- |
Classic drivers are going to be deprecated soon, it is recommended to
switch all overcloud nodes to matching hardware types. See the `hardware
types migration documentation
<https://docs.openstack.org/ironic/latest/admin/upgrade-to-hardware-types.html>`_
for the detailed procedure.
- |
As part of migration to hardware types, the default value of the
``discovery_default_driver`` option was changed from ``pxe_ipmitool``
to ``ipmi``.

View File

@ -141,10 +141,11 @@
# for newly enrolled nodes. (boolean value)
#enable_node_discovery = false
# The default driver to use for newly discovered nodes (requires
# enable_node_discovery set to True). This driver is automatically
# added to enabled_drivers. (string value)
#discovery_default_driver = pxe_ipmitool
# The default driver or hardware type to use for newly discovered
# nodes (requires enable_node_discovery set to True). It is
# automatically added to enabled_drivers or enabled_hardware_types
# accordingly. (string value)
#discovery_default_driver = ipmi
# Whether to enable the debug log level for Undercloud OpenStack
# services. (boolean value)
@ -199,12 +200,16 @@
# deployments and after the introspection. (boolean value)
#clean_nodes = false
# List of enabled bare metal drivers. (list value)
# DEPRECATED: List of enabled bare metal drivers. (list value)
# This option is deprecated for removal.
# Its value may be silently ignored in the future.
# Reason: Please switch to hardware types and the
# enabled_hardware_types option.
#enabled_drivers = pxe_ipmitool,pxe_drac,pxe_ilo
# List of enabled bare metal hardware types (next generation drivers).
# (list value)
#enabled_hardware_types = ipmi,redfish
#enabled_hardware_types = ipmi,redfish,ilo,idrac
# An optional docker 'registry-mirror' that will beconfigured in
# /etc/docker/daemon.json. (string value)