Merge "Allow ramdisk to specify PXE boot interface"
This commit is contained in:
commit
2fbe520ba8
|
@ -324,6 +324,14 @@ See `1.1.0 release tracking page`_ for details.
|
|||
|
||||
**Major Features**
|
||||
|
||||
* 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.
|
||||
|
||||
See `better-boot-interface-detection blueprint
|
||||
<https://blueprints.launchpad.net/ironic-discoverd/+spec/better-boot-interface-detection>`_
|
||||
for details.
|
||||
|
||||
**Other Changes**
|
||||
|
||||
* Experimental plugin ``edeploy`` to use with
|
||||
|
|
|
@ -32,8 +32,13 @@
|
|||
; 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.
|
||||
; 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
|
||||
; 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
|
||||
|
|
|
@ -29,6 +29,7 @@ DEFAULTS = {
|
|||
'firewall_update_period': '15',
|
||||
# Introspection process settings
|
||||
'ports_for_inactive_interfaces': 'false',
|
||||
'only_pxe_booting_port': 'true',
|
||||
'timeout': '3600',
|
||||
'node_status_keep_time': '604800',
|
||||
'clean_up_period': '60',
|
||||
|
|
|
@ -66,7 +66,17 @@ class ValidateInterfacesHook(base.ProcessingHook):
|
|||
|
||||
ports_for_inactive = conf.getboolean('discoverd',
|
||||
'ports_for_inactive_interfaces')
|
||||
if not ports_for_inactive:
|
||||
only_pxe = conf.getboolean('discoverd', 'only_pxe_booting_port')
|
||||
pxe_mac = node_info.get('boot_interface')
|
||||
|
||||
if only_pxe and pxe_mac:
|
||||
LOG.info('PXE boot interface was %s', pxe_mac)
|
||||
pxe_mac = pxe_mac.replace('-', ':').lower()
|
||||
valid_interfaces = {
|
||||
n: iface for n, iface in valid_interfaces.items()
|
||||
if iface['mac'].lower() == pxe_mac
|
||||
}
|
||||
elif not ports_for_inactive:
|
||||
valid_interfaces = {
|
||||
n: iface for n, iface in valid_interfaces.items()
|
||||
if iface.get('ip')
|
||||
|
|
|
@ -34,6 +34,7 @@ class BaseTest(test_base.NodeTest):
|
|||
'ramdisk_error,scheduler,validate_interfaces')
|
||||
self.started_at = time.time()
|
||||
self.all_macs = self.macs + ['DE:AD:BE:EF:DE:AD']
|
||||
self.pxe_mac = self.macs[1]
|
||||
self.data = {
|
||||
'ipmi_address': self.bmc_address,
|
||||
'cpus': 2,
|
||||
|
@ -44,12 +45,14 @@ class BaseTest(test_base.NodeTest):
|
|||
'em1': {'mac': self.macs[0], 'ip': '1.2.0.1'},
|
||||
'em2': {'mac': self.macs[1], 'ip': '1.2.0.2'},
|
||||
'em3': {'mac': self.all_macs[2]},
|
||||
}
|
||||
},
|
||||
'boot_interface': self.pxe_mac,
|
||||
}
|
||||
self.ports = [
|
||||
self.all_ports = [
|
||||
mock.Mock(uuid='port_uuid%d' % i, address=mac)
|
||||
for i, mac in enumerate(self.macs)
|
||||
]
|
||||
self.ports = [self.all_ports[1]]
|
||||
|
||||
|
||||
@mock.patch.object(process, '_process_node', autospec=True)
|
||||
|
@ -81,6 +84,46 @@ class TestProcess(BaseTest):
|
|||
|
||||
self.assertEqual(self.fake_result_json, res)
|
||||
|
||||
# Only boot interface is added by default
|
||||
self.assertEqual(['em2'], sorted(self.data['interfaces']))
|
||||
self.assertEqual(['em1', 'em2', 'em3'],
|
||||
sorted(self.data['all_interfaces']))
|
||||
self.assertEqual([self.pxe_mac], 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_no_boot_interface(self, cli, pop_mock, process_mock):
|
||||
del self.data['boot_interface']
|
||||
|
||||
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['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_non_pxe_interfaces(self, cli, pop_mock, process_mock):
|
||||
conf.CONF.set('discoverd', 'only_pxe_booting_port', 'false')
|
||||
|
||||
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'],
|
||||
|
@ -112,6 +155,8 @@ 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')
|
||||
del self.data['boot_interface']
|
||||
|
||||
process.process(self.data)
|
||||
|
||||
self.assertEqual(['em1', 'em2', 'em3'],
|
||||
|
@ -234,6 +279,7 @@ class TestProcessNode(BaseTest):
|
|||
self.validate_attempts = 5
|
||||
self.power_off_attempts = 2
|
||||
self.data['macs'] = self.macs # validate_interfaces hook
|
||||
self.ports = self.all_ports
|
||||
self.cached_node = node_cache.NodeInfo(uuid=self.uuid,
|
||||
started_at=self.started_at)
|
||||
self.patch_before = [
|
||||
|
|
Loading…
Reference in New Issue