]>
Commit | Line | Data |
---|---|---|
5470bdf1 MT |
1 | #!/usr/bin/python |
2 | ||
3 | import logging | |
4 | import os | |
5 | import tornado.httpserver | |
6 | import tornado.ioloop | |
7 | import tornado.locale | |
8 | import tornado.options | |
9 | import tornado.web | |
10 | ||
8b9b631e | 11 | import backend |
5470bdf1 | 12 | |
9068dba1 MT |
13 | from handlers_base import BaseHandler |
14 | ||
5470bdf1 MT |
15 | BASEDIR = os.path.dirname(__file__) |
16 | ||
0d71ac64 MT |
17 | LATEST_VERSION = "2.0" |
18 | ||
a9bf3cbe | 19 | def word_wrap(s, width=45): |
7261a759 MT |
20 | paragraphs = s.split('\n') |
21 | lines = [] | |
22 | for paragraph in paragraphs: | |
23 | while len(paragraph) > width: | |
24 | pos = paragraph.rfind(' ', 0, width) | |
25 | if not pos: | |
26 | pos = width | |
27 | lines.append(paragraph[:pos]) | |
28 | paragraph = paragraph[pos:] | |
a9bf3cbe | 29 | lines.append(paragraph.lstrip()) |
7261a759 | 30 | return '\n'.join(lines) |
5470bdf1 | 31 | |
9068dba1 | 32 | class BootBaseHandler(BaseHandler): |
37b5c0cf MT |
33 | @property |
34 | def arch(self): | |
35 | arch = self.get_argument("arch", "i386") | |
36 | if not arch in ("x86_64", "i586", "i386"): | |
37 | raise tornado.web.HTTPError(400, "Invalid architecture") | |
38 | ||
39 | if arch == "i386": | |
40 | arch = "i586" | |
41 | ||
42 | return arch | |
43 | ||
44 | @property | |
45 | def platform(self): | |
46 | platform = self.get_argument("platform", "pcbios") | |
47 | if not platform in ("pcbios", "efi"): | |
48 | raise tornado.web.HTTPError(400, "Invalid platform") | |
49 | ||
50 | return platform | |
5470bdf1 MT |
51 | |
52 | ||
8e2e1261 | 53 | class MenuGPXEHandler(BootBaseHandler): |
0d71ac64 | 54 | |
5470bdf1 MT |
55 | """ |
56 | menu.gpxe | |
57 | """ | |
58 | def get(self): | |
0d71ac64 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)) | |
e7c9ed3c | 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 |
83 | class 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 | 90 | class 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): | |
66b066ae | 103 | return "https://nightly.ipfire.org/next/latest/%s/images/vmlinuz" % arch |
37b5c0cf MT |
104 | |
105 | def netboot_initrd_url(self, arch, platform): | |
66b066ae | 106 | return "https://nightly.ipfire.org/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) |