]>
git.ipfire.org Git - pbs.git/blob - src/web/builds.py
5 from ..errors
import NoSuchDistroError
9 from . import ui_modules
11 class APIv1IndexHandler(base
.APIMixin
, base
.BaseHandler
):
12 # Allow users to create builds
15 @tornado.web
.authenticated
18 upload
= self
.get_argument_upload("upload_id")
20 raise tornado
.web
.HTTPError(404, "Could not find upload")
22 # Check permissions of the upload
23 if not upload
.has_perm(self
.current_user
):
24 raise tornado
.web
.HTTPError(403, "No permission for using upload %s" % upload
)
26 # Fetch the repository
27 repo_name
= self
.get_argument("repo", None)
29 # Did the uploader request to disable test builds?
30 disable_test_builds
= self
.get_argument_bool("disable_test_builds")
32 with self
.db
.transaction():
35 package
= await self
.backend
.packages
.create(upload
)
37 # If the distribution that is coded into the package could not be found,
38 # we will send that error to the user...
39 except NoSuchDistroError
as e
:
40 raise tornado
.web
.HTTPError(404, "Could not find distribution: %s" % e
)
43 repo
= self
.current_user
.get_repo(package
.distro
, repo_name
)
45 raise tornado
.web
.HTTPError(404, "Could not find repository")
48 build
= await self
.backend
.builds
.create(repo
, package
,
49 owner
=self
.current_user
, disable_test_builds
=disable_test_builds
)
54 # Send some data about the build
57 "name" : "%s" % build
,
60 # Launch all jobs (in the background)
61 self
.backend
.run_task(self
.backend
.builds
.launch
, [build
])
64 class IndexHandler(base
.BaseHandler
):
67 offset
= self
.get_argument_int("offset", None) or 0
68 limit
= self
.get_argument_int("limit", None) or 25
71 user
= self
.get_argument_user("user", None)
73 # Fetch the most recent builds
75 builds
= self
.backend
.builds
.get_by_user(user
, limit
=limit
, offset
=offset
)
77 builds
= self
.backend
.builds
.get_recent(limit
=limit
, offset
=offset
)
79 # Group builds by date
80 builds
= misc
.group(builds
, lambda build
: build
.created_at
.date())
82 self
.render("builds/index.html", builds
=builds
, user
=user
,
83 limit
=limit
, offset
=offset
)
86 class QueueHandler(base
.BaseHandler
):
88 self
.render("builds/queue.html", queue
=self
.backend
.jobs
.queue
)
91 class ShowHandler(base
.BaseHandler
):
92 async def get(self
, uuid
):
93 build
= self
.backend
.builds
.get_by_uuid(uuid
)
95 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
97 # Fetch any fixed Bugs
98 bugs
= await build
.get_bugs()
100 self
.render("builds/show.html", build
=build
, pkg
=build
.pkg
,
101 distro
=build
.distro
, bugs
=bugs
)
104 class CloneHandler(base
.BaseHandler
):
105 @tornado.web
.authenticated
107 build
= self
.backend
.builds
.get_by_uuid(uuid
)
109 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
113 repos
= self
.current_user
.repos
[build
.distro
]
117 self
.render("builds/clone.html", build
=build
, repos
=repos
)
119 @tornado.web
.authenticated
120 async def post(self
, uuid
):
121 build
= self
.backend
.builds
.get_by_uuid(uuid
)
123 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
125 # Fetch the repository
126 repo
= self
.current_user
.get_repo(build
.distro
, self
.get_argument("repo"))
129 with self
.db
.transaction():
130 clone
= await self
.backend
.builds
.create(
131 repo
=repo
, package
=build
.pkg
, owner
=self
.current_user
,
134 # Launch all jobs (in the background)
135 self
.backend
.run_task(self
.backend
.builds
.launch
, [clone
])
137 self
.redirect("/builds/%s" % clone
.uuid
)
140 class DeleteHandler(base
.BaseHandler
):
141 @tornado.web
.authenticated
143 build
= self
.backend
.builds
.get_by_uuid(uuid
)
145 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
148 if not build
.can_be_deleted(self
.current_user
):
149 raise tornado
.web
.HTTPError(403, "%s cannot delete build %s" \
150 % (self
.current_user
, build
))
152 self
.render("builds/delete.html", build
=build
)
154 @tornado.web
.authenticated
155 async def post(self
, uuid
):
156 build
= self
.backend
.builds
.get_by_uuid(uuid
)
158 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
161 if not build
.can_be_deleted(self
.current_user
):
162 raise tornado
.web
.HTTPError(403, "%s cannot delete build %s" \
163 % (self
.current_user
, build
))
166 with self
.db
.transaction():
167 await build
.delete(self
.current_user
)
169 self
.redirect("/builds")
172 class WatchHandler(base
.BaseHandler
):
173 @tornado.web
.authenticated
174 def post(self
, uuid
):
175 build
= self
.backend
.builds
.get_by_uuid(uuid
)
177 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
179 with self
.db
.transaction():
180 build
.add_watcher(self
.current_user
)
182 self
.redirect("/builds/%s" % build
.uuid
)
185 class UnwatchHandler(base
.BaseHandler
):
186 @tornado.web
.authenticated
187 def post(self
, uuid
):
188 build
= self
.backend
.builds
.get_by_uuid(uuid
)
190 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
192 with self
.db
.transaction():
193 build
.remove_watcher(self
.current_user
)
195 self
.redirect("/builds/%s" % build
.uuid
)
198 class CommentHandler(base
.BaseHandler
):
199 @tornado.web
.authenticated
200 async def post(self
, uuid
):
201 build
= self
.backend
.builds
.get_by_uuid(uuid
)
203 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
205 text
= self
.get_argument("text")
207 # Add a new comment to the build
208 with self
.db
.transaction():
209 await build
.comment(self
.current_user
, text
)
211 # Redirect to the build
212 self
.redirect("/builds/%s" % build
.uuid
)
215 class BugHandler(base
.BaseHandler
):
216 @tornado.web
.authenticated
217 async def get(self
, uuid
):
218 build
= self
.backend
.builds
.get_by_uuid(uuid
)
220 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
223 fields
= await self
.backend
.bugzilla
.fields
225 self
.render("builds/bug.html", build
=build
, fields
=fields
)
227 @tornado.web
.authenticated
228 async def post(self
, uuid
):
229 build
= self
.backend
.builds
.get_by_uuid(uuid
)
231 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
233 # Is the user connected to Bugzilla?
234 if not self
.current_user
.bugzilla
:
235 raise tornado
.web
.HTTPError(400, "%s is not connected to Bugzilla" \
239 # Summary & Description
240 "summary" : self
.get_argument("summary"),
241 "description" : self
.get_argument("description", None),
242 } | build
.bugzilla_fields
245 bug
= await self
.current_user
.bugzilla
.create_bug(**kwargs
)
247 # Send the attachments
248 for job
in build
.jobs
:
249 if not self
.get_argument_bool("attach_log_%s" % job
.uuid
):
254 log
= await job
.open_log()
255 except FileNotFoundError
as e
:
256 log
.warning("Could not open log file for %s" % job
)
259 # Attach it to the bug
260 await bug
.attach(summary
="Log file for %s" % job
, filename
="%s.log" % job
,
261 data
=log
, content_type
="text/plain")
263 self
.render("builds/bug-created.html", build
=build
, bug
=bug
)
266 class ReposAddHandler(base
.BaseHandler
):
267 @tornado.web
.authenticated
269 build
= self
.backend
.builds
.get_by_uuid(uuid
)
271 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
273 # Fetch all available repositories
275 repos
= self
.current_user
.repos
[build
.distro
]
279 self
.render("builds/repos/add.html", build
=build
, repos
=repos
)
281 @tornado.web
.authenticated
282 async def post(self
, uuid
):
283 build
= self
.backend
.builds
.get_by_uuid(uuid
)
285 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
287 slug
= self
.get_argument("repo")
289 # Fetch the repository
290 repo
= self
.current_user
.get_repo(build
.distro
, slug
)
292 raise tornado
.web
.HTTPError(400, "Could not find repository '%s'" % slug
)
294 # Add the build to the repository
295 with self
.db
.transaction():
296 await repo
.add_build(build
, user
=self
.current_user
, update
=False)
298 # Update the repository in the background
299 self
.backend
.run_task(repo
.update
)
301 self
.redirect("/builds/%s" % build
.uuid
)
304 class ReposRemoveHandler(base
.BaseHandler
):
305 @tornado.web
.authenticated
307 build
= self
.backend
.builds
.get_by_uuid(uuid
)
309 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
311 # Raise error when the build is in to repositories
313 raise tornado
.web
.HTTPError(400)
315 self
.render("builds/repos/remove.html", build
=build
)
317 @tornado.web
.authenticated
318 async def post(self
, uuid
):
319 build
= self
.backend
.builds
.get_by_uuid(uuid
)
321 raise tornado
.web
.HTTPError(404, "Could not find build %s" % uuid
)
323 # Fetch all selected repos
324 repos
= self
.get_arguments("repo")
326 # Raise an error if nothing has been selected
328 raise tornado
.web
.HTTPError(400, "No repositories selected")
330 # Find all selected repositories
331 repos
= [repo
for repo
in build
.repos
if repo
.slug
in repos
]
333 # Remove build from all repositories
334 with self
.db
.transaction():
336 await repo
.remove_build(build
, user
=self
.current_user
, update
=False)
338 # Update all repositories in the background
340 self
.backend
.run_task(repo
.update
)
342 self
.redirect("/builds/%s" % build
.uuid
)
345 class GroupShowHandler(base
.BaseHandler
):
347 group
= self
.backend
.builds
.groups
.get_by_uuid(uuid
)
349 raise tornado
.web
.HTTPError(404, "Could not find build group %s" % uuid
)
351 self
.render("builds/groups/show.html", group
=group
)
354 class ListModule(ui_modules
.UIModule
):
355 def render(self
, builds
):
356 return self
.render_string("builds/modules/list.html", builds
=builds
)
359 class GroupListModule(ui_modules
.UIModule
):
360 def render(self
, group
, limit
=None):
361 return self
.render_string("builds/groups/modules/list.html",
362 group
=group
, limit
=limit
)
365 class WatchersModule(ui_modules
.UIModule
):
366 def render(self
, build
, watchers
=None):
368 watchers
= build
.watchers
370 return self
.render_string("builds/modules/watchers.html",
371 build
=build
, watchers
=watchers
)