diff --git a/ironic/common/pxe_utils.py b/ironic/common/pxe_utils.py index e6d631d38b..0a0ff400c7 100644 --- a/ironic/common/pxe_utils.py +++ b/ironic/common/pxe_utils.py @@ -465,15 +465,35 @@ def dhcp_options_for_instance(task, ipxe_enabled=False, url_boot=False): # if the request comes from dumb firmware send them the iPXE # boot image. if dhcp_provider_name == 'neutron': - # Neutron use dnsmasq as default DHCP agent, add extra config - # to neutron "dhcp-match=set:ipxe,175" and use below option + # Neutron use dnsmasq as default DHCP agent. Neutron carries the + # configuration to relate to the tags below. The ipxe6 tag was + # added in the Stein cycle which identifies the iPXE User-Class + # directly and is only sent in DHCPv6. + + # NOTE(TheJulia): Lets send both, let neutron tag/sort it out as + # an ip_version field is also transmitted. Plus, given the + # semi-obscure nature of this, being more verbose and letting + # the DHCP server do the best thing possible is likely the best + # course of action. dhcp_opts.append({'opt_name': "tag:!ipxe,%s" % boot_file_param, 'opt_value': boot_file}) + dhcp_opts.append({'opt_name': "tag:!ipxe6,%s" % boot_file_param, + 'opt_value': boot_file}) dhcp_opts.append({'opt_name': "tag:ipxe,%s" % boot_file_param, 'opt_value': ipxe_script_url}) + dhcp_opts.append({'opt_name': "tag:ipxe6,%s" % boot_file_param, + 'opt_value': ipxe_script_url}) else: # !175 == non-iPXE. # http://ipxe.org/howto/dhcpd#ipxe-specific_options + if ip_version == 6: + LOG.warning('IPv6 is enabled and the DHCP driver appears set ' + 'to a plugin aside from "neutron". Node %(name)s ' + 'may not receive proper DHCPv6 provided ' + 'boot parameters.'.format(name=task.node.uuid)) + # NOTE(TheJulia): This was added for ISC DHCPd support, however it + # appears that isc support was never added to neutron and is likely + # a down stream driver. dhcp_opts.append({'opt_name': "!%s,%s" % (DHCP_IPXE_ENCAP_OPTS, boot_file_param), 'opt_value': boot_file}) diff --git a/ironic/tests/unit/common/test_pxe_utils.py b/ironic/tests/unit/common/test_pxe_utils.py index 87f64c2630..f0eebb21d4 100644 --- a/ironic/tests/unit/common/test_pxe_utils.py +++ b/ironic/tests/unit/common/test_pxe_utils.py @@ -860,13 +860,23 @@ class TestPXEUtils(db_base.DbTestCase): expected_info = [{'opt_name': 'tag:!ipxe,59', 'opt_value': 'tftp://[ff80::1]/fake-bootfile', 'ip_version': ip_version}, + {'opt_name': 'tag:!ipxe6,59', + 'opt_value': 'tftp://[ff80::1]/fake-bootfile', + 'ip_version': ip_version}, {'opt_name': 'tag:ipxe,59', + 'opt_value': expected_boot_script_url, + 'ip_version': ip_version}, + {'opt_name': 'tag:ipxe6,59', 'opt_value': expected_boot_script_url, 'ip_version': ip_version}] + elif ip_version == 4: expected_info = [{'opt_name': 'tag:!ipxe,67', 'opt_value': boot_file, 'ip_version': ip_version}, + {'opt_name': 'tag:!ipxe6,67', + 'opt_value': boot_file, + 'ip_version': ip_version}, {'opt_name': '66', 'opt_value': '192.0.2.1', 'ip_version': ip_version}, @@ -876,6 +886,9 @@ class TestPXEUtils(db_base.DbTestCase): {'opt_name': 'tag:ipxe,67', 'opt_value': expected_boot_script_url, 'ip_version': ip_version}, + {'opt_name': 'tag:ipxe6,67', + 'opt_value': expected_boot_script_url, + 'ip_version': ip_version}, {'opt_name': 'server-ip-address', 'opt_value': '192.0.2.1', 'ip_version': ip_version}] diff --git a/releasenotes/notes/ipxe-with-dhcpv6-2bc7bd7f53a70f51.yaml b/releasenotes/notes/ipxe-with-dhcpv6-2bc7bd7f53a70f51.yaml new file mode 100644 index 0000000000..655d26fcb6 --- /dev/null +++ b/releasenotes/notes/ipxe-with-dhcpv6-2bc7bd7f53a70f51.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixes an issue has been corrected where hosts executing ``iPXE`` to boot + would error indicating that no configuration was found for networks where + IPv6 is in use. This has been remedied through a minor addition to the + Networking service in the Stein development cycle. For more information + please see `story 2004502 `_.