diff --git a/elements/puppet-stack-config/puppet-stack-config.pp b/elements/puppet-stack-config/puppet-stack-config.pp index cc3b2da7f..b1db304f4 100644 --- a/elements/puppet-stack-config/puppet-stack-config.pp +++ b/elements/puppet-stack-config/puppet-stack-config.pp @@ -505,8 +505,10 @@ include ::ironic::conductor include ::ironic::drivers::drac include ::ironic::drivers::ilo include ::ironic::drivers::inspector +include ::ironic::drivers::interfaces include ::ironic::drivers::ipmi include ::ironic::drivers::pxe +include ::ironic::drivers::redfish include ::ironic::glance include ::ironic::inspector include ::ironic::neutron diff --git a/elements/puppet-stack-config/puppet-stack-config.yaml.template b/elements/puppet-stack-config/puppet-stack-config.yaml.template index 9c7f41998..edfa3b6c8 100644 --- a/elements/puppet-stack-config/puppet-stack-config.yaml.template +++ b/elements/puppet-stack-config/puppet-stack-config.yaml.template @@ -462,7 +462,6 @@ nova::db::sync_api::db_sync_timeout: 900 # Ironic ironic::debug: "%{hiera('debug')}" ironic::my_ip: {{LOCAL_IP}} -ironic::enabled_drivers: {{ENABLED_DRIVERS}} ironic::rpc_response_timeout: 600 ironic::api::authtoken::password: {{UNDERCLOUD_IRONIC_PASSWORD}} ironic::api::authtoken::auth_uri: "%{hiera('keystone_auth_uri')}" @@ -491,6 +490,13 @@ ironic::conductor::cleaning_disk_erase: 'metadata' ironic::conductor::cleaning_network: 'ctlplane' ironic::conductor::provisioning_network: 'ctlplane' 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_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::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 a79f310c0..46b7785bf 100644 --- a/instack_undercloud/tests/test_undercloud.py +++ b/instack_undercloud/tests/test_undercloud.py @@ -418,6 +418,23 @@ class TestGenerateEnvironment(BaseTestCase): 'pxe_ipmitool']) self.assertEqual(env['INSPECTION_NODE_NOT_FOUND_HOOK'], 'enroll') + def test_enabled_hardware_types(self): + conf = config_fixture.Config() + self.useFixture(conf) + conf.config(enable_node_discovery=True, + discovery_default_driver='foobar', + enabled_hardware_types=['ipmi', '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']) + 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']) + def test_docker_registry_mirror(self): conf = config_fixture.Config() self.useFixture(conf) diff --git a/instack_undercloud/undercloud.py b/instack_undercloud/undercloud.py index 2d3df6ee5..6121592c4 100644 --- a/instack_undercloud/undercloud.py +++ b/instack_undercloud/undercloud.py @@ -364,6 +364,10 @@ _opts = [ cfg.ListOpt('enabled_drivers', default=['pxe_ipmitool', 'pxe_drac', 'pxe_ilo'], help=('List of enabled bare metal drivers.')), + cfg.ListOpt('enabled_hardware_types', + default=['ipmi', 'redfish'], + help=('List of enabled bare metal hardware types (next ' + 'generation drivers).')), cfg.StrOpt('docker_registry_mirror', default='', help=('An optional docker \'registry-mirror\' that will be' @@ -996,7 +1000,9 @@ class InstackEnvironment(dict): DYNAMIC_KEYS = {'INSPECTION_COLLECTORS', 'INSPECTION_KERNEL_ARGS', 'INSPECTION_NODE_NOT_FOUND_HOOK', 'TRIPLEO_INSTALL_USER', 'TRIPLEO_UNDERCLOUD_CONF_FILE', - 'TRIPLEO_UNDERCLOUD_PASSWORD_FILE'} + 'TRIPLEO_UNDERCLOUD_PASSWORD_FILE', + 'ENABLED_POWER_INTERFACES', + 'ENABLED_MANAGEMENT_INTERFACES'} """The variables we calculate in _generate_environment call.""" PUPPET_KEYS = DYNAMIC_KEYS | {opt.name.upper() for _, group in list_opts() @@ -1016,6 +1022,11 @@ class InstackEnvironment(dict): return super(InstackEnvironment, self).__setitem__(key, value) +def _make_list(values): + """Generate a list suitable to pass to templates.""" + return '[%s]' % ', '.join('"%s"' % item for item in values) + + def _generate_environment(instack_root): """Generate an environment dict for instack @@ -1098,14 +1109,29 @@ def _generate_environment(instack_root): # 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: - enabled_drivers.add(CONF.discovery_default_driver) + 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'] = '' - instack_env['ENABLED_DRIVERS'] = ( - '[%s]' % ', '.join('"%s"' % drv for drv in set(enabled_drivers))) + # 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 if CONF.docker_registry_mirror: instack_env['DOCKER_REGISTRY_MIRROR'] = CONF.docker_registry_mirror diff --git a/releasenotes/notes/hw-types-ded17c6d920e1feb.yaml b/releasenotes/notes/hw-types-ded17c6d920e1feb.yaml new file mode 100644 index 000000000..72314f65c --- /dev/null +++ b/releasenotes/notes/hw-types-ded17c6d920e1feb.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Allow configuring enabled hardware types via new ``enabled_hardware_types`` + configuration option. See `the driver composition reform spec + `_ + for details. Enabled management and power interfaces are derived for + known hardware types. Inspection via **ironic-inspector** and + ``socat``-based serial console support is enabled by default. + - | + Support Redfish-compatible hardware via ``redfish`` hardware type. diff --git a/undercloud.conf.sample b/undercloud.conf.sample index 83da4ae2b..e205f4c12 100644 --- a/undercloud.conf.sample +++ b/undercloud.conf.sample @@ -208,6 +208,10 @@ # List of enabled bare metal drivers. (list value) #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 + # An optional docker 'registry-mirror' that will beconfigured in # /etc/docker/daemon.json. (string value) #docker_registry_mirror =