Fix DHCPv6 support
Adds logic to handle the appropriate replies for DHCPv6 responses. The IPv6 nature was discovered while researching differences and finding that the field ID value changes between IPv4 and IPv6 DHCP clients, as DHCPv6 is purely booting from a URL. Change-Id: I63572bea9bfb150aaeb4708dfa57e71adf4f64ab Task: 9788 Story: 1744620 Story: 2003934
This commit is contained in:
parent
b766343183
commit
90d58ede94
@ -43,9 +43,15 @@ PXE_CFG_DIR_NAME = CONF.pxe.pxe_config_subdir
|
||||
DHCP_CLIENT_ID = '61' # rfc2132
|
||||
DHCP_TFTP_SERVER_NAME = '66' # rfc2132
|
||||
DHCP_BOOTFILE_NAME = '67' # rfc2132
|
||||
DHCPV6_BOOTFILE_NAME = '59' # rfc5870
|
||||
# NOTE(TheJulia): adding note for the bootfile parameter
|
||||
# field as defined by RFC 5870. No practical examples seem
|
||||
# available. Neither grub2 or ipxe seem to leverage this.
|
||||
# DHCPV6_BOOTFILE_PARAMS = '60' # rfc5870
|
||||
DHCP_TFTP_SERVER_ADDRESS = '150' # rfc5859
|
||||
DHCP_IPXE_ENCAP_OPTS = '175' # Tentatively Assigned
|
||||
DHCP_TFTP_PATH_PREFIX = '210' # rfc5071
|
||||
|
||||
DEPLOY_KERNEL_RAMDISK_LABELS = ['deploy_kernel', 'deploy_ramdisk']
|
||||
RESCUE_KERNEL_RAMDISK_LABELS = ['rescue_kernel', 'rescue_ramdisk']
|
||||
KERNEL_RAMDISK_LABELS = {'deploy': DEPLOY_KERNEL_RAMDISK_LABELS,
|
||||
@ -391,16 +397,58 @@ def clean_up_pxe_config(task):
|
||||
task.node.uuid))
|
||||
|
||||
|
||||
def dhcp_options_for_instance(task):
|
||||
def _dhcp_option_file_or_url(task, urlboot=False):
|
||||
"""Returns the appropriate file or URL.
|
||||
|
||||
:param task: A TaskManager object.
|
||||
:param url_boot: Boolean value default False to indicate if a
|
||||
URL should be returned to the file as opposed
|
||||
to a file.
|
||||
"""
|
||||
boot_file = deploy_utils.get_pxe_boot_file(task.node)
|
||||
# NOTE(TheJulia): There are additional cases as we add new
|
||||
# features, so the logic below is in the form of if/elif/elif
|
||||
if not urlboot:
|
||||
return boot_file
|
||||
elif urlboot:
|
||||
path_prefix = get_tftp_path_prefix()
|
||||
if path_prefix == '':
|
||||
path_prefix = '/'
|
||||
return ("tftp://" + CONF.pxe.tftp_server
|
||||
+ path_prefix + boot_file)
|
||||
|
||||
|
||||
def dhcp_options_for_instance(task, ipxe_enabled=False, url_boot=False):
|
||||
"""Retrieves the DHCP PXE boot options.
|
||||
|
||||
:param task: A TaskManager instance.
|
||||
:param ipxe_enabled: Default false boolean that siganls if iPXE
|
||||
formatting should be returned by the method
|
||||
for DHCP server configuration.
|
||||
:param url_boot: Default false boolean to inform the method if
|
||||
a URL should be returned to boot the node.
|
||||
If [pxe]ip_version is set to `6`, then this option
|
||||
has no effect as url_boot form is required by DHCPv6
|
||||
standards.
|
||||
:returns: Dictionary to be sent to the networking service describing
|
||||
the DHCP options to be set.
|
||||
"""
|
||||
dhcp_opts = []
|
||||
ip_version = int(CONF.pxe.ip_version)
|
||||
if ip_version == 4:
|
||||
boot_file_param = DHCP_BOOTFILE_NAME
|
||||
else:
|
||||
# NOTE(TheJulia): Booting with v6 means it is always
|
||||
# a URL reply.
|
||||
boot_file_param = DHCPV6_BOOTFILE_NAME
|
||||
url_boot = True
|
||||
# NOTE(TheJulia): The ip_version value config from the PXE config is
|
||||
# guarded in the configuration, so there is no real sense in having
|
||||
# anything else here in the event the value is something aside from
|
||||
# 4 or 6, as there are no other possible values.
|
||||
boot_file = _dhcp_option_file_or_url(task, url_boot)
|
||||
|
||||
boot_file = deploy_utils.get_pxe_boot_file(task.node)
|
||||
|
||||
if is_ipxe_enabled(task):
|
||||
if ipxe_enabled:
|
||||
script_name = os.path.basename(CONF.pxe.ipxe_boot_script)
|
||||
ipxe_script_url = '/'.join([CONF.deploy.http_url, script_name])
|
||||
dhcp_provider_name = CONF.dhcp.dhcp_provider
|
||||
@ -409,7 +457,7 @@ def dhcp_options_for_instance(task):
|
||||
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
|
||||
dhcp_opts.append({'opt_name': "tag:!ipxe,%s" % DHCP_BOOTFILE_NAME,
|
||||
dhcp_opts.append({'opt_name': "tag:!ipxe,%s" % boot_file_param,
|
||||
'opt_value': boot_file})
|
||||
dhcp_opts.append({'opt_name': "tag:ipxe,%s" % DHCP_BOOTFILE_NAME,
|
||||
'opt_value': ipxe_script_url})
|
||||
@ -417,25 +465,27 @@ def dhcp_options_for_instance(task):
|
||||
# !175 == non-iPXE.
|
||||
# http://ipxe.org/howto/dhcpd#ipxe-specific_options
|
||||
dhcp_opts.append({'opt_name': "!%s,%s" % (DHCP_IPXE_ENCAP_OPTS,
|
||||
DHCP_BOOTFILE_NAME),
|
||||
boot_file_param),
|
||||
'opt_value': boot_file})
|
||||
dhcp_opts.append({'opt_name': DHCP_BOOTFILE_NAME,
|
||||
dhcp_opts.append({'opt_name': boot_file_param,
|
||||
'opt_value': ipxe_script_url})
|
||||
else:
|
||||
dhcp_opts.append({'opt_name': DHCP_BOOTFILE_NAME,
|
||||
dhcp_opts.append({'opt_name': boot_file_param,
|
||||
'opt_value': boot_file})
|
||||
# 210 == tftp server path-prefix or tftp root, will be used to find
|
||||
# pxelinux.cfg directory. The pxelinux.0 loader infers this information
|
||||
# from it's own path, but Petitboot needs it to be specified by this
|
||||
# option since it doesn't use pxelinux.0 loader.
|
||||
dhcp_opts.append({'opt_name': DHCP_TFTP_PATH_PREFIX,
|
||||
'opt_value': get_tftp_path_prefix()})
|
||||
|
||||
dhcp_opts.append({'opt_name': DHCP_TFTP_SERVER_NAME,
|
||||
'opt_value': CONF.pxe.tftp_server})
|
||||
dhcp_opts.append({'opt_name': DHCP_TFTP_SERVER_ADDRESS,
|
||||
'opt_value': CONF.pxe.tftp_server})
|
||||
if not url_boot:
|
||||
dhcp_opts.append(
|
||||
{'opt_name': DHCP_TFTP_PATH_PREFIX,
|
||||
'opt_value': get_tftp_path_prefix()})
|
||||
|
||||
if not url_boot:
|
||||
dhcp_opts.append({'opt_name': DHCP_TFTP_SERVER_NAME,
|
||||
'opt_value': CONF.pxe.tftp_server})
|
||||
dhcp_opts.append({'opt_name': DHCP_TFTP_SERVER_ADDRESS,
|
||||
'opt_value': CONF.pxe.tftp_server})
|
||||
# NOTE(vsaienko) set this option specially for dnsmasq case as it always
|
||||
# sets `siaddr` field which is treated by pxe clients as TFTP server
|
||||
# see page 9 https://tools.ietf.org/html/rfc2131.
|
||||
@ -449,12 +499,13 @@ def dhcp_options_for_instance(task):
|
||||
# unknown options but potentially it may blow up with others.
|
||||
# Related bug was opened on Neutron side:
|
||||
# https://bugs.launchpad.net/neutron/+bug/1723354
|
||||
dhcp_opts.append({'opt_name': 'server-ip-address',
|
||||
'opt_value': CONF.pxe.tftp_server})
|
||||
if not url_boot:
|
||||
dhcp_opts.append({'opt_name': 'server-ip-address',
|
||||
'opt_value': CONF.pxe.tftp_server})
|
||||
|
||||
# Append the IP version for all the configuration options
|
||||
for opt in dhcp_opts:
|
||||
opt.update({'ip_version': int(CONF.pxe.ip_version)})
|
||||
opt.update({'ip_version': ip_version})
|
||||
|
||||
return dhcp_opts
|
||||
|
||||
@ -593,10 +644,10 @@ def get_image_info(node, mode='deploy'):
|
||||
def build_deploy_pxe_options(task, pxe_info, mode='deploy'):
|
||||
pxe_opts = {}
|
||||
node = task.node
|
||||
|
||||
# TODO(TheJulia): In the future this should become an argument
|
||||
ipxe_enabled = is_ipxe_enabled(task)
|
||||
kernel_label = '%s_kernel' % mode
|
||||
ramdisk_label = '%s_ramdisk' % mode
|
||||
ipxe_enabled = is_ipxe_enabled(task)
|
||||
for label, option in ((kernel_label, 'deployment_aki_path'),
|
||||
(ramdisk_label, 'deployment_ari_path')):
|
||||
if ipxe_enabled:
|
||||
@ -839,7 +890,7 @@ def prepare_instance_pxe_config(task, image_info,
|
||||
"""
|
||||
|
||||
node = task.node
|
||||
dhcp_opts = dhcp_options_for_instance(task)
|
||||
dhcp_opts = dhcp_options_for_instance(task, ipxe_enabled)
|
||||
provider = dhcp_factory.DHCPFactory()
|
||||
provider.update_dhcp(task, dhcp_opts)
|
||||
pxe_config_path = get_pxe_config_file_path(
|
||||
|
@ -142,7 +142,8 @@ class iPXEBoot(pxe_base.PXEBaseMixin, base.BootInterface):
|
||||
# or was deleted.
|
||||
pxe_utils.create_ipxe_boot_script()
|
||||
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=True)
|
||||
provider = dhcp_factory.DHCPFactory()
|
||||
provider.update_dhcp(task, dhcp_opts)
|
||||
|
||||
@ -219,7 +220,8 @@ class iPXEBoot(pxe_base.PXEBaseMixin, base.BootInterface):
|
||||
pxe_utils.cache_ramdisk_kernel(task, instance_image_info)
|
||||
|
||||
# If it's going to PXE boot we need to update the DHCP server
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task,
|
||||
ipxe_enabled=True)
|
||||
provider = dhcp_factory.DHCPFactory()
|
||||
provider.update_dhcp(task, dhcp_opts)
|
||||
|
||||
|
@ -141,8 +141,8 @@ class PXEBoot(pxe_base.PXEBaseMixin, base.BootInterface):
|
||||
"""
|
||||
node = task.node
|
||||
mode = deploy_utils.rescue_or_deploy_mode(node)
|
||||
|
||||
if CONF.pxe.ipxe_enabled:
|
||||
ipxe_enabled = CONF.pxe.ipxe_enabled
|
||||
if ipxe_enabled:
|
||||
# NOTE(mjturek): At this point, the ipxe boot script should
|
||||
# already exist as it is created at startup time. However, we
|
||||
# call the boot script create method here to assert its
|
||||
@ -150,7 +150,8 @@ class PXEBoot(pxe_base.PXEBaseMixin, base.BootInterface):
|
||||
# or was deleted.
|
||||
pxe_utils.create_ipxe_boot_script()
|
||||
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=ipxe_enabled)
|
||||
provider = dhcp_factory.DHCPFactory()
|
||||
provider.update_dhcp(task, dhcp_opts)
|
||||
|
||||
@ -224,7 +225,8 @@ class PXEBoot(pxe_base.PXEBaseMixin, base.BootInterface):
|
||||
pxe_utils.cache_ramdisk_kernel(task, instance_image_info)
|
||||
|
||||
# If it's going to PXE boot we need to update the DHCP server
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled)
|
||||
provider = dhcp_factory.DHCPFactory()
|
||||
provider.update_dhcp(task, dhcp_opts)
|
||||
|
||||
|
@ -719,22 +719,33 @@ class TestPXEUtils(db_base.DbTestCase):
|
||||
self.config(tftp_server='192.0.2.1', group='pxe')
|
||||
self.config(pxe_bootfile_name='fake-bootfile', group='pxe')
|
||||
self.config(tftp_root='/tftp-path/', group='pxe')
|
||||
expected_info = [{'opt_name': '67',
|
||||
'opt_value': 'fake-bootfile',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': '210',
|
||||
'opt_value': '/tftp-path/',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': '66',
|
||||
'opt_value': '192.0.2.1',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': '150',
|
||||
'opt_value': '192.0.2.1',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': 'server-ip-address',
|
||||
'opt_value': '192.0.2.1',
|
||||
'ip_version': ip_version}
|
||||
]
|
||||
|
||||
if ip_version == 6:
|
||||
# NOTE(TheJulia): DHCPv6 RFCs seem to indicate that the prior
|
||||
# options are not imported, although they may be supported
|
||||
# by vendors. The apparent proper option is to return a
|
||||
# URL in the field https://tools.ietf.org/html/rfc5970#section-3
|
||||
expected_info = [{'opt_name': '59',
|
||||
'opt_value': 'tftp://192.0.2.1/tftp-path'
|
||||
'/fake-bootfile',
|
||||
'ip_version': ip_version}]
|
||||
elif ip_version == 4:
|
||||
expected_info = [{'opt_name': '67',
|
||||
'opt_value': 'fake-bootfile',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': '210',
|
||||
'opt_value': '/tftp-path/',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': '66',
|
||||
'opt_value': '192.0.2.1',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': '150',
|
||||
'opt_value': '192.0.2.1',
|
||||
'ip_version': ip_version},
|
||||
{'opt_name': 'server-ip-address',
|
||||
'opt_value': '192.0.2.1',
|
||||
'ip_version': ip_version}
|
||||
]
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
self.assertEqual(expected_info,
|
||||
pxe_utils.dhcp_options_for_instance(task))
|
||||
@ -817,7 +828,8 @@ class TestPXEUtils(db_base.DbTestCase):
|
||||
'ip_version': 4}]
|
||||
|
||||
self.assertItemsEqual(expected_info,
|
||||
pxe_utils.dhcp_options_for_instance(task))
|
||||
pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=True))
|
||||
|
||||
self.config(dhcp_provider='neutron', group='dhcp')
|
||||
expected_boot_script_url = 'http://192.0.3.2:1234/boot.ipxe'
|
||||
@ -838,7 +850,8 @@ class TestPXEUtils(db_base.DbTestCase):
|
||||
'ip_version': 4}]
|
||||
|
||||
self.assertItemsEqual(expected_info,
|
||||
pxe_utils.dhcp_options_for_instance(task))
|
||||
pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=True))
|
||||
|
||||
def test_dhcp_options_for_instance_ipxe_bios(self):
|
||||
boot_file = 'fake-bootfile-bios'
|
||||
|
@ -257,7 +257,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
|
||||
'rescue_ramdisk': 'r'}
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=True)
|
||||
task.driver.boot.prepare_ramdisk(task, {'foo': 'bar'})
|
||||
mock_deploy_img_info.assert_called_once_with(task.node, mode=mode)
|
||||
provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
|
||||
@ -538,7 +539,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
|
||||
'ramdisk': ('', '/path/to/ramdisk')}
|
||||
get_image_info_mock.return_value = image_info
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=True)
|
||||
pxe_config_path = pxe_utils.get_pxe_config_file_path(
|
||||
task.node.uuid)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
@ -578,7 +580,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
|
||||
self.node.provision_state = states.ACTIVE
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=True)
|
||||
pxe_config_path = pxe_utils.get_pxe_config_file_path(
|
||||
task.node.uuid)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
@ -615,7 +618,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
|
||||
'ramdisk': ('', '/path/to/ramdisk')}
|
||||
get_image_info_mock.return_value = image_info
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=True)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = False
|
||||
|
||||
@ -644,7 +648,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
|
||||
dhcp_factory_mock.return_value = provider_mock
|
||||
get_image_info_mock.return_value = {}
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=True)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = True
|
||||
task.driver.boot.prepare_instance(task)
|
||||
@ -688,7 +693,8 @@ class iPXEBootTestCase(db_base.DbTestCase):
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
task.node.driver_internal_info = {
|
||||
'boot_from_volume': vol_id}
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task,
|
||||
ipxe_enabled=True)
|
||||
pxe_config_path = pxe_utils.get_pxe_config_file_path(
|
||||
task.node.uuid)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
|
@ -255,7 +255,8 @@ class PXEBootTestCase(db_base.DbTestCase):
|
||||
'rescue_ramdisk': 'r'}
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=CONF.pxe.ipxe_enabled)
|
||||
task.driver.boot.prepare_ramdisk(task, {'foo': 'bar'})
|
||||
mock_deploy_img_info.assert_called_once_with(task.node, mode=mode)
|
||||
provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
|
||||
@ -543,7 +544,8 @@ class PXEBootTestCase(db_base.DbTestCase):
|
||||
'ramdisk': ('', '/path/to/ramdisk')}
|
||||
get_image_info_mock.return_value = image_info
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=CONF.pxe.ipxe_enabled)
|
||||
pxe_config_path = pxe_utils.get_pxe_config_file_path(
|
||||
task.node.uuid)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
@ -583,7 +585,8 @@ class PXEBootTestCase(db_base.DbTestCase):
|
||||
self.node.provision_state = states.ACTIVE
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=CONF.pxe.ipxe_enabled)
|
||||
pxe_config_path = pxe_utils.get_pxe_config_file_path(
|
||||
task.node.uuid)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
@ -621,7 +624,8 @@ class PXEBootTestCase(db_base.DbTestCase):
|
||||
'ramdisk': ('', '/path/to/ramdisk')}
|
||||
get_image_info_mock.return_value = image_info
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=CONF.pxe.ipxe_enabled)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = False
|
||||
|
||||
@ -647,7 +651,8 @@ class PXEBootTestCase(db_base.DbTestCase):
|
||||
dhcp_factory_mock.return_value = provider_mock
|
||||
get_image_info_mock.return_value = {}
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, CONF.pxe.ipxe_enabled)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
task.node.driver_internal_info['is_whole_disk_image'] = True
|
||||
task.driver.boot.prepare_instance(task)
|
||||
@ -691,7 +696,8 @@ class PXEBootTestCase(db_base.DbTestCase):
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
task.node.driver_internal_info = {
|
||||
'boot_from_volume': vol_id}
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task,
|
||||
ipxe_enabled=True)
|
||||
pxe_config_path = pxe_utils.get_pxe_config_file_path(
|
||||
task.node.uuid)
|
||||
task.node.properties['capabilities'] = 'boot_mode:bios'
|
||||
@ -780,7 +786,8 @@ class PXEBootTestCase(db_base.DbTestCase):
|
||||
instance_info['capabilities'] = {'boot_option': 'ramdisk'}
|
||||
task.node.instance_info = instance_info
|
||||
task.node.save()
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=CONF.pxe.ipxe_enabled)
|
||||
pxe_config_path = pxe_utils.get_pxe_config_file_path(
|
||||
task.node.uuid)
|
||||
task.driver.boot.prepare_instance(task)
|
||||
@ -871,7 +878,8 @@ class PXERamdiskDeployTestCase(db_base.DbTestCase):
|
||||
'ramdisk': ('', '/path/to/ramdisk')}
|
||||
get_image_info_mock.return_value = image_info
|
||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
|
||||
dhcp_opts = pxe_utils.dhcp_options_for_instance(
|
||||
task, ipxe_enabled=CONF.pxe.ipxe_enabled)
|
||||
pxe_config_path = pxe_utils.get_pxe_config_file_path(
|
||||
task.node.uuid)
|
||||
task.node.properties['capabilities'] = 'boot_option:netboot'
|
||||
|
9
releasenotes/notes/boot-from-url-98d21670e726c518.yaml
Normal file
9
releasenotes/notes/boot-from-url-98d21670e726c518.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixes a misunderstanding in how DHCPv6 booting of machines operates
|
||||
in that only a URL to the boot loader is expected in that case, as opposed
|
||||
to traditional TFTP parameters. Now a URL is sent to the client in the form
|
||||
of ``tftp://<tftp_address>/<tftp_path>/<boot_file>``. See
|
||||
`story 1744620 <https://storyboard.openstack.org/#!/story/1744620>`_
|
||||
for more information.
|
Loading…
Reference in New Issue
Block a user