]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blame - webapp/handlers_boot.py
BIO: Make this work for pxelinux.
[people/shoehn/ipfire.org.git] / webapp / handlers_boot.py
CommitLineData
5470bdf1
MT
1#!/usr/bin/python
2
3import logging
4import os
5import tornado.httpserver
6import tornado.ioloop
7import tornado.locale
8import tornado.options
9import tornado.web
10
8b9b631e 11import backend
5470bdf1
MT
12
13BASEDIR = os.path.dirname(__file__)
14
a9bf3cbe 15def word_wrap(s, width=45):
7261a759
MT
16 paragraphs = s.split('\n')
17 lines = []
18 for paragraph in paragraphs:
19 while len(paragraph) > width:
20 pos = paragraph.rfind(' ', 0, width)
21 if not pos:
22 pos = width
23 lines.append(paragraph[:pos])
24 paragraph = paragraph[pos:]
a9bf3cbe 25 lines.append(paragraph.lstrip())
7261a759 26 return '\n'.join(lines)
5470bdf1 27
8e2e1261 28class BootBaseHandler(tornado.web.RequestHandler):
5470bdf1
MT
29 @property
30 def netboot(self):
31 return backend.NetBoot()
32
33
8e2e1261 34class MenuGPXEHandler(BootBaseHandler):
5470bdf1
MT
35 """
36 menu.gpxe
37 """
38 def get(self):
e847f85c
MT
39 # Check if version of the bootloader is recent enough.
40 # Otherwise send the latest version of the PXE loader.
41 user_agent = self.request.headers.get("User-Agent", None)
42 if user_agent:
43 try:
44 client, version = user_agent.split("/")
45 except:
46 pass
47 else:
48 # We replaced gPXE by iPXE.
49 if client == "gPXE":
50 return self.serve_update()
51
52 # Everything under version 1.0.0 should be
53 # updated.
54 if version < "1.0.0":
55 return self.serve_update()
5470bdf1
MT
56
57 # Devliver content
58 self.set_header("Content-Type", "text/plain")
59 self.write("#!gpxe\n")
e847f85c
MT
60
61 self.write("set 209:string premenu.cfg\n")
62 self.write("set 210:string http://boot.ipfire.org/\n")
63 self.write("chain pxelinux.0\n")
64
65 def serve_update(self):
66 self.set_header("Content-Type", "text/plain")
67 self.write("#!gpxe\n")
68
69 # Small warning
70 self.write("echo\necho Your copy of gPXE/iPXE is too old. ")
71 self.write("Upgrade to avoid seeing this every boot!\n")
72
73 self.write("chain http://mirror0.ipfire.org/releases/ipfire-boot/latest/ipxe.kpxe\n")
5470bdf1
MT
74
75
8e2e1261 76class MenuCfgHandler(BootBaseHandler):
5470bdf1
MT
77 def _menu_string(self, menu, level=0):
78 s = ""
79
80 for entry in menu:
81 s += self._menu_entry(entry, level=level)
82
83 return s
84
85 def _menu_entry(self, entry, level=0):
86 lines = []
87
88 ident = "\t" * level
89
90 if entry.type == "seperator":
2109db85 91 lines.append(ident + "menu separator")
5470bdf1
MT
92
93 elif entry.type == "header":
94 lines.append(ident + "menu begin %d" % entry.id)
95 lines.append(ident + "\tmenu title %s" % entry.title)
96
97 # Add "Back..." entry
98 lines.append(ident + "\tlabel %d.back" % entry.id)
99 lines.append(ident + "\t\tmenu label Back...")
100 lines.append(ident + "\t\tmenu exit")
2109db85 101 lines.append(ident + "\tmenu separator")
5470bdf1 102
2109db85 103 lines.append("%s" % self._menu_string(entry.submenu, level=level+1))
5470bdf1 104 lines.append(ident + "menu end")
5470bdf1
MT
105
106 elif entry.type == "config":
107 lines.append(ident + "label %d" % entry.id)
108 lines.append(ident + "\tmenu label %s" % entry.title)
109 if entry.description:
110 lines.append(ident + "\ttext help")
7261a759 111 lines.append(word_wrap(entry.description))
5470bdf1 112 lines.append(ident + "\tendtext")
31c90b72
MT
113
114 config = self.netboot.get_config(entry.item)
115 if not config: return ""
116
117 lines.append(ident + "\tkernel %s" % config.image1)
118 if config.image2:
119 lines.append(ident + "\tinitrd %s" % config.image2)
120 if config.args:
121 lines.append(ident + "\tappend %s" % config.args)
5470bdf1 122
7261a759 123 return "\n".join(lines + [""])
5470bdf1
MT
124
125 def get(self):
126 self.set_header("Content-Type", "text/plain")
127
128 menu = self._menu_string(self.netboot.get_menu(1))
129
085f94df 130 self.render("netboot/menu.cfg", menu=menu)
5470bdf1
MT
131
132
8e2e1261 133class BootGPXEHandler(BootBaseHandler):
5470bdf1
MT
134 def get(self, id):
135 config = self.netboot.get_config(id)
136 if not config:
137 raise tornado.web.HTTPError(404, "Configuration with ID '%s' was not found" % id)
138
139 lines = ["#!gpxe", "imgfree",]
140
141 line = "kernel -n img %s" % config.image1
142 if line.endswith(".iso"):
143 line += " iso"
8b9b631e
MT
144 if config.args:
145 line += " %s" % config.args
5470bdf1
MT
146 lines.append(line)
147
148 if config.image2:
149 lines.append("initrd -n img %s" % config.image2)
150
151 lines.append("boot img")
152
153 for line in lines:
154 self.write("%s\n" % line)