]>
git.ipfire.org Git - pbs.git/blob - src/web/builders.py
7 from . import ui_modules
10 log
= logging
.getLogger("pbs.web.builders")
12 class APIv1ControlHandler(base
.APIMixin
, tornado
.websocket
.WebSocketHandler
):
13 @tornado.web
.authenticated
15 # The builder has opened a new connection
16 self
.current_user
.connected(self
)
18 # After the builder has connected, try to dispatch some jobs
19 await self
.backend
.jobs
.queue
.dispatch()
21 def on_ping(self
, data
):
22 log
.debug("%s has pinged us" % self
.builder
)
25 # Drop the connection to the builder
26 self
.current_user
.disconnected()
28 async def on_message(self
, message
):
30 message
= self
._decode
_json
_message
(message
)
32 # Fetch the message type & data
33 type = message
.get("type")
34 data
= message
.get("data")
38 await self
._handle
_stats
(data
)
40 # Log an error and ignore any other messages
42 log
.error("Received message of type '%s' which we cannot handle here" % type)
44 async def _handle_stats(self
, data
):
46 Handles stats messages
48 with self
.db
.transaction():
49 await self
.builder
.log_stats(**data
)
52 class APIv1StatsHandler(base
.APIMixin
, base
.BaseHandler
):
57 "cpu_model" : self
.get_argument("cpu_model"),
58 "cpu_count" : self
.get_argument_int("cpu_count"),
59 "cpu_arch" : self
.get_argument("cpu_arch"),
62 "pakfire_version" : self
.get_argument("pakfire_version"),
65 "os_name" : self
.get_argument("os_name"),
68 "cpu_user" : self
.get_argument_float("cpu_user"),
69 "cpu_nice" : self
.get_argument_float("cpu_nice"),
70 "cpu_system" : self
.get_argument_float("cpu_system"),
71 "cpu_idle" : self
.get_argument_float("cpu_idle"),
72 "cpu_iowait" : self
.get_argument_float("cpu_iowait"),
73 "cpu_irq" : self
.get_argument_float("cpu_irq"),
74 "cpu_softirq" : self
.get_argument_float("cpu_softirq"),
75 "cpu_steal" : self
.get_argument_float("cpu_steal"),
76 "cpu_guest" : self
.get_argument_float("cpu_guest"),
77 "cpu_guest_nice" : self
.get_argument_float("cpu_guest_nice"),
80 "loadavg1" : self
.get_argument_float("loadavg1"),
81 "loadavg5" : self
.get_argument_float("loadavg5"),
82 "loadavg15" : self
.get_argument_float("loadavg15"),
85 "mem_total" : self
.get_argument_int("mem_total"),
86 "mem_available" : self
.get_argument_int("mem_available"),
87 "mem_used" : self
.get_argument_int("mem_used"),
88 "mem_free" : self
.get_argument_int("mem_free"),
89 "mem_active" : self
.get_argument_int("mem_active"),
90 "mem_inactive" : self
.get_argument_int("mem_inactive"),
91 "mem_buffers" : self
.get_argument_int("mem_buffers"),
92 "mem_cached" : self
.get_argument_int("mem_cached"),
93 "mem_shared" : self
.get_argument_int("mem_shared"),
96 "swap_total" : self
.get_argument_int("swap_total"),
97 "swap_used" : self
.get_argument_int("swap_used"),
98 "swap_free" : self
.get_argument_int("swap_free"),
101 with self
.db
.transaction():
102 await self
.builder
.log_stats(**stats
)
108 class StatsHandler(base
.BaseHandler
, tornado
.websocket
.WebSocketHandler
):
109 # No authentication required
110 async def open(self
, name
):
111 builder
= self
.backend
.builders
.get_by_name(name
)
113 raise tornado
.web
.HTTPError(404, "Could not find builder %s" % name
)
115 # Register to receive updates
116 self
.backend
.builders
.stats
.join(builder
=builder
, connection
=self
)
118 # Initially send the stats that we currently have
120 await self
.submit_stats(builder
.stats
)
123 self
.backend
.builders
.stats
.leave(self
)
125 async def submit_stats(self
, stats
):
126 await self
.write_message({
127 "cpu_usage" : stats
.cpu_usage
,
128 "mem_usage" : stats
.mem_usage
,
129 "swap_usage" : stats
.swap_usage
,
133 class IndexHandler(base
.BaseHandler
):
135 self
.render("builders/index.html", builders
=self
.backend
.builders
)
138 class ShowHandler(base
.BaseHandler
):
139 async def get(self
, hostname
):
140 builder
= self
.backend
.builders
.get_by_name(hostname
)
142 raise tornado
.web
.HTTPError(404, "Could not find builder %s" % hostname
)
146 "is_running" : await builder
.is_running(),
147 "is_shutting_down" : await builder
.is_shutting_down(),
148 "is_shut_down" : await builder
.is_shut_down(),
151 self
.render("builders/show.html", builder
=builder
, **args
)
154 class CreateHandler(base
.BaseHandler
):
155 @tornado.web
.authenticated
158 if not self
.current_user
.is_admin():
159 raise tornado
.web
.HTTPError(403)
161 self
.render("builders/create.html")
163 @tornado.web
.authenticated
166 if not self
.current_user
.is_admin():
167 raise tornado
.web
.HTTPError(403)
169 hostname
= self
.get_argument("hostname")
171 # Create a new builder
172 with self
.db
.transaction():
173 builder
= self
.backend
.builders
.create(hostname
, user
=self
.current_user
)
175 self
.redirect("/builders/%s/edit" % builder
.hostname
)
178 class BuilderEditHandler(base
.BaseHandler
):
179 @tornado.web
.authenticated
180 def get(self
, hostname
):
181 builder
= self
.backend
.builders
.get_by_name(hostname
)
183 raise tornado
.web
.HTTPError(404, "Builder not found")
186 if not builder
.has_perm(self
.current_user
):
187 raise tornado
.web
.HTTPError(403)
189 self
.render("builders/edit.html", builder
=builder
)
191 @tornado.web
.authenticated
192 async def post(self
, hostname
):
193 builder
= self
.backend
.builders
.get_by_name(hostname
)
195 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % hostname
)
198 if not builder
.has_perm(self
.current_user
):
199 raise tornado
.web
.HTTPError(403)
201 with self
.db
.transaction():
202 builder
.enabled
= self
.get_argument("enabled", False)
203 builder
.maintenance
= self
.get_argument_bool("maintenance")
204 builder
.max_jobs
= self
.get_argument_int("max_jobs")
206 # Try to dispatch more jobs
207 await self
.backend
.jobs
.queue
.dispatch()
209 self
.redirect("/builders/%s" % builder
.hostname
)
212 class DeleteHandler(base
.BaseHandler
):
213 @tornado.web
.authenticated
215 builder
= self
.backend
.builders
.get_by_name(name
)
217 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
220 if not builder
.has_perm(self
.current_user
):
221 raise tornado
.web
.HTTPError(403)
223 self
.render("builders/delete.html", builder
=builder
)
225 @tornado.web
.authenticated
226 async def post(self
, hostname
):
227 builder
= self
.backend
.builders
.get_by_name(hostname
)
229 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % hostname
)
232 if not builder
.has_perm(self
.current_user
):
233 raise tornado
.web
.HTTPError(403)
236 with self
.db
.transaction():
237 builder
.delete(user
=self
.current_user
)
239 self
.redirect("/builders")
242 class StartHandler(base
.BaseHandler
):
243 @tornado.web
.authenticated
245 builder
= self
.backend
.builders
.get_by_name(name
)
247 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
250 if not builder
.has_perm(self
.current_user
):
251 raise tornado
.web
.HTTPError(403)
253 # Builders must be in maintenance mode
254 if not builder
.maintenance
:
255 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
257 self
.render("builders/start.html", builder
=builder
)
259 @tornado.web
.authenticated
260 async def post(self
, name
):
261 builder
= self
.backend
.builders
.get_by_name(name
)
263 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
266 if not builder
.has_perm(self
.current_user
):
267 raise tornado
.web
.HTTPError(403)
269 # Builders must be in maintenance mode
270 if not builder
.maintenance
:
271 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
275 await builder
.start(wait
=False)
277 # XXX what do we do when this fails?
281 self
.redirect("/builders/%s" % builder
.hostname
)
284 class StopHandler(base
.BaseHandler
):
285 @tornado.web
.authenticated
287 builder
= self
.backend
.builders
.get_by_name(name
)
289 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
292 if not builder
.has_perm(self
.current_user
):
293 raise tornado
.web
.HTTPError(403)
295 # Builders must be in maintenance mode
296 if not builder
.maintenance
:
297 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
299 self
.render("builders/stop.html", builder
=builder
)
301 @tornado.web
.authenticated
302 async def post(self
, name
):
303 builder
= self
.backend
.builders
.get_by_name(name
)
305 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
308 if not builder
.has_perm(self
.current_user
):
309 raise tornado
.web
.HTTPError(403)
311 # Builders must be in maintenance mode
312 if not builder
.maintenance
:
313 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
317 await builder
.stop(wait
=False)
319 # XXX what do we do when this fails?
323 self
.redirect("/builders/%s" % builder
.hostname
)
326 class StatsModule(ui_modules
.UIModule
):
327 def render(self
, builder
):
328 return self
.render_string("builders/modules/stats.html", builder
=builder
)
330 def javascript_files(self
):
332 "js/builders-stats.min.js",