[arch-projects] [archweb] [RFC] Add releng netboot to archweb
This is a WIP patch series to add the netboot environment to archweb. I send it primarily to receive comments on the code and suggestions for the missing pieces: - Right now, the binary files needed by pxelinux are not served, but are redirects to the old releng site. Only the essential files are there, so not everything in the menu will work. - The files on the information page are not served yet, nor do they exist. - I have no idea if django properly caches this page, or if this requires extra configuration, as regenerating it every time seems like overkill. - All files that iPXE needs to access must be served without SSL as far as I know. To test it, set your archweb test environment to run on http://localhost:8000/ Download ipxe.lkrn from https://paste.xinu.at/OX7oU8/ and execute qemu-system-x86_64 -enable-kvm -kernel bin/ipxe.lkrn or qemu-system-x86_64 -enable-kvm -kernel bin/ipxe.lkrn -cpu kvm32
--- releng/urls.py | 5 ++ releng/views.py | 4 ++ templates/releng/netboot.html | 125 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 templates/releng/netboot.html diff --git a/releng/urls.py b/releng/urls.py index 76c3634..be94404 100644 --- a/releng/urls.py +++ b/releng/urls.py @@ -20,9 +20,14 @@ 'release_torrent', {}, 'releng-release-torrent'), ) +netboot_patterns = patterns('releng.views', + (r'^$', 'netboot_info', {}, 'releng-netboot-info'), +) + urlpatterns = patterns('', (r'^feedback/', include(feedback_patterns)), (r'^releases/', include(releases_patterns)), + (r'^netboot/', include(netboot_patterns)), ) # vim: set ts=4 sw=4 et: diff --git a/releng/views.py b/releng/views.py index b1c76a4..e3a58bb 100644 --- a/releng/views.py +++ b/releng/views.py @@ -238,4 +238,8 @@ def release_torrent(request, version): response['Content-Disposition'] = 'attachment; filename=%s' % filename return response + +def netboot_info(request): + return render(request, "releng/netboot.html", None) + # vim: set ts=4 sw=4 et: diff --git a/templates/releng/netboot.html b/templates/releng/netboot.html new file mode 100644 index 0000000..3242e6f --- /dev/null +++ b/templates/releng/netboot.html @@ -0,0 +1,125 @@ +{% extends "base.html" %} + +{% block title %}Arch Linux - Netboot Live System{% endblock %} + +{% block content %} +<div id="arch-downloads" class="box"> + +<h2>Arch Linux Netboot Live System</h2> + +<p>The Arch Linux netboot environment allows booting Arch Linux live + media directly over the network. It will boot into a menu where you + can choose from a list of available mirrors. The image will be + downloaded into memory. +</p> + +<p><strong>Requirements:</strong> A computer that connects to the internet via LAN and DHCP.</p> + +<p>If your ethernet NIC is not supported by iPXE, you must use your NIC's netboot capabilities. + This is only possible if you select "Boot from network" in the BIOS and + configure your DHCP server to <a href="#undi_pxeimage">load the PXE image provided below</a>. + In this case, the UNDI driver will be used for downloads until Linux is booted. The first + stage of the download can be <strong>extremely</strong> + slow. +</p> + +<h3>Test netboot with qemu</h3> + +<p>Download an iPXE kernel image.</p> +<ul> + <li><a href="ipxe.lkrn">ipxe.lkrn</a> Graphical Menu</li> + <li><a href="ipxe_text.lkrn">ipxe_text.lkrn</a> Text Menu</li> +</ul> +<p>Run qemu with the kernel image:</p> +<pre>qemu -m 1G -kernel ipxe.lkrn</pre> + +<h3><a name="kernelimage">Boot with any Linux bootloader</a></h3> + +<p>Download an iPXE kernel image to <i>/boot</i>.</p> +<ul> + <li><a href="ipxe.lkrn">ipxe.lkrn</a> Graphical Menu</li> + <li><a href="ipxe_text.lkrn">ipxe_text.lkrn</a> Text Menu</li> +</ul> +<p>Add the image to your bootloader configuration:</p> + +<p>GRUB 2:</p> +<pre>menuentry 'Arch Linux Netboot Environment' { + set root='(hd0,1)' + linux16 /ipxe.lkrn +}</pre> + +<p>Syslinux:</p> +<pre>LABEL archnetboot +MENU LABEL Arch Linux Netboot Environment +KERNEL /ipxe.lkrn</pre> + +<p>GRUB Legacy:</p> +<pre>title Arch Linux Netboot Environment +kernel (hd0,0)/ipxe.lkrn</pre> + +<h3>Boot from USB</h3> + +<!-- +<p><strong>This method will overwrite the USB drive. To avoid that, it is recommended that +you install a bootloader and use the <i>.lkrn</i> file as describe above.</strong></p> + +<p>Download an iPXE USB image.</p> +<ul> + <li><a href="ipxe.usb">ipxe.usb</a> Graphical Menu</li> + <li><a href="ipxe_text.usb">ipxe_text.usb</a> Text Menu</li> +</ul> +<p>Write the image to a USB drive:</p> +<pre>dd if=ipxe.usb of=/dev/sdx</pre> +//--> + +<p>Install a bootloader (e.g. GRUB or syslinux) onto the USB drive and use the <i>.lkrn</i> file + <a href="#kernelimage">as described above</a>.</p> + +<h3>Boot from Floppy</h3> + +<p>Download an iPXE floppy image.</p> +<ul> + <li><a href="ipxe.dsk">ipxe.dsk</a> Graphical Menu</li> + <li><a href="ipxe_text.dsk">ipxe_text.dsk</a> Text Menu</li> +</ul> +<p>Write the image to your floppy:</p> +<pre>dd if=ipxe.dsk of=/dev/fd0</pre> + +<h3>Boot from CD</h3> + +<p>Download an iPXE ISO image and write it to a CD.</p> +<ul> + <li><a href="ipxe.iso">ipxe.iso</a> Graphical Menu</li> + <li><a href="ipxe_text.iso">ipxe_text.iso</a> Text Menu</li> +</ul> + +<h3>Boot from the network</h3> + +There are two ways to do this: + +<h4><a name="undi_pxeimage">Using an iPXE image</a></h4> + +<p>Download an iPXE PXE image into your TFTP root.</p> +<ul> + <li><a href="ipxe.pxe">ipxe.pxe</a> Graphical Menu</li> + <li><a href="ipxe_text.pxe">ipxe_text.pxe</a> Text Menu</li> +</ul> + +<p>Set the PXE filename to <i>ipxe.pxe</i> (using the <i>filname</i> option in dhcpd or the <i>-M</i> option in dnsmasq).</p> + +<p>This method is recommended, as it will always work - if iPXE lacks a native NIC driver, the UNDI driver will be used.</p> + +<h4>Flashing your boot ROM</h4> + +<p>You can build a custom iPXE images and flash it to your boot ROM. +You must include one of the following iPXE scripts:</p> + +<ul> + <li><a href="arch.ipxe">arch.ipxe</a> Graphical Menu</li> + <li><a href="arch_text.ipxe">arch_text.ipxe</a> Text Menu</li> +</ul> + +<p><strong>If you do this, your computer will always boot the Arch netboot environment when you netboot your computer.</strong></p> + +</div> +{% endblock %} -- 1.8.3
--- releng/templatetags/__init__.py | 0 releng/templatetags/host_from_url.py | 13 ++++ releng/urls.py | 11 ++- releng/views.py | 29 +++++++- templates/releng/pxelinux.cfg.txt | 118 +++++++++++++++++++++++++++++++ templates/releng/pxelinux_choose.cfg.txt | 13 ++++ 6 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 releng/templatetags/__init__.py create mode 100644 releng/templatetags/host_from_url.py create mode 100644 templates/releng/pxelinux.cfg.txt create mode 100644 templates/releng/pxelinux_choose.cfg.txt diff --git a/releng/templatetags/__init__.py b/releng/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/releng/templatetags/host_from_url.py b/releng/templatetags/host_from_url.py new file mode 100644 index 0000000..3ad0fc2 --- /dev/null +++ b/releng/templatetags/host_from_url.py @@ -0,0 +1,13 @@ +from datetime import timedelta +from django import template +from django.template.defaultfilters import floatformat +import string + +register = template.Library() + +register = template.Library() +@register.filter(name='host_from_url') +def host_from_url(val): + return string.split(val, "/", 3)[2] + +# vim: set ts=4 sw=4 et: diff --git a/releng/urls.py b/releng/urls.py index be94404..3ed4a42 100644 --- a/releng/urls.py +++ b/releng/urls.py @@ -1,6 +1,7 @@ -from django.conf.urls import include, patterns +from django.conf.urls import include, patterns, url from .views import ReleaseListView, ReleaseDetailView +from django.views.generic import RedirectView feedback_patterns = patterns('releng.views', (r'^$', 'test_results_overview', {}, 'releng-test-overview'), @@ -22,8 +23,16 @@ netboot_patterns = patterns('releng.views', (r'^$', 'netboot_info', {}, 'releng-netboot-info'), + (r'^pxelinux_vesa.cfg', 'netboot_config_is64', { 'style': 'vesa' }), + (r'^pxelinux_text.cfg', 'netboot_config_is64', { 'style': 'text' }), + (r'^pxelinux_vesa_64.cfg', 'netboot_config', { 'style': 'vesa', 'arch': 64 }), + (r'^pxelinux_vesa_32.cfg', 'netboot_config', { 'style': 'vesa', 'arch': 32 }), + (r'^pxelinux_text_64.cfg', 'netboot_config', { 'style': 'text', 'arch': 64 }), + (r'^pxelinux_text_32.cfg', 'netboot_config', { 'style': 'text', 'arch': 32 }), ) +netboot_patterns += [url(r'^' + rfile + '$', RedirectView.as_view(url='http://releng.archlinux.org/pxeboot/boot/' + rfile)) for rfile in ('pxelinux.0', 'ifcpu64.c32', 'menu.c32', 'splash.png', 'vesamenu.c32')] + urlpatterns = patterns('', (r'^feedback/', include(feedback_patterns)), (r'^releases/', include(releases_patterns)), diff --git a/releng/views.py b/releng/views.py index e3a58bb..4f9fbee 100644 --- a/releng/views.py +++ b/releng/views.py @@ -10,7 +10,7 @@ from .models import (Architecture, BootType, Bootloader, ClockChoice, Filesystem, HardwareType, InstallType, Iso, IsoType, Module, Source, Test, Release) - +from mirrors.models import (Mirror, MirrorUrl, MirrorProtocol) def standard_field(model, empty_label=None, help_text=None, required=True): return forms.ModelChoiceField(queryset=model.objects.all(), @@ -242,4 +242,31 @@ def release_torrent(request, version): def netboot_info(request): return render(request, "releng/netboot.html", None) +def netboot_config_is64(request, style): + context = { + 'style': style + } + return render(request, "releng/pxelinux_choose.cfg.txt", context, content_type='text/plain') + +def netboot_config(request, style, arch): + releases = Release.objects.all().order_by("-release_date") + releases = [ release.version for release in releases if release.available ] + if arch == 64: + archs = ['x86_64', 'i686'] + else: + archs = ['i686'] + mirrorurls = MirrorUrl.objects.all() + mirrorurls = sorted([ mirrorurl for mirrorurl in mirrorurls if ( mirrorurl.active and mirrorurl.protocol.protocol == 'http' + and mirrorurl.mirror.public + and mirrorurl.mirror.active + and mirrorurl.mirror.isos ) ], key=lambda x: x.country.name) + context = { + 'style': style, + 'arch': arch, + 'archs': archs, + 'releases': releases, + 'mirrorurls': mirrorurls, + } + return render(request, "releng/pxelinux.cfg.txt", context, content_type='text/plain') + # vim: set ts=4 sw=4 et: diff --git a/templates/releng/pxelinux.cfg.txt b/templates/releng/pxelinux.cfg.txt new file mode 100644 index 0000000..f88bf19 --- /dev/null +++ b/templates/releng/pxelinux.cfg.txt @@ -0,0 +1,118 @@ +SERIAL 0 38400 +{% if style == 'vesa' %} +UI vesamenu.c32 +MENU BACKGROUND splash.png + +MENU WIDTH 78 +MENU MARGIN 4 +MENU ROWS 11 +MENU VSHIFT 10 +MENU TIMEOUTROW 17 +MENU TABMSGROW 15 +MENU CMDLINEROW 17 +MENU HELPMSGROW 17 +MENU HELPMSGENDROW -1 + +# Refer to http://syslinux.zytor.com/wiki/index.php/Doc/menu +MENU COLOR border 30;44 #40ffffff #a0000000 std +MENU COLOR title 1;36;44 #9033ccff #a0000000 std +MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all +MENU COLOR unsel 37;44 #50ffffff #a0000000 std +MENU COLOR help 37;40 #c0ffffff #a0000000 std +MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std +MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std +MENU COLOR msg07 37;40 #90ffffff #a0000000 std +MENU COLOR tabmsg 31;40 #30ffffff #00000000 std +{% elif style == 'text' %} +UI menu.c32 + +MENU WIDTH 80 +MENU MARGIN 2 +MENU ROWS 14 +MENU VSHIFT 1 +MENU TIMEOUTROW 21 +MENU TABMSGROW 19 +MENU CMDLINEROW 21 +MENU HELPMSGROW 21 +MENU HELPMSGENDROW -1 +{% endif %} +PROMPT 0 +MENU TITLE Arch Linux +{% load host_from_url %}{% for a in archs %} +MENU BEGIN release_{{ a }} + MENU TITLE Official Releases ({{ a }}) + + LABEL - + MENU LABEL back + MENU EXIT + + MENU SEPARATOR +{% for release in releases %} + MENU BEGIN release_{{ release }}_{{ a }} + MENU TITLE {{ release }} ({{ a }}) + + LABEL - + MENU LABEL back + MENU EXIT + + MENU SEPARATOR +{% regroup mirrorurls by country as mirrors_by_country %}{% for mirrorgroup in mirrors_by_country %} + MENU BEGIN release_{{ release }}_{{ a }}_{{ mirrorgroup.grouper }} + MENU TITLE {{ release }} ({{ a }}), {{ mirrorgroup.grouper.name }} + + LABEL - + MENU LABEL back + MENU EXIT + + MENU SEPARATOR +{% for mirror in mirrorgroup.list %} + LABEL release_{{ release }}_{{ a }}_{{ mirrorgroup.grouper }}_{{ mirror.url|host_from_url }} + TEXT HELP + Boot Arch Linux ({{ a }}) live medium. + Release {{ release }}, mirror {{ mirror.url|host_from_url }}. + ENDTEXT + MENU LABEL {{ mirror.url|host_from_url }} + LINUX {{ mirror.url }}iso/{{ release }}/arch/boot/{{ a }}/vmlinuz + INITRD {{ mirror.url }}iso/{{ release }}/arch/boot/{{ a }}/archiso.img + APPEND archiso_http_srv={{ mirror.url }}iso/{{ release }}/ archisobasedir=arch checksum=y ip=dhcp +{% endfor %} + MENU END +{% endfor %} + MENU END +{% endfor %} +MENU END +{% endfor %} +MENU BEGIN hardware +MENU TITLE Hardware Information + +LABEL - +MENU LABEL back +MENU EXIT + +MENU SEPARATOR + +# http://www.memtest.org/ +LABEL memtest +MENU LABEL Run Memtest86+ (RAM test) +LINUX memtest + +# http://hdt-project.org/ +LABEL hdt +MENU LABEL Hardware Information (HDT) +COM32 hdt.c32 +APPEND modules_alias=hdt/modalias.gz pciids=hdt/pciids.gz + +MENU END + +LABEL reboot +MENU LABEL Reboot +COM32 reboot.c32 +{% if style == 'vesa' %} +LABEL totext +MENU LABEL Switch to text mode +CONFIG pxelinux_text_{{ arch }}.cfg +{% elif style == 'text' %} +LABEL tograph +MENU LABEL Switch to graphical mode +CONFIG pxelinux_vesa_{{ arch }}.cfg +{% endif %} diff --git a/templates/releng/pxelinux_choose.cfg.txt b/templates/releng/pxelinux_choose.cfg.txt new file mode 100644 index 0000000..e1c7922 --- /dev/null +++ b/templates/releng/pxelinux_choose.cfg.txt @@ -0,0 +1,13 @@ +SERIAL 0 38400 +DEFAULT choose +PROMPT 0 + +LABEL choose +KERNEL ifcpu64.c32 +APPEND have64 -- nohave64 + +LABEL have64 +CONFIG pxelinux_{{ style }}_64.cfg + +LABEL nohave64 +CONFIG pxelinux_{{ style }}_32.cfg -- 1.8.3
participants (1)
-
Thomas Bächler