diff --git a/elements/puppet-stack-config/puppet-stack-config.yaml.template b/elements/puppet-stack-config/puppet-stack-config.yaml.template index ea8d3fbdd..b41302c9f 100644 --- a/elements/puppet-stack-config/puppet-stack-config.yaml.template +++ b/elements/puppet-stack-config/puppet-stack-config.yaml.template @@ -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}} diff --git a/instack_undercloud/tests/test_undercloud.py b/instack_undercloud/tests/test_undercloud.py index 27ca58056..991d8d7e0 100644 --- a/instack_undercloud/tests/test_undercloud.py +++ b/instack_undercloud/tests/test_undercloud.py @@ -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() diff --git a/instack_undercloud/undercloud.py b/instack_undercloud/undercloud.py index 8586c6020..5acc310f1 100644 --- a/instack_undercloud/undercloud.py +++ b/instack_undercloud/undercloud.py @@ -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() diff --git a/releasenotes/notes/switch-to-hw-types-b3abf03ef9b7973b.yaml b/releasenotes/notes/switch-to-hw-types-b3abf03ef9b7973b.yaml new file mode 100644 index 000000000..66626cd90 --- /dev/null +++ b/releasenotes/notes/switch-to-hw-types-b3abf03ef9b7973b.yaml @@ -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 + `_ + 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``. diff --git a/undercloud.conf.sample b/undercloud.conf.sample index ff0e3ff22..1cd2c881d 100644 --- a/undercloud.conf.sample +++ b/undercloud.conf.sample @@ -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)