]>
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 StatsHandler(base
.BaseHandler
, tornado
.websocket
.WebSocketHandler
):
58 # No authentication required
59 async def open(self
, name
):
60 builder
= self
.backend
.builders
.get_by_name(name
)
62 raise tornado
.web
.HTTPError(404, "Could not find builder %s" % name
)
64 # Register to receive updates
65 self
.backend
.builders
.stats
.join(builder
=builder
, connection
=self
)
67 # Initially send the stats that we currently have
69 await self
.submit_stats(builder
.stats
)
72 self
.backend
.builders
.stats
.leave(self
)
74 async def submit_stats(self
, stats
):
75 await self
.write_message({
76 "cpu_usage" : stats
.cpu_usage
,
77 "mem_usage" : stats
.mem_usage
,
78 "swap_usage" : stats
.swap_usage
,
82 class IndexHandler(base
.BaseHandler
):
84 self
.render("builders/index.html", builders
=self
.backend
.builders
)
87 class ShowHandler(base
.BaseHandler
):
88 async def get(self
, hostname
):
89 builder
= self
.backend
.builders
.get_by_name(hostname
)
91 raise tornado
.web
.HTTPError(404, "Could not find builder %s" % hostname
)
95 "is_running" : await builder
.is_running(),
96 "is_shutting_down" : await builder
.is_shutting_down(),
97 "is_shut_down" : await builder
.is_shut_down(),
100 self
.render("builders/show.html", builder
=builder
, **args
)
103 class CreateHandler(base
.BaseHandler
):
104 @tornado.web
.authenticated
107 if not self
.current_user
.is_admin():
108 raise tornado
.web
.HTTPError(403)
110 self
.render("builders/create.html")
112 @tornado.web
.authenticated
115 if not self
.current_user
.is_admin():
116 raise tornado
.web
.HTTPError(403)
118 hostname
= self
.get_argument("hostname")
120 # Create a new builder
121 with self
.db
.transaction():
122 builder
= self
.backend
.builders
.create(hostname
, user
=self
.current_user
)
124 self
.redirect("/builders/%s/edit" % builder
.hostname
)
127 class BuilderEditHandler(base
.BaseHandler
):
128 @tornado.web
.authenticated
129 def get(self
, hostname
):
130 builder
= self
.backend
.builders
.get_by_name(hostname
)
132 raise tornado
.web
.HTTPError(404, "Builder not found")
135 if not builder
.has_perm(self
.current_user
):
136 raise tornado
.web
.HTTPError(403)
138 self
.render("builders/edit.html", builder
=builder
)
140 @tornado.web
.authenticated
141 async def post(self
, hostname
):
142 builder
= self
.backend
.builders
.get_by_name(hostname
)
144 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % hostname
)
147 if not builder
.has_perm(self
.current_user
):
148 raise tornado
.web
.HTTPError(403)
150 with self
.db
.transaction():
151 builder
.enabled
= self
.get_argument("enabled", False)
152 builder
.maintenance
= self
.get_argument_bool("maintenance")
153 builder
.max_jobs
= self
.get_argument_int("max_jobs")
155 # Try to dispatch more jobs
156 await self
.backend
.jobs
.queue
.dispatch()
158 self
.redirect("/builders/%s" % builder
.hostname
)
161 class DeleteHandler(base
.BaseHandler
):
162 @tornado.web
.authenticated
164 builder
= self
.backend
.builders
.get_by_name(name
)
166 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
169 if not builder
.has_perm(self
.current_user
):
170 raise tornado
.web
.HTTPError(403)
172 self
.render("builders/delete.html", builder
=builder
)
174 @tornado.web
.authenticated
175 async def post(self
, hostname
):
176 builder
= self
.backend
.builders
.get_by_name(hostname
)
178 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % hostname
)
181 if not builder
.has_perm(self
.current_user
):
182 raise tornado
.web
.HTTPError(403)
185 with self
.db
.transaction():
186 builder
.delete(user
=self
.current_user
)
188 self
.redirect("/builders")
191 class StartHandler(base
.BaseHandler
):
192 @tornado.web
.authenticated
194 builder
= self
.backend
.builders
.get_by_name(name
)
196 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
199 if not builder
.has_perm(self
.current_user
):
200 raise tornado
.web
.HTTPError(403)
202 # Builders must be in maintenance mode
203 if not builder
.maintenance
:
204 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
206 self
.render("builders/start.html", builder
=builder
)
208 @tornado.web
.authenticated
209 async def post(self
, name
):
210 builder
= self
.backend
.builders
.get_by_name(name
)
212 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
215 if not builder
.has_perm(self
.current_user
):
216 raise tornado
.web
.HTTPError(403)
218 # Builders must be in maintenance mode
219 if not builder
.maintenance
:
220 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
224 await builder
.start(wait
=False)
226 # XXX what do we do when this fails?
230 self
.redirect("/builders/%s" % builder
.hostname
)
233 class StopHandler(base
.BaseHandler
):
234 @tornado.web
.authenticated
236 builder
= self
.backend
.builders
.get_by_name(name
)
238 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
241 if not builder
.has_perm(self
.current_user
):
242 raise tornado
.web
.HTTPError(403)
244 # Builders must be in maintenance mode
245 if not builder
.maintenance
:
246 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
248 self
.render("builders/stop.html", builder
=builder
)
250 @tornado.web
.authenticated
251 async def post(self
, name
):
252 builder
= self
.backend
.builders
.get_by_name(name
)
254 raise tornado
.web
.HTTPError(404, "Builder not found: %s" % name
)
257 if not builder
.has_perm(self
.current_user
):
258 raise tornado
.web
.HTTPError(403)
260 # Builders must be in maintenance mode
261 if not builder
.maintenance
:
262 raise tornado
.web
.HTTPError(400, "%s is not in maintenance mode" % builder
)
266 await builder
.stop(wait
=False)
268 # XXX what do we do when this fails?
272 self
.redirect("/builders/%s" % builder
.hostname
)
275 class StatsModule(ui_modules
.UIModule
):
276 def render(self
, builder
):
277 return self
.render_string("builders/modules/stats.html", builder
=builder
)
279 def javascript_files(self
):
281 "js/builders-stats.min.js",