X-Git-Url: http://git.ipfire.org/?p=people%2Fshoehn%2Fipfire.org.git;a=blobdiff_plain;f=webapp%2Fhandlers_boot.py;h=bccf5865f3403f494eb6d5620aae13e729b391b7;hp=22acce5a5ad90f06ca354b8d9bff474dfbf713ec;hb=37b5c0cfad98b9520eca5d21d9bcb5eac039204f;hpb=d577e64511c6fe2564a0c058d6c05b40d6cfe2ee diff --git a/webapp/handlers_boot.py b/webapp/handlers_boot.py index 22acce5..bccf586 100644 --- a/webapp/handlers_boot.py +++ b/webapp/handlers_boot.py @@ -10,6 +10,8 @@ import tornado.web import backend +from handlers_base import BaseHandler + BASEDIR = os.path.dirname(__file__) def word_wrap(s, width=45): @@ -25,10 +27,25 @@ def word_wrap(s, width=45): lines.append(paragraph.lstrip()) return '\n'.join(lines) -class BootBaseHandler(tornado.web.RequestHandler): +class BootBaseHandler(BaseHandler): + @property + def arch(self): + arch = self.get_argument("arch", "i386") + if not arch in ("x86_64", "i586", "i386"): + raise tornado.web.HTTPError(400, "Invalid architecture") + + if arch == "i386": + arch = "i586" + + return arch + @property - def netboot(self): - return backend.NetBoot() + def platform(self): + platform = self.get_argument("platform", "pcbios") + if not platform in ("pcbios", "efi"): + raise tornado.web.HTTPError(400, "Invalid platform") + + return platform class MenuGPXEHandler(BootBaseHandler): @@ -36,82 +53,94 @@ class MenuGPXEHandler(BootBaseHandler): menu.gpxe """ def get(self): - # XXX Check if version of the bootloader is allright + # Check if version of the bootloader is recent enough. + # Otherwise send the latest version of the PXE loader. + user_agent = self.request.headers.get("User-Agent", None) + if user_agent: + try: + client, version = user_agent.split("/") + except: + pass + else: + # We replaced gPXE by iPXE. + if client == "gPXE": + return self.serve_update() + + # Everything under version 1.0.0 should be + # updated. + if version < "1.0.0": + return self.serve_update() # Devliver content self.set_header("Content-Type", "text/plain") self.write("#!gpxe\n") - self.write("chain menu.c32 premenu.cfg\n") - - -class MenuCfgHandler(BootBaseHandler): - def _menu_string(self, menu, level=0): - s = "" - for entry in menu: - s += self._menu_entry(entry, level=level) + self.write("set 209:string premenu.cfg?arch=%s&platform=%s\n" \ + % (self.arch, self.platform)) + self.write("set 210:string http://boot.dev.ipfire.org/\n") + self.write("chain pxelinux.0\n") - return s + def serve_update(self): + self.set_header("Content-Type", "text/plain") + self.write("#!gpxe\n") - def _menu_entry(self, entry, level=0): - lines = [] + # Small warning + self.write("echo\necho Your copy of gPXE/iPXE is too old. ") + self.write("Upgrade to avoid seeing this every boot!\n") - ident = "\t" * level + self.write("chain http://mirror0.ipfire.org/releases/ipfire-boot/latest/ipxe.kpxe\n") - if entry.type == "seperator": - lines.append(ident + "menu separator") +class PremenuCfgHandler(BootBaseHandler): + def get(self): + self.set_header("Content-Type", "text/plain") - elif entry.type == "header": - lines.append(ident + "menu begin %d" % entry.id) - lines.append(ident + "\tmenu title %s" % entry.title) + self.render("netboot/premenu.cfg", arch=self.arch, platform=self.platform) - # Add "Back..." entry - lines.append(ident + "\tlabel %d.back" % entry.id) - lines.append(ident + "\t\tmenu label Back...") - lines.append(ident + "\t\tmenu exit") - lines.append(ident + "\tmenu separator") - lines.append("%s" % self._menu_string(entry.submenu, level=level+1)) - lines.append(ident + "menu end") +class MenuCfgHandler(BootBaseHandler): + class NightlyBuildReleaseDummy(object): + id = 100 + name = "Nightly Build" + sname = "nightly-build" - elif entry.type == "config": - lines.append(ident + "label %d" % entry.id) - lines.append(ident + "\tmenu label %s" % entry.title) - if entry.description: - lines.append(ident + "\ttext help") - lines.append(word_wrap(entry.description)) - lines.append(ident + "\tendtext") - lines.append(ident + "\tkernel /config/%s/boot.gpxe" % entry.item) + def supports_arch(self, arch): + return arch in ("i586", "x86_64") - return "\n".join(lines + [""]) + def supports_platform(self, platform): + return platform == "pcbios" - def get(self): - self.set_header("Content-Type", "text/plain") + def netboot_kernel_url(self, arch, platform): + return "http://nightly.ipfire.org/next/latest/%s/images/vmlinuz" % arch - menu = self._menu_string(self.netboot.get_menu(1)) + def netboot_initrd_url(self, arch, platform): + return "http://nightly.ipfire.org/next/latest/%s/images/instroot" % arch - self.render("menu.cfg", menu=menu) + def netboot_args(self, arch, platform): + return "installer.download-url=http://nightly.ipfire.org/next/latest/%s/images/installer.iso" % arch + def is_netboot_capable(self): + return True -class BootGPXEHandler(BootBaseHandler): - def get(self, id): - config = self.netboot.get_config(id) - if not config: - raise tornado.web.HTTPError(404, "Configuration with ID '%s' was not found" % id) + nightly_build = NightlyBuildReleaseDummy() - lines = ["#!gpxe", "imgfree",] + def get(self): + self.set_header("Content-Type", "text/plain") - line = "kernel -n img %s" % config.image1 - if line.endswith(".iso"): - line += " iso" - if config.args: - line += " %s" % config.args - lines.append(line) + latest_release = self.releases.get_latest() + if latest_release and not latest_release.supports_arch(self.arch): + latest_release = None - if config.image2: - lines.append("initrd -n img %s" % config.image2) + stable_releases = [r for r in self.releases.get_stable() + if r.supports_arch(self.arch) and r.supports_platform(self.platform)] + try: + stable_releases.remove(latest_release) + except ValueError: + pass - lines.append("boot img") + development_releases = [r for r in self.releases.get_unstable() + if r.supports_arch(self.arch) and r.supports_platform(self.platform)] + development_releases.insert(0, self.nightly_build) - for line in lines: - self.write("%s\n" % line) + self.render("netboot/menu.cfg", latest_release=latest_release, + stable_releases=stable_releases, development_releases=development_releases, + arch=self.arch, platform=self.platform)