]>
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 | ||
11347e46 | 11 | from .handlers_base import BaseHandler |
9068dba1 | 12 | |
5470bdf1 MT |
13 | BASEDIR = os.path.dirname(__file__) |
14 | ||
0d71ac64 MT |
15 | LATEST_VERSION = "2.0" |
16 | ||
a9bf3cbe | 17 | def word_wrap(s, width=45): |
7261a759 MT |
18 | paragraphs = s.split('\n') |
19 | lines = [] | |
20 | for paragraph in paragraphs: | |
21 | while len(paragraph) > width: | |
22 | pos = paragraph.rfind(' ', 0, width) | |
23 | if not pos: | |
24 | pos = width | |
25 | lines.append(paragraph[:pos]) | |
26 | paragraph = paragraph[pos:] | |
a9bf3cbe | 27 | lines.append(paragraph.lstrip()) |
7261a759 | 28 | return '\n'.join(lines) |
5470bdf1 | 29 | |
9068dba1 | 30 | class BootBaseHandler(BaseHandler): |
37b5c0cf MT |
31 | @property |
32 | def arch(self): | |
33 | arch = self.get_argument("arch", "i386") | |
34 | if not arch in ("x86_64", "i586", "i386"): | |
35 | raise tornado.web.HTTPError(400, "Invalid architecture") | |
36 | ||
37 | if arch == "i386": | |
38 | arch = "i586" | |
39 | ||
40 | return arch | |
41 | ||
42 | @property | |
43 | def platform(self): | |
44 | platform = self.get_argument("platform", "pcbios") | |
45 | if not platform in ("pcbios", "efi"): | |
46 | raise tornado.web.HTTPError(400, "Invalid platform") | |
47 | ||
48 | return platform | |
5470bdf1 MT |
49 | |
50 | ||
8e2e1261 | 51 | class MenuGPXEHandler(BootBaseHandler): |
0d71ac64 | 52 | |
5470bdf1 MT |
53 | """ |
54 | menu.gpxe | |
55 | """ | |
56 | def get(self): | |
a69e87a1 MT |
57 | version = self.get_argument("version", None) |
58 | if not version or version < LATEST_VERSION: | |
59 | return self.serve_update() | |
98133910 MT |
60 | |
61 | # Deliver content | |
5470bdf1 MT |
62 | self.set_header("Content-Type", "text/plain") |
63 | self.write("#!gpxe\n") | |
e847f85c | 64 | |
37b5c0cf MT |
65 | self.write("set 209:string premenu.cfg?arch=%s&platform=%s\n" \ |
66 | % (self.arch, self.platform)) | |
e7c9ed3c | 67 | self.write("set 210:string http://boot.ipfire.org/\n") |
e847f85c MT |
68 | self.write("chain pxelinux.0\n") |
69 | ||
70 | def serve_update(self): | |
71 | self.set_header("Content-Type", "text/plain") | |
72 | self.write("#!gpxe\n") | |
73 | ||
74 | # Small warning | |
75 | self.write("echo\necho Your copy of gPXE/iPXE is too old. ") | |
76 | self.write("Upgrade to avoid seeing this every boot!\n") | |
77 | ||
e48a74ea | 78 | self.write("chain static/netboot/ipxe.kpxe\n") |
5470bdf1 | 79 | |
98133910 | 80 | |
37b5c0cf MT |
81 | class PremenuCfgHandler(BootBaseHandler): |
82 | def get(self): | |
83 | self.set_header("Content-Type", "text/plain") | |
84 | ||
85 | self.render("netboot/premenu.cfg", arch=self.arch, platform=self.platform) | |
86 | ||
5470bdf1 | 87 | |
8e2e1261 | 88 | class MenuCfgHandler(BootBaseHandler): |
53211b33 MT |
89 | class NightlyBuildReleaseDummy(object): |
90 | id = 100 | |
91 | name = "Nightly Build" | |
92 | sname = "nightly-build" | |
93 | ||
37b5c0cf MT |
94 | def supports_arch(self, arch): |
95 | return arch in ("i586", "x86_64") | |
96 | ||
97 | def supports_platform(self, platform): | |
98 | return platform == "pcbios" | |
99 | ||
100 | def netboot_kernel_url(self, arch, platform): | |
66b066ae | 101 | return "https://nightly.ipfire.org/next/latest/%s/images/vmlinuz" % arch |
37b5c0cf MT |
102 | |
103 | def netboot_initrd_url(self, arch, platform): | |
66b066ae | 104 | return "https://nightly.ipfire.org/next/latest/%s/images/instroot" % arch |
37b5c0cf MT |
105 | |
106 | def netboot_args(self, arch, platform): | |
66b066ae | 107 | return "installer.download-url=https://nightly.ipfire.org/next/latest/%s/images/installer.iso" % arch |
53211b33 MT |
108 | |
109 | def is_netboot_capable(self): | |
110 | return True | |
111 | ||
112 | nightly_build = NightlyBuildReleaseDummy() | |
113 | ||
5470bdf1 MT |
114 | def get(self): |
115 | self.set_header("Content-Type", "text/plain") | |
116 | ||
9068dba1 | 117 | latest_release = self.releases.get_latest() |
37b5c0cf MT |
118 | if latest_release and not latest_release.supports_arch(self.arch): |
119 | latest_release = None | |
120 | ||
121 | stable_releases = [r for r in self.releases.get_stable() | |
122 | if r.supports_arch(self.arch) and r.supports_platform(self.platform)] | |
9068dba1 MT |
123 | try: |
124 | stable_releases.remove(latest_release) | |
125 | except ValueError: | |
126 | pass | |
127 | ||
37b5c0cf MT |
128 | development_releases = [r for r in self.releases.get_unstable() |
129 | if r.supports_arch(self.arch) and r.supports_platform(self.platform)] | |
53211b33 | 130 | development_releases.insert(0, self.nightly_build) |
5470bdf1 | 131 | |
9068dba1 | 132 | self.render("netboot/menu.cfg", latest_release=latest_release, |
37b5c0cf MT |
133 | stable_releases=stable_releases, development_releases=development_releases, |
134 | arch=self.arch, platform=self.platform) |