--- Now that the March and May ISOs have the required initramfs signatures (April version is broken, sadly), I think it is time to deploy the new netboot environment to the main archweb site. This patch does not add a website and compatible IPXE images yet, but only supplies the correct ipxe configuration. Once this patch is live, I will provide test images and start working on instructions for the website. Highlights of this new feature: * Uses release and mirror data from archweb * Comfortable configuration of version, architecture, mirror and boot options via ipxe menu. * Complete signature verification: With the proper ipxe image, the signature of the kernel and initramfs files is verified. Then the kernel is booted and archiso verifies the signature of the squashfs image. releng/urls.py | 5 ++ releng/views.py | 21 +++++- templates/releng/archlinux.ipxe | 157 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 templates/releng/archlinux.ipxe diff --git a/releng/urls.py b/releng/urls.py index ca76eb2..0e87de4 100644 --- a/releng/urls.py +++ b/releng/urls.py @@ -22,9 +22,14 @@ 'release_torrent', {}, 'releng-release-torrent'), ) +netboot_patterns = patterns('releng.views', + (r'^archlinux\.ipxe$', 'netboot_config', {}, 'releng-netboot-config') +) + 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 dbb65c2..7db469c 100644 --- a/releng/views.py +++ b/releng/views.py @@ -13,7 +13,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(), @@ -280,4 +280,23 @@ def releases_json(request): response = HttpResponse(to_json, content_type='application/json') return response +def netboot_config(request): + release_qs = Release.objects.filter(available=True).order_by('-release_date') + releases = [ release.version for release in release_qs ] + mirrorurls = MirrorUrl.objects.filter(protocol__protocol='http', + active=True, + mirror__public=True, + mirror__active=True, + mirror__isos=True) + mirrorurls = sorted( mirrorurls, + key=lambda x: x.mirror.name) + mirrorurls = sorted( mirrorurls, + key=lambda x: x.country.name) + context = { + 'archs': [ 'i686', 'x86_64' ], + 'releases': releases, + 'mirrorurls': mirrorurls, + } + return render(request, "releng/archlinux.ipxe", context, content_type='text/plain') + # vim: set ts=4 sw=4 et: diff --git a/templates/releng/archlinux.ipxe b/templates/releng/archlinux.ipxe new file mode 100644 index 0000000..87f9c83 --- /dev/null +++ b/templates/releng/archlinux.ipxe @@ -0,0 +1,157 @@ +#!ipxe +{% regroup mirrorurls by country as mirrors_by_country %} + +# Figure out if client is 64-bit capable +cpuid --ext 29 && set cpuarch x86_64 || set cpuarch i686 + +# allow only trusted images +imgtrust + +# initial options +set bootarch ${cpuarch} +set release {{ releases.0 }} +set mirrorurl +set extrabootoptions ip=dhcp +set countrycode + +:main +menu Arch Linux Netboot +item --gap Settings +item set_architecture Architecture: ${bootarch} +item set_release Release: ${release} +isset ${mirrorurl} && item set_mirror Mirror: ${mirrorurl} || item set_mirror Choose a mirror +item set_options Boot options: ${extrabootoptions} +item +isset ${mirrorurl} && item boot Boot Arch Linux || item --gap Boot Arch Linux +item shell Drop to iPXE shell +item reboot Reboot +item exit Exit iPXE +isset ${mirrorurl} && choose --default set_options selected || choose --default set_mirror selected || goto shell +goto ${selected} || goto main + +:shell +echo Type 'exit' to get the back to the menu +shell +goto main + +:reboot +reboot + +:exit +exit + +:set_architecture +menu Arch Linux Netboot: Select Architecture +item back back +item +item --gap Available architectures: +iseq ${cpuarch} x86_64 && item x86_64 x64_64 || +item i686 i686 +choose selected || goto main +iseq ${selected} back && goto main || +set bootarch ${selected} +goto main + +:set_release +menu Arch Linux Netboot: Select Release +item back back +item +item --gap Available releases: +{% for release in releases %}item {{ release }} {{ release }} +{% endfor %} +choose selected || goto main +iseq ${selected} back && goto main || +set release ${selected} +goto main + +:set_mirror +goto select_mirror_country + +:select_mirror_country +menu Arch Linux Netboot: Select Mirror +item back back +item +item --gap Custom Configuration: +item custom Enter mirror URL +item +item --gap Select Mirror By Country: +{% for mirrorgroup in mirrors_by_country %} +{% if mirrorgroup.grouper == '' %} +item 00 Global +{% else %} +item {{ mirrorgroup.grouper }} {{ mirrorgroup.grouper.name }} +{% endif %} +{% endfor %} +isset ${countrycode} && choose --default ${countrycode} selected || choose selected || goto main +iseq ${selected} back && goto main || +iseq ${selected} custom && goto enter_mirror_url || +set countrycode ${selected} +goto select_mirror_url + +:enter_mirror_url +set countrycode +echo Enter the mirror URL including the trailing slash. +echo Example: http://some.host/archlinux/ +echo +echo -n Mirror URL: ${} && read mirrorurl || goto select_mirror_country +goto main + +:select_mirror_url +goto select_mirror_url_${countrycode} || goto select_mirror_country + +{% for mirrorgroup in mirrors_by_country %} +{% if mirrorgroup.grouper == '' %} +:select_mirror_url_00 +set countryname Global +{% else %} +:select_mirror_url_{{ mirrorgroup.grouper }} +set countryname {{ mirrorgroup.grouper.name }} +{% endif %} +menu Arch Linux Netboot: Select Mirror +item back back +item +item --gap Available mirrors in ${countryname} +{% for mirror in mirrorgroup.list %}item {{ mirror.url }} {{ mirror.mirror.name }} +{% endfor %} +choose selected || goto select_mirror_country +iseq ${selected} back && goto select_mirror_country || +set mirrorurl ${selected} +goto main +{% endfor %} + +:set_options +echo -n Boot options: ${} && read extrabootoptions || +goto main + +:boot +echo Booting Arch Linux ${bootarch} ${release} from ${mirrorurl} +echo +kernel ${mirrorurl}iso/${release}/arch/boot/${bootarch}/vmlinuz || goto failed_download +imgverify vmlinuz ${mirrorurl}iso/${release}/arch/boot/${bootarch}/vmlinuz.ipxe.sig || goto failed_verify +initrd ${mirrorurl}iso/${release}/arch/boot/intel_ucode.img || goto failed_download +imgverify intel_ucode.img ${mirrorurl}iso/${release}/arch/boot/intel_ucode.img.ipxe.sig || goto failed_verify +initrd ${mirrorurl}iso/${release}/arch/boot/${bootarch}/archiso.img || goto failed_download +imgverify archiso.img ${mirrorurl}iso/${release}/arch/boot/${bootarch}/archiso.img.ipxe.sig || goto failed_verify +imgargs vmlinuz initrd=intel_ucode.img initrd=archiso.img archiso_http_srv=${mirrorurl}iso/${release}/ archisobasedir=arch verify=y ${extrabootoptions} +boot || goto failed_boot + +:failed_download +echo +echo Failed to download a file. +goto failed + +:failed_verify +echo +echo Failed to verify a file. +goto failed + +:failed_boot +echo +echo Boot failed. +goto failed + +:failed +echo Press a key to return to the menu. +prompt +imgfree +goto main -- 2.8.0