launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #11469
[Merge] lp:~jtv/maas/bug-1042877 into lp:maas
Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/bug-1042877 into lp:maas.
Requested reviews:
MAAS Maintainers (maas-maintainers)
For more details, see:
https://code.launchpad.net/~jtv/maas/bug-1042877/+merge/122049
I pre-imped this with Gavin, but also called in Daviey and Robie for details. A lot changes, and unfortunately it all more or less had to do so in one go:
* Instead of re-using /var/lib/tftpboot/, create our own /var/lib/maas/tftp/.
* No more "maas/" prefix: pxelinux.0, pxelinux.cfg/01-aa-bb-cc-dd-ee-ff, i386/generic/precise/install/kernel.
* Don't download pxelinux.0; take just the i386 binary from syslinux.
* Consistently get all pxelinux files from /usr/lib/syslinux; don't mix installed modules with downloaded loaders.
* Drop bootpath and related complexity.
One small bit that I managed to leave for later: CURRENT_RELEASE should no longer be needed in maas-import-pxe-files. I'll remove that separately.
Rather than trawl through the MP diff, you may find it easier to read the commit log as a blow-by-blow account.
Jeroen
--
https://code.launchpad.net/~jtv/maas/bug-1042877/+merge/122049
Your team MAAS Maintainers is requested to review the proposed merge of lp:~jtv/maas/bug-1042877 into lp:maas.
=== modified file 'etc/pserv.yaml'
--- etc/pserv.yaml 2012-08-30 06:25:25 +0000
+++ etc/pserv.yaml 2012-08-30 12:19:20 +0000
@@ -31,7 +31,7 @@
## TFTP configuration.
#
tftp:
- # root: /var/lib/tftpboot
+ root: /var/lib/maas/tftp
# port: 69
port: 5244
## The URL to be contacted to generate PXE configurations.
=== modified file 'scripts/maas-import-pxe-files'
--- scripts/maas-import-pxe-files 2012-08-28 23:35:55 +0000
+++ scripts/maas-import-pxe-files 2012-08-30 12:19:20 +0000
@@ -6,7 +6,7 @@
# pre-boot loader, kernels, and initrd images.
#
# This script downloads the required files into the TFTP home directory
-# (by default, /var/lib/tftpboot). Run it with the necessarily privileges
+# (by default, /var/lib/maas/tftp). Run it with the necessarily privileges
# to write them there.
# Exit immediately if a command exits with a non-zero status.
@@ -64,31 +64,15 @@
}
-# Download the pre-boot loader, pxelinux.0, for architecture $1. If
-# successful, install it for netboot use. (Not all architectures need this
-# file, and there's rarely an urgent need for the very latest file, so if
-# the download fails this function just skips it.)
+# Copy the pre-boot loader pxelinux.0, and modules we need, from the
+# installed syslinux version. Install it into the TFTP tree for
+# netbooting.
update_pre_boot_loader() {
- local arch=$1
- local url=$(compose_installer_download_url $arch $CURRENT_RELEASE)
- if ! $DOWNLOAD $url/pxelinux.0
- then
- echo "Could not download pre-boot loader for $arch; skipping."
- return
- fi
-
- # If the file has changed, move it into place (replacing any previous
- # version). Otherwise, leave the filesystem alone.
- if [ -f pxelinux.0 ]
- then
- # TODO: pxelinux.0 is downloaded but there's no reason why it can't
- # come from the syslinux package like chain.c32 is.
- maas-provision install-pxe-bootloader --loader='pxelinux.0'
- maas-provision install-pxe-bootloader \
- --loader='/usr/lib/syslinux/chain.c32'
- maas-provision install-pxe-bootloader \
- --loader='/usr/lib/syslinux/ifcpu64.c32'
- fi
+ for loader_file in pxelinux.0 chain.c32 ifcpu64.c32
+ do
+ maas-provision install-pxe-bootloader \
+ --loader="/usr/lib/syslinux/$loader_file"
+ done
}
@@ -122,14 +106,8 @@
echo "Downloading to temporary location $DOWNLOAD_DIR."
pushd -- $DOWNLOAD_DIR
- # All files we create here are public. The TFTP user will need to be
- # able to read them.
- umask a+r
-
for arch in $ARCHES
do
- update_pre_boot_loader $arch
-
for release in $RELEASES
do
update_install_files $arch $release
@@ -151,7 +129,11 @@
main() {
+ # All files we create here are public. The TFTP user will need to be
+ # able to read them.
+ umask a+r
+ update_pre_boot_loader
import_install_images
import_ephemeral_images
}
=== modified file 'src/provisioningserver/config.py'
--- src/provisioningserver/config.py 2012-08-30 06:25:25 +0000
+++ src/provisioningserver/config.py 2012-08-30 12:19:20 +0000
@@ -59,7 +59,7 @@
if_key_missing = None
- root = String(if_missing="/var/lib/tftpboot")
+ root = String(if_missing="/var/lib/maas/tftp")
port = Int(min=1, max=65535, if_missing=69)
generator = String(if_missing=b"http://localhost/MAAS/api/1.0/pxeconfig/")
=== modified file 'src/provisioningserver/pxe/config.commissioning.template'
--- src/provisioningserver/pxe/config.commissioning.template 2012-08-24 12:48:12 +0000
+++ src/provisioningserver/pxe/config.commissioning.template 2012-08-30 12:19:20 +0000
@@ -6,14 +6,14 @@
LABEL amd64
SAY Booting (amd64) under MAAS direction...
- KERNEL {{kernel_params(arch="amd64") | kernel_path | relative}}
- INITRD {{kernel_params(arch="amd64") | initrd_path | relative}}
+ KERNEL {{kernel_params(arch="amd64") | kernel_path }}
+ INITRD {{kernel_params(arch="amd64") | initrd_path }}
APPEND {{kernel_params(arch="amd64") | kernel_command}}
IPAPPEND 2
LABEL i386
SAY Booting (i386) under MAAS direction...
- KERNEL {{kernel_params(arch="i386") | kernel_path | relative}}
- INITRD {{kernel_params(arch="i386") | initrd_path | relative}}
+ KERNEL {{kernel_params(arch="i386") | kernel_path }}
+ INITRD {{kernel_params(arch="i386") | initrd_path }}
APPEND {{kernel_params(arch="i386") | kernel_command}}
IPAPPEND 2
=== modified file 'src/provisioningserver/pxe/config.py'
--- src/provisioningserver/pxe/config.py 2012-08-24 19:14:58 +0000
+++ src/provisioningserver/pxe/config.py 2012-08-30 12:19:20 +0000
@@ -23,7 +23,6 @@
from errno import ENOENT
from os import path
-import posixpath
from provisioningserver.kernel_opts import compose_kernel_command_line_new
from provisioningserver.pxe.tftppath import compose_image_path
import tempita
@@ -71,18 +70,14 @@
"No PXE template found in %r!" % template_dir)
-def render_pxe_config(bootpath, kernel_params, **extra):
+def render_pxe_config(kernel_params, **extra):
"""Render a PXE configuration file as a unicode string.
- :param bootpath: The directory path of `pxelinux.0`.
:param kernel_params: An instance of `KernelParameters`.
:param extra: Allow for other arguments. This is a safety valve;
parameters generated in another component (for example, see
`TFTPBackend.get_config_reader`) won't cause this to break.
"""
- if bootpath is None:
- bootpath = ''
-
template = get_pxe_template(
kernel_params.purpose, kernel_params.arch,
kernel_params.subarch)
@@ -95,24 +90,19 @@
params.arch, params.subarch,
params.release, params.purpose)
- def initrd(params):
+ def initrd_path(params):
return "%s/initrd.gz" % image_dir(params)
- def kernel(params):
+ def kernel_path(params):
return "%s/linux" % image_dir(params)
def kernel_command(params):
return compose_kernel_command_line_new(params)
- def relative(path):
- # Return `path` relative to `bootpath`.
- return posixpath.relpath(path, start=bootpath)
-
namespace = {
- "initrd_path": initrd,
+ "initrd_path": initrd_path,
"kernel_command": kernel_command,
"kernel_params": kernel_params,
- "kernel_path": kernel,
- "relative": relative,
+ "kernel_path": kernel_path,
}
return template.substitute(namespace)
=== modified file 'src/provisioningserver/pxe/config.template'
--- src/provisioningserver/pxe/config.template 2012-08-24 12:48:12 +0000
+++ src/provisioningserver/pxe/config.template 2012-08-30 12:19:20 +0000
@@ -2,7 +2,7 @@
LABEL execute
SAY Booting under MAAS direction...
- KERNEL {{kernel_params | kernel_path | relative}}
- INITRD {{kernel_params | initrd_path | relative}}
+ KERNEL {{kernel_params | kernel_path }}
+ INITRD {{kernel_params | initrd_path }}
APPEND {{kernel_params | kernel_command}}
IPAPPEND 2
=== modified file 'src/provisioningserver/pxe/install_bootloader.py'
--- src/provisioningserver/pxe/install_bootloader.py 2012-08-17 14:28:27 +0000
+++ src/provisioningserver/pxe/install_bootloader.py 2012-08-30 12:19:20 +0000
@@ -30,7 +30,7 @@
"""Locate a loader's destination, creating the directory if needed.
:param tftproot: The root directory served up by the TFTP server,
- e.g. /var/lib/tftpboot/.
+ e.g. /var/lib/maas/tftp/.
:return: Full path describing the directory that the installed loader
should end up having.
"""
=== modified file 'src/provisioningserver/pxe/install_image.py'
--- src/provisioningserver/pxe/install_image.py 2012-07-23 10:24:39 +0000
+++ src/provisioningserver/pxe/install_image.py 2012-08-30 12:19:20 +0000
@@ -33,7 +33,7 @@
"""Locate an image's destination. Create containing directory if needed.
:param tftproot: The root directory served up by the TFTP server,
- e.g. /var/lib/tftpboot/.
+ e.g. /var/lib/maas/tftp/.
:param arch: Main architecture to locate the destination for.
:param subarch: Sub-architecture of the main architecture.
:param release: OS release name, e.g. "precise".
=== modified file 'src/provisioningserver/pxe/tests/test_config.py'
--- src/provisioningserver/pxe/tests/test_config.py 2012-08-24 16:23:15 +0000
+++ src/provisioningserver/pxe/tests/test_config.py 2012-08-30 12:19:20 +0000
@@ -21,7 +21,6 @@
from maastesting.matchers import ContainsAll
from maastesting.testcase import TestCase
import mock
-import posixpath
from provisioningserver import kernel_opts
from provisioningserver.pxe import config
from provisioningserver.pxe.config import render_pxe_config
@@ -150,9 +149,8 @@
def test_render(self):
# Given the right configuration options, the PXE configuration is
# correctly rendered.
- bootpath = factory.make_name("bootpath")
params = make_kernel_parameters()
- output = render_pxe_config(bootpath=bootpath, kernel_params=params)
+ output = render_pxe_config(kernel_params=params)
# The output is always a Unicode string.
self.assertThat(output, IsInstance(unicode))
# The template has rendered without error. PXELINUX configurations
@@ -162,7 +160,6 @@
image_dir = compose_image_path(
arch=params.arch, subarch=params.subarch,
release=params.release, purpose=params.purpose)
- image_dir = posixpath.relpath(image_dir, bootpath)
self.assertThat(
output, MatchesAll(
MatchesRegex(
@@ -177,10 +174,7 @@
def test_render_with_extra_arguments_does_not_affect_output(self):
# render_pxe_config() allows any keyword arguments as a safety valve.
- options = {
- "bootpath": factory.make_name("bootpath"),
- "kernel_params": make_kernel_parameters(),
- }
+ options = {"kernel_params": make_kernel_parameters()}
# Capture the output before sprinking in some random options.
output_before = render_pxe_config(**options)
# Sprinkle some magic in.
@@ -196,7 +190,6 @@
# If purpose is "local", the config.localboot.template should be
# used.
options = {
- "bootpath": factory.make_name("bootpath"),
"kernel_params":
make_kernel_parameters()._replace(purpose="local"),
}
@@ -207,7 +200,6 @@
# Intel i386 is a special case and needs to use the chain.c32
# loader as the LOCALBOOT PXE directive is unreliable.
options = {
- "bootpath": factory.make_name("bootpath"),
"kernel_params": make_kernel_parameters()._replace(
arch="i386", purpose="local"),
}
@@ -219,7 +211,6 @@
# Intel amd64 is a special case and needs to use the chain.c32
# loader as the LOCALBOOT PXE directive is unreliable.
options = {
- "bootpath": factory.make_name("bootpath"),
"kernel_params": make_kernel_parameters()._replace(
arch="amd64", purpose="local"),
}
@@ -233,7 +224,6 @@
get_ephemeral_name = self.patch(kernel_opts, "get_ephemeral_name")
get_ephemeral_name.return_value = factory.make_name("ephemeral")
options = {
- "bootpath": factory.make_name("bootpath"),
"kernel_params": make_kernel_parameters()._replace(
purpose="commissioning"),
}
@@ -251,13 +241,14 @@
default_section["APPEND"].split())
# Both "i386" and "amd64" sections exist.
self.assertThat(config, ContainsAll(("i386", "amd64")))
- # Each section defines KERNEL, INITRD, and APPEND settings, each
- # containing paths referring to their architectures.
+ # Each section defines KERNEL, INITRD, and APPEND settings. The
+ # KERNEL and INITRD ones contain paths referring to their
+ # architectures.
for section_label in ("i386", "amd64"):
section = config[section_label]
self.assertThat(
section, ContainsAll(("KERNEL", "INITRD", "APPEND")))
- contains_arch_path = Contains("/%s/" % section_label)
+ contains_arch_path = StartsWith("%s/" % section_label)
self.assertThat(section["KERNEL"], contains_arch_path)
self.assertThat(section["INITRD"], contains_arch_path)
- self.assertThat(section["APPEND"], contains_arch_path)
+ self.assertIn("APPEND", section)
=== modified file 'src/provisioningserver/pxe/tests/test_install_image.py'
--- src/provisioningserver/pxe/tests/test_install_image.py 2012-07-23 13:25:15 +0000
+++ src/provisioningserver/pxe/tests/test_install_image.py 2012-08-30 12:19:20 +0000
@@ -79,13 +79,13 @@
def test_make_destination_follows_pxe_path_conventions(self):
# The directory that make_destination returns follows the PXE
# directory hierarchy specified for MAAS:
- # /var/lib/tftproot/maas/<arch>/<subarch>/<release>/<purpose>
- # (Where the /var/lib/tftproot/ part is configurable, so we
+ # /var/lib/maas/tftp/<arch>/<subarch>/<release>/<purpose>
+ # (Where the /var/lib/maas/tftp/ part is configurable, so we
# can test this without overwriting system files).
tftproot = self.make_dir()
arch, subarch, release, purpose = make_arch_subarch_release_purpose()
self.assertEqual(
- os.path.join(tftproot, 'maas', arch, subarch, release, purpose),
+ os.path.join(tftproot, arch, subarch, release, purpose),
make_destination(tftproot, arch, subarch, release, purpose))
def test_make_destination_creates_directory_if_not_present(self):
=== modified file 'src/provisioningserver/pxe/tests/test_tftppath.py'
--- src/provisioningserver/pxe/tests/test_tftppath.py 2012-08-17 14:11:20 +0000
+++ src/provisioningserver/pxe/tests/test_tftppath.py 2012-08-30 12:19:20 +0000
@@ -41,7 +41,7 @@
def test_compose_config_path_follows_maas_pxe_directory_layout(self):
name = factory.make_name('config')
self.assertEqual(
- 'maas/pxelinux.cfg/%02x-%s' % (ARP_HTYPE.ETHERNET, name),
+ 'pxelinux.cfg/%02x-%s' % (ARP_HTYPE.ETHERNET, name),
compose_config_path(name))
def test_compose_config_path_does_not_include_tftp_root(self):
@@ -56,7 +56,7 @@
release = factory.make_name('release')
purpose = factory.make_name('purpose')
self.assertEqual(
- 'maas/%s/%s/%s/%s' % (arch, subarch, release, purpose),
+ '%s/%s/%s/%s' % (arch, subarch, release, purpose),
compose_image_path(arch, subarch, release, purpose))
def test_compose_image_path_does_not_include_tftp_root(self):
@@ -69,7 +69,7 @@
Not(StartsWith(self.tftproot)))
def test_compose_bootloader_path_follows_maas_pxe_directory_layout(self):
- self.assertEqual('maas/pxelinux.0', compose_bootloader_path())
+ self.assertEqual('pxelinux.0', compose_bootloader_path())
def test_compose_bootloader_path_does_not_include_tftp_root(self):
self.assertThat(
=== modified file 'src/provisioningserver/pxe/tftppath.py'
--- src/provisioningserver/pxe/tftppath.py 2012-08-30 06:25:25 +0000
+++ src/provisioningserver/pxe/tftppath.py 2012-08-30 12:19:20 +0000
@@ -29,7 +29,7 @@
simulate PXELINUX and don't actually load `pxelinux.0`, but use its path
to figure out where configuration files are located.
"""
- return "maas/pxelinux.0"
+ return "pxelinux.0"
# TODO: move this; it is now only used for testing.
@@ -48,7 +48,7 @@
# Not using os.path.join: this is a TFTP path, not a native path. Yes, in
# practice for us they're the same. We always assume that the ARP HTYPE
# (hardware type) that PXELINUX sends is Ethernet.
- return "maas/pxelinux.cfg/{htype:02x}-{mac}".format(
+ return "pxelinux.cfg/{htype:02x}-{mac}".format(
htype=ARP_HTYPE.ETHERNET, mac=mac)
@@ -66,7 +66,7 @@
:return: Path for the corresponding image directory (containing a
kernel and initrd) as exposed over TFTP.
"""
- return '/'.join(['maas', arch, subarch, release, purpose])
+ return '/'.join([arch, subarch, release, purpose])
def locate_tftp_path(path, tftproot):
=== modified file 'src/provisioningserver/tests/test_config.py'
--- src/provisioningserver/tests/test_config.py 2012-08-24 10:53:26 +0000
+++ src/provisioningserver/tests/test_config.py 2012-08-30 12:19:20 +0000
@@ -147,7 +147,7 @@
'tftp': {
'generator': 'http://localhost/MAAS/api/1.0/pxeconfig/',
'port': 69,
- 'root': "/var/lib/tftpboot",
+ 'root': "/var/lib/maas/tftp",
},
}
=== modified file 'src/provisioningserver/tests/test_maas_import_pxe_files.py'
--- src/provisioningserver/tests/test_maas_import_pxe_files.py 2012-08-17 14:45:13 +0000
+++ src/provisioningserver/tests/test_maas_import_pxe_files.py 2012-08-30 12:19:20 +0000
@@ -23,11 +23,7 @@
)
from provisioningserver.pxe import tftppath
from provisioningserver.testing.config import ConfigFixture
-from testtools.matchers import (
- FileContains,
- FileExists,
- Not,
- )
+from testtools.matchers import FileContains
def read_file(path, name):
@@ -97,7 +93,7 @@
archive = self.make_dir()
download = compose_download_dir(archive, arch, release)
os.makedirs(download)
- for filename in ['initrd.gz', 'linux', 'pxelinux.0']:
+ for filename in ['initrd.gz', 'linux']:
factory.make_file(download, filename)
return archive
@@ -135,40 +131,27 @@
with open(os.devnull, 'wb') as dev_null:
check_call(script, env=env, stdout=dev_null)
- def test_downloads_pre_boot_loader(self):
+ def test_procures_pre_boot_loader(self):
arch = factory.make_name('arch')
release = 'precise'
archive = self.make_downloads(arch=arch, release=release)
self.call_script(archive, self.tftproot, arch=arch, release=release)
tftp_path = compose_tftp_bootloader_path(self.tftproot)
- download_path = compose_download_dir(archive, arch, release)
- expected_contents = read_file(download_path, 'pxelinux.0')
+ expected_contents = read_file('/usr/lib/syslinux', 'pxelinux.0')
self.assertThat(tftp_path, FileContains(expected_contents))
- def test_ignores_missing_pre_boot_loader(self):
- arch = factory.make_name('arch')
- release = 'precise'
- archive = self.make_downloads(arch=arch, release=release)
- download_path = compose_download_dir(archive, arch, release)
- os.remove(os.path.join(download_path, 'pxelinux.0'))
- self.call_script(archive, self.tftproot, arch=arch, release=release)
- tftp_path = compose_tftp_bootloader_path(self.tftproot)
- self.assertThat(tftp_path, Not(FileExists()))
-
def test_updates_pre_boot_loader(self):
arch = factory.make_name('arch')
release = 'precise'
tftp_path = compose_tftp_bootloader_path(self.tftproot)
- os.makedirs(os.path.dirname(tftp_path))
with open(tftp_path, 'w') as existing_file:
existing_file.write(factory.getRandomString())
archive = self.make_downloads(arch=arch, release=release)
self.call_script(archive, self.tftproot, arch=arch, release=release)
- download_path = compose_download_dir(archive, arch, release)
- expected_contents = read_file(download_path, 'pxelinux.0')
+ expected_contents = read_file('/usr/lib/syslinux', 'pxelinux.0')
self.assertThat(tftp_path, FileContains(expected_contents))
- def test_downloads_install_image(self):
+ def test_procures_install_image(self):
arch = factory.make_name('arch')
release = 'precise'
archive = self.make_downloads(arch=arch, release=release)
=== modified file 'src/provisioningserver/tests/test_tftp.py'
--- src/provisioningserver/tests/test_tftp.py 2012-08-27 12:00:44 +0000
+++ src/provisioningserver/tests/test_tftp.py 2012-08-30 12:19:20 +0000
@@ -70,10 +70,7 @@
The path is intended to match `re_config_file`, and the components are
the expected groups from a match.
"""
- components = {
- "bootpath": b"maas", # Static.
- "mac": factory.getRandomMACAddress(b"-"),
- }
+ components = {"mac": factory.getRandomMACAddress(b"-")}
config_path = compose_config_path(components["mac"])
return config_path, components
@@ -115,17 +112,17 @@
mac = 'aa-bb-cc-dd-ee-ff'
match = TFTPBackend.re_config_file.match('pxelinux.cfg/01-%s' % mac)
self.assertIsNotNone(match)
- self.assertEqual({'mac': mac, 'bootpath': None}, match.groupdict())
+ self.assertEqual({'mac': mac}, match.groupdict())
def test_re_config_file_matches_pxelinux_cfg_with_leading_slash(self):
mac = 'aa-bb-cc-dd-ee-ff'
match = TFTPBackend.re_config_file.match('/pxelinux.cfg/01-%s' % mac)
self.assertIsNotNone(match)
- self.assertEqual({'mac': mac, 'bootpath': None}, match.groupdict())
+ self.assertEqual({'mac': mac}, match.groupdict())
def test_re_config_file_does_not_match_non_config_file(self):
self.assertIsNone(
- TFTPBackend.re_config_file.match('maas/pxelinux.cfg/kernel'))
+ TFTPBackend.re_config_file.match('pxelinux.cfg/kernel'))
def test_re_config_file_does_not_match_file_in_root(self):
self.assertIsNone(
@@ -153,18 +150,16 @@
def test_get_generator_url(self):
# get_generator_url() merges the parameters obtained from the request
# file path (arch, subarch, name) into the configured generator URL.
- bootpath = factory.make_name("bootpath")
mac = factory.getRandomMACAddress(b"-")
dummy = factory.make_name("dummy").encode("ascii")
backend_url = b"http://example.com/?" + urlencode({b"dummy": dummy})
backend = TFTPBackend(self.make_dir(), backend_url)
# params is an example of the parameters obtained from a request.
- params = {"bootpath": bootpath, "mac": mac}
+ params = {"mac": mac}
generator_url = urlparse(backend.get_generator_url(params))
self.assertEqual("example.com", generator_url.hostname)
query = parse_qsl(generator_url.query)
query_expected = [
- ("bootpath", bootpath),
("dummy", dummy),
("mac", mac),
]
@@ -200,9 +195,7 @@
reader = yield backend.get_reader(config_path)
output = reader.read(10000)
- # The expected parameters include bootpath; this is extracted from the
- # file path by re_config_file.
- expected_params = dict(mac=mac, bootpath="maas")
+ expected_params = dict(mac=mac)
observed_params = json.loads(output)
self.assertEqual(expected_params, observed_params)
@@ -212,10 +205,7 @@
# `IReader` of a PXE configuration, rendered by `render_pxe_config`.
backend = TFTPBackend(self.make_dir(), b"http://example.com/")
# Fake configuration parameters, as discovered from the file path.
- fake_params = {
- "bootpath": "maas",
- "mac": factory.getRandomMACAddress(b"-"),
- }
+ fake_params = {"mac": factory.getRandomMACAddress(b"-")}
# Fake kernel configuration parameters, as returned from the API call.
fake_kernel_params = make_kernel_parameters()
=== modified file 'src/provisioningserver/tftp.py'
--- src/provisioningserver/tftp.py 2012-08-24 18:34:57 +0000
+++ src/provisioningserver/tftp.py 2012-08-30 12:19:20 +0000
@@ -86,14 +86,7 @@
re_config_file = re.compile(
r'''
# Optional leading slash(es).
- ^/?
- # Optional boot path prefix (separated from the rest by slash):
- (?:
- (?P<bootpath>
- maas
- )
- /
- )?
+ ^/*
pxelinux[.]cfg # PXELINUX expects this.
/
{htype:02x} # ARP HTYPE.