]> git.ipfire.org Git - ipfire.org.git/blame - src/web/boot.py
people: Add congratulations page for activating the new account
[ipfire.org.git] / src / web / boot.py
CommitLineData
5470bdf1
MT
1#!/usr/bin/python
2
3import logging
4import os
93feb275 5import re
5470bdf1
MT
6import tornado.httpserver
7import tornado.ioloop
8import tornado.locale
9import tornado.options
10import tornado.web
93feb275 11import unicodedata
5470bdf1 12
124a8404 13from . import base
93feb275 14from . import ui_modules
9068dba1 15
5470bdf1
MT
16BASEDIR = os.path.dirname(__file__)
17
0d71ac64
MT
18LATEST_VERSION = "2.0"
19
a9bf3cbe 20def word_wrap(s, width=45):
7261a759
MT
21 paragraphs = s.split('\n')
22 lines = []
23 for paragraph in paragraphs:
24 while len(paragraph) > width:
25 pos = paragraph.rfind(' ', 0, width)
26 if not pos:
27 pos = width
28 lines.append(paragraph[:pos])
29 paragraph = paragraph[pos:]
a9bf3cbe 30 lines.append(paragraph.lstrip())
7261a759 31 return '\n'.join(lines)
5470bdf1 32
124a8404 33class BootBaseHandler(base.BaseHandler):
37b5c0cf
MT
34 @property
35 def arch(self):
36 arch = self.get_argument("arch", "i386")
37 if not arch in ("x86_64", "i586", "i386"):
38 raise tornado.web.HTTPError(400, "Invalid architecture")
39
40 if arch == "i386":
41 arch = "i586"
42
43 return arch
44
45 @property
46 def platform(self):
47 platform = self.get_argument("platform", "pcbios")
48 if not platform in ("pcbios", "efi"):
49 raise tornado.web.HTTPError(400, "Invalid platform")
50
51 return platform
5470bdf1
MT
52
53
8e2e1261 54class MenuGPXEHandler(BootBaseHandler):
5470bdf1
MT
55 """
56 menu.gpxe
57 """
58 def get(self):
a69e87a1
MT
59 version = self.get_argument("version", None)
60 if not version or version < LATEST_VERSION:
61 return self.serve_update()
98133910
MT
62
63 # Deliver content
5470bdf1
MT
64 self.set_header("Content-Type", "text/plain")
65 self.write("#!gpxe\n")
e847f85c 66
37b5c0cf
MT
67 self.write("set 209:string premenu.cfg?arch=%s&platform=%s\n" \
68 % (self.arch, self.platform))
453c817c 69 self.write("set 210:string http://boot.ipfire.org/\n")
e847f85c
MT
70 self.write("chain pxelinux.0\n")
71
72 def serve_update(self):
73 self.set_header("Content-Type", "text/plain")
74 self.write("#!gpxe\n")
75
76 # Small warning
77 self.write("echo\necho Your copy of gPXE/iPXE is too old. ")
78 self.write("Upgrade to avoid seeing this every boot!\n")
79
e48a74ea 80 self.write("chain static/netboot/ipxe.kpxe\n")
5470bdf1 81
98133910 82
37b5c0cf
MT
83class PremenuCfgHandler(BootBaseHandler):
84 def get(self):
85 self.set_header("Content-Type", "text/plain")
86
87 self.render("netboot/premenu.cfg", arch=self.arch, platform=self.platform)
88
5470bdf1 89
8e2e1261 90class MenuCfgHandler(BootBaseHandler):
53211b33
MT
91 class NightlyBuildReleaseDummy(object):
92 id = 100
93 name = "Nightly Build"
94 sname = "nightly-build"
95
37b5c0cf
MT
96 def supports_arch(self, arch):
97 return arch in ("i586", "x86_64")
98
99 def supports_platform(self, platform):
100 return platform == "pcbios"
101
102 def netboot_kernel_url(self, arch, platform):
4383298a 103 return "http://boot.ipfire.org/nightly/next/latest/%s/images/vmlinuz" % arch
37b5c0cf
MT
104
105 def netboot_initrd_url(self, arch, platform):
4383298a 106 return "http://boot.ipfire.org/nightly/next/latest/%s/images/instroot" % arch
37b5c0cf
MT
107
108 def netboot_args(self, arch, platform):
66b066ae 109 return "installer.download-url=https://nightly.ipfire.org/next/latest/%s/images/installer.iso" % arch
53211b33
MT
110
111 def is_netboot_capable(self):
112 return True
113
114 nightly_build = NightlyBuildReleaseDummy()
115
5470bdf1
MT
116 def get(self):
117 self.set_header("Content-Type", "text/plain")
118
9068dba1 119 latest_release = self.releases.get_latest()
37b5c0cf
MT
120 if latest_release and not latest_release.supports_arch(self.arch):
121 latest_release = None
122
123 stable_releases = [r for r in self.releases.get_stable()
124 if r.supports_arch(self.arch) and r.supports_platform(self.platform)]
9068dba1
MT
125 try:
126 stable_releases.remove(latest_release)
127 except ValueError:
128 pass
129
37b5c0cf
MT
130 development_releases = [r for r in self.releases.get_unstable()
131 if r.supports_arch(self.arch) and r.supports_platform(self.platform)]
53211b33 132 development_releases.insert(0, self.nightly_build)
5470bdf1 133
9068dba1 134 self.render("netboot/menu.cfg", latest_release=latest_release,
37b5c0cf
MT
135 stable_releases=stable_releases, development_releases=development_releases,
136 arch=self.arch, platform=self.platform)
93feb275
MT
137
138
139class MenuConfigModule(ui_modules.UIModule):
140 def render(self, release, arch=None, platform=None):
141 return self.render_string("netboot/menu-config.cfg", release=release,
142 arch=arch, platform=platform)
143
144
145class MenuHeaderModule(ui_modules.UIModule):
146 def render(self, title, releases, arch=None, platform=None):
147 # Remove any non-ASCII characters
148 try:
149 slug = unicodedata.normalize("NFKD", title)
150 except TypeError:
151 pass
152
153 # Remove excessive whitespace
154 slug = re.sub(r"[^\w]+", " ", slug)
155
156 slug = "-".join(slug.split()).lower()
157
158 return self.render_string("netboot/menu-header.cfg", slug=slug,
159 title=title, releases=releases, arch=arch, platform=platform)
160
161
162class MenuSeparatorModule(ui_modules.UIModule):
163 def render(self):
164 return self.render_string("netboot/menu-separator.cfg")