]>
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
, base
.BackendMixin
, tornado
.websocket
.WebSocketHandler
):
15 # This is here to require authentication before
16 # the websocket connection is being negotiated.
20 # The builder has opened a new connection
21 self
.current_user
.connected(self
)
23 # After the builder has connected, try to dispatch some jobs
24 await self
.backend
.jobs
.queue
.dispatch()
26 def on_ping(self
, data
):
27 log
.debug("%s has pinged us" % self
.builder
)
30 # Drop the connection to the builder
31 self
.current_user
.disconnected()
33 async def on_message(self
, message
):
35 message
= self
._decode
_json
_message
(message
)
37 # Fetch the message type & data
38 type = message
.get("type")
39 data
= message
.get("data")
43 await self
._handle
_stats
(data
)
45 # Log an error and ignore any other messages
47 log
.error("Received message of type '%s' which we cannot handle here" % type)
49 async def _handle_stats(self
, data
):
51 Handles stats messages
53 with self
.db
.transaction():
54 await self
.builder
.log_stats(**data
)
57 class APIv1StatsHandler(base
.APIMixin
, base
.BaseHandler
):
62 "cpu_model" : self
.get_argument("cpu_model"),
63 "cpu_count" : self
.get_argument_int("cpu_count"),
64 "cpu_arch" : self
.get_argument("cpu_arch"),
67 "pakfire_version" : self
.get_argument("pakfire_version"),
70 "os_name" : self
.get_argument("os_name"),
73 "cpu_user" : self
.get_argument_float("cpu_user"),
74 "cpu_nice" : self
.get_argument_float("cpu_nice"),
75 "cpu_system" : self
.get_argument_float("cpu_system"),
76 "cpu_idle" : self
.get_argument_float("cpu_idle"),
77 "cpu_iowait" : self
.get_argument_float("cpu_iowait"),
78 "cpu_irq" : self
.get_argument_float("cpu_irq"),
79 "cpu_softirq" : self
.get_argument_float("cpu_softirq"),
80 "cpu_steal" : self
.get_argument_float("cpu_steal"),
81 "cpu_guest" : self
.get_argument_float("cpu_guest"),
82 "cpu_guest_nice" : self
.get_argument_float("cpu_guest_nice"),
85 "loadavg1" : self
.get_argument_float("loadavg1"),
86 "loadavg5" : self
.get_argument_float("loadavg5"),
87 "loadavg15" : self
.get_argument_float("loadavg15"),
90 "mem_total" : self
.get_argument_int("mem_total"),
91 "mem_available" : self
.get_argument_int("mem_available"),
92 "mem_used" : self
.get_argument_int("mem_used"),
93 "mem_free" : self
.get_argument_int("mem_free"),
94 "mem_active" : self
.get_argument_int("mem_active"),
95 "mem_inactive" : self
.get_argument_int("mem_inactive"),
96 "mem_buffers" : self
.get_argument_int("mem_buffers"),
97 "mem_cached" : self
.get_argument_int("mem_cached"),
98 "mem_shared" : self
.get_argument_int("mem_shared"),
101 "swap_total" : self
.get_argument_int("swap_total"),
102 "swap_used" : self
.get_argument_int("swap_used"),
103 "swap_free" : self
.get_argument_int("swap_free"),
106 with self
.db
.transaction():
107 await self
.builder
.log_stats(**stats
)
113 class StatsHandler(base
.BaseHandler
, tornado
.websocket
.WebSocketHandler
):
114 # No authentication required
115 async def open(self
, name
):
116 builder
= self
.backend
.builders
.get_by_name(name
)
118 raise tornado
.web
.HTTPError(404, "Could not find builder %s" % name
)
120 # Register to receive updates
121 self
.backend
.builders
.stats
.join(builder
=builder
, connection
=self
)
123 # Initially send the stats that we currently have
125 await self
.submit_stats(builder
.stats
)
128 self
.backend
.builders
.stats
.leave(self
)
130 async def submit_stats(self
, stats
):
131 await self
.write_message({
132 "cpu_usage" : stats
.cpu_usage
,
133 "mem_usage" : stats
.mem_usage
,
134 "swap_usage" : stats
.swap_usage
,
138 class IndexHandler(base
.BaseHandler
):
140 self
.render("builders/index.html", builders
=self
.backend
.builders
)
143 class ShowHandler(base
.BaseHandler
):
144 async def get(self
, hostname
):
145 builder
= self
.backend
.builders
.get_by_name(hostname
)
147 raise tornado
.web
.HTTPError(404, "Could not find builder %s" % hostname
)
151 "is_running" : await builder
.is_running(),
152 "is_shutting_down" : await builder
.is_shutting_down(),
153 "is_shut_down" : await builder
.is_shut_down(),
156 self
.render("builders/show.html", builder
=builder
, **args
)
159 class CreateHandler(base
.BaseHandler
):
160 @tornado.web
.authenticated
163 if not self
.current_user
.is_admin():
164 raise tornado
.web
.HTTPError(403)
166 self
.render("builders/create.html")
168 @tornado.web
.authenticated
171 if not self
.current_user
.is_admin():
172 raise tornado
.web
.HTTPError(403)
174 hostname
= self
.get_argument("hostname")
176 # Create a new builder
177 with self
.db
.transaction():
178 builder
= self
.backend
.builders
.create(hostname
, user
=self
.current_user
)
180 self
.redirect("/builders/%s/edit" % builder
.hostname
)
183 class BuilderEditHandler(base
.BaseHandler
):
184 @tornado.web
.authenticated
185 def get(self
, hostname
):
186 builder
= self
.backend
.builders
.get_by_name(hostname
)
188 raise tornado
.web
.HTTPError(404, "Builder not found")
191 if not builder
.has_perm(self
.current_user
):
192 raise tornado
.web
.HTTPError(403)
194 self
.render("builders/edit.html", builder
=builder
)
196 @tornado.web
.authenticated
197 async def post(self
, hostname
):
198 builder
= self
.backend
.builders
.get_by_name(hostname
)
200 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % hostname
)
203 if not builder
.has_perm(self
.current_user
):
204 raise tornado
.web
.HTTPError(403)
206 with self
.db
.transaction():
207 builder
.enabled
= self
.get_argument("enabled", False)
208 builder
.maintenance
= self
.get_argument_bool("maintenance")
209 builder
.max_jobs
= self
.get_argument_int("max_jobs")
211 # Try to dispatch more jobs
212 await self
.backend
.jobs
.queue
.dispatch()
214 self
.redirect("/builders/%s" % builder
.hostname
)
217 class DeleteHandler(base
.BaseHandler
):
218 @tornado.web
.authenticated
220 builder
= self
.backend
.builders
.get_by_name(name
)
222 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
225 if not builder
.has_perm(self
.current_user
):
226 raise tornado
.web
.HTTPError(403)
228 self
.render("builders/delete.html", builder
=builder
)
230 @tornado.web
.authenticated
231 async def post(self
, hostname
):
232 builder
= self
.backend
.builders
.get_by_name(hostname
)
234 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % hostname
)
237 if not builder
.has_perm(self
.current_user
):
238 raise tornado
.web
.HTTPError(403)
241 with self
.db
.transaction():
242 builder
.delete(user
=self
.current_user
)
244 self
.redirect("/builders")
247 class StartHandler(base
.BaseHandler
):
248 @tornado.web
.authenticated
250 builder
= self
.backend
.builders
.get_by_name(name
)
252 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
255 if not builder
.has_perm(self
.current_user
):
256 raise tornado
.web
.HTTPError(403)
258 # Builders must be in maintenance mode
259 if not builder
.maintenance
:
260 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
262 self
.render("builders/start.html", builder
=builder
)
264 @tornado.web
.authenticated
265 async def post(self
, name
):
266 builder
= self
.backend
.builders
.get_by_name(name
)
268 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
271 if not builder
.has_perm(self
.current_user
):
272 raise tornado
.web
.HTTPError(403)
274 # Builders must be in maintenance mode
275 if not builder
.maintenance
:
276 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
280 await builder
.start(wait
=False)
282 # XXX what do we do when this fails?
286 self
.redirect("/builders/%s" % builder
.hostname
)
289 class StopHandler(base
.BaseHandler
):
290 @tornado.web
.authenticated
292 builder
= self
.backend
.builders
.get_by_name(name
)
294 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
297 if not builder
.has_perm(self
.current_user
):
298 raise tornado
.web
.HTTPError(403)
300 # Builders must be in maintenance mode
301 if not builder
.maintenance
:
302 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
304 self
.render("builders/stop.html", builder
=builder
)
306 @tornado.web
.authenticated
307 async def post(self
, name
):
308 builder
= self
.backend
.builders
.get_by_name(name
)
310 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
313 if not builder
.has_perm(self
.current_user
):
314 raise tornado
.web
.HTTPError(403)
316 # Builders must be in maintenance mode
317 if not builder
.maintenance
:
318 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
322 await builder
.stop(wait
=False)
324 # XXX what do we do when this fails?
328 self
.redirect("/builders/%s" % builder
.hostname
)
331 class StatsModule(ui_modules
.UIModule
):
332 def render(self
, builder
):
333 return self
.render_string("builders/modules/stats.html", builder
=builder
)
335 def javascript_files(self
):
337 "js/builders-stats.min.js",