Merge "Fix DHCPv6 support"
This commit is contained in:
commit
dd02698ad4
@ -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…
x
Reference in New Issue
Block a user