More generic option for tuning adding ports

New option 'add_ports' with values 'all', 'active', 'pxe'.
Deprecate old option 'ports_for_inactive_interfaces' and drop
introduced in this cycle option 'only_pxe_booting_port'.

Change-Id: I40155fa1c4a54945cdc83506e741fc9be506b9db
Partial-Bug: #1404279
This commit is contained in:
Dmitry Tantsur 2015-03-23 17:08:07 +01:00
parent 18235ab8c1
commit b9e8e1e73f
5 changed files with 72 additions and 23 deletions

View File

@ -339,7 +339,7 @@ See `1.1.0 release tracking page`_ for details.
* Default to only creating a port for the NIC that the ramdisk was PXE booted
from, if such information is provided by ramdisk as ``boot_interface`` field.
Adjustable by ``only_pxe_booting_port`` option.
Adjustable by ``add_ports`` option.
See `better-boot-interface-detection blueprint
<https://blueprints.launchpad.net/ironic-discoverd/+spec/better-boot-interface-detection>`_
@ -359,6 +359,9 @@ See `1.1.0 release tracking page`_ for details.
**Other Changes**
* New option ``add_ports`` allows precise control over which ports to add,
replacing deprecated ``ports_for_inactive_interfaces``.
* Experimental plugin ``edeploy`` to use with `eDeploy hardware detection and
classification utilities`_.

View File

@ -29,16 +29,11 @@
;; Introspection process settings
; If set to false, discoverd will create ports only for those interfaces, that
; received IP address during ramdisk boot. Otherwise ports will be created
; for all interfaces. You should leave it as false, unless you encounter any
; bugs with this behavior. Has limited effect if only_pxe_booting_port is true.
;ports_for_inactive_interfaces = false
; If set to true, discoverd will try to detect the interface that node
; PXE booted from and will create a port only for it.
; If it cannot be detected, all ports will be created
; (regulated by ports_for_inactive_interfaces option).
;only_pxe_booting_port = true
; Which MAC addresses to add as ports during introspection. Possible values:
; all (all MAC addresses), active (MAC addresses of NIC with IP addresses),
; pxe (only MAC address of NIC node PXE booted from, falls back to 'active' if
; PXE MAC not supplied by the ramdisk).
;add_ports = pxe
; Timeout after which introspection is considered failed, set to 0 to disable.
;timeout = 3600
; For how much time (in seconds) to keep status information about nodes after
@ -77,3 +72,8 @@
;processing_hooks = scheduler,validate_interfaces
; Debug mode enabled/disabled.
;debug = false
;; Deprecated options
; Use add_ports
;ports_for_inactive_interfaces = false

View File

@ -29,8 +29,7 @@ DEFAULTS = {
'dnsmasq_interface': 'br-ctlplane',
'firewall_update_period': '15',
# Introspection process settings
'ports_for_inactive_interfaces': 'false',
'only_pxe_booting_port': 'true',
'add_ports': 'pxe',
'timeout': '3600',
'node_status_keep_time': '604800',
'clean_up_period': '60',

View File

@ -14,8 +14,9 @@
"""Standard set of plugins."""
import logging
import sys
from ironic_discoverd.common.i18n import _, _LI, _LW
from ironic_discoverd.common.i18n import _, _LC, _LI, _LW
from ironic_discoverd import conf
from ironic_discoverd.plugins import base
from ironic_discoverd import utils
@ -51,9 +52,28 @@ class SchedulerHook(base.ProcessingHook):
return patch, {}
VALID_ADD_PORTS_VALUES = ('all', 'active', 'pxe')
class ValidateInterfacesHook(base.ProcessingHook):
"""Hook to validate network interfaces."""
def __init__(self):
if conf.get('discoverd', 'add_ports') not in VALID_ADD_PORTS_VALUES:
LOG.critical(_LC('Accepted values for [discoverd]add_ports are '
'%(valid)s, got %(actual)s'),
{'valid': VALID_ADD_PORTS_VALUES,
'actual': conf.get('discoverd', 'add_ports')})
sys.exit(1)
def _ports_to_add(self):
if conf.getboolean('discoverd', 'ports_for_inactive_interfaces'):
LOG.warning(_LW('Using deprecated option '
'[discoverd]ports_for_inactive_interfaces'))
return 'all'
else:
return conf.get('discoverd', 'add_ports')
def before_processing(self, node_info):
"""Validate information about network interfaces."""
bmc_address = node_info.get('ipmi_address')
@ -65,12 +85,10 @@ class ValidateInterfacesHook(base.ProcessingHook):
if utils.is_valid_mac(iface.get('mac'))
}
ports_for_inactive = conf.getboolean('discoverd',
'ports_for_inactive_interfaces')
only_pxe = conf.getboolean('discoverd', 'only_pxe_booting_port')
ports_to_add = self._ports_to_add()
pxe_mac = node_info.get('boot_interface')
if only_pxe and pxe_mac:
if ports_to_add == 'pxe' and pxe_mac:
LOG.info(_LI('PXE boot interface was %s'), pxe_mac)
if '-' in pxe_mac:
# pxelinux format: 01-aa-bb-cc-dd-ee-ff
@ -81,7 +99,7 @@ class ValidateInterfacesHook(base.ProcessingHook):
n: iface for n, iface in valid_interfaces.items()
if iface['mac'].lower() == pxe_mac
}
elif not ports_for_inactive:
elif ports_to_add != 'all':
valid_interfaces = {
n: iface for n, iface in valid_interfaces.items()
if iface.get('ip')

View File

@ -22,6 +22,7 @@ from ironic_discoverd import conf
from ironic_discoverd import firewall
from ironic_discoverd import node_cache
from ironic_discoverd.plugins import example as example_plugin
from ironic_discoverd.plugins import standard as std_plugins
from ironic_discoverd import process
from ironic_discoverd.test import base as test_base
from ironic_discoverd import utils
@ -137,18 +138,39 @@ class TestProcess(BaseTest):
self.data, pop_mock.return_value)
@prepare_mocks
def test_non_pxe_interfaces(self, cli, pop_mock, process_mock):
conf.CONF.set('discoverd', 'only_pxe_booting_port', 'false')
def test_add_ports_active(self, cli, pop_mock, process_mock):
conf.CONF.set('discoverd', 'add_ports', 'active')
res = process.process(self.data)
self.assertEqual(self.fake_result_json, res)
self.assertEqual(['em1', 'em2'],
sorted(self.data['interfaces']))
self.assertEqual(['em1', 'em2', 'em3'],
sorted(self.data['all_interfaces']))
self.assertEqual(self.macs, sorted(self.data['macs']))
pop_mock.assert_called_once_with(bmc_address=self.bmc_address,
mac=self.data['macs'])
cli.node.get.assert_called_once_with(self.uuid)
process_mock.assert_called_once_with(cli, cli.node.get.return_value,
self.data, pop_mock.return_value)
@prepare_mocks
def test_add_ports_all(self, cli, pop_mock, process_mock):
conf.CONF.set('discoverd', 'add_ports', 'all')
res = process.process(self.data)
self.assertEqual(self.fake_result_json, res)
# By default interfaces w/o IP are dropped
self.assertEqual(['em1', 'em2'], sorted(self.data['interfaces']))
self.assertEqual(['em1', 'em2', 'em3'],
sorted(self.data['interfaces']))
self.assertEqual(['em1', 'em2', 'em3'],
sorted(self.data['all_interfaces']))
self.assertEqual(self.macs, sorted(self.data['macs']))
self.assertEqual(self.all_macs, sorted(self.data['macs']))
pop_mock.assert_called_once_with(bmc_address=self.bmc_address,
mac=self.data['macs'])
@ -175,6 +197,7 @@ class TestProcess(BaseTest):
@prepare_mocks
def test_ports_for_inactive(self, cli, pop_mock, process_mock):
conf.CONF.set('discoverd', 'ports_for_inactive_interfaces', 'true')
conf.CONF.remove_option('discoverd', 'add_ports')
del self.data['boot_interface']
process.process(self.data)
@ -481,3 +504,9 @@ class TestProcessNode(BaseTest):
mock.ANY,
error='Failed to power off node %s, check it\'s power management'
' configuration: boom' % self.uuid)
class TestValidateInterfacesHook(test_base.BaseTest):
def test_wrong_add_ports(self):
conf.CONF.set('discoverd', 'add_ports', 'foobar')
self.assertRaises(SystemExit, std_plugins.ValidateInterfacesHook)