Chromium Code Reviews| Index: appengine/swarming/handlers_frontend.py |
| diff --git a/appengine/swarming/handlers_frontend.py b/appengine/swarming/handlers_frontend.py |
| index 158d74e69cf2a76feb3f490e776fd3193791e53c..30e7f75bde531a758c90bde78ad1445f1c28495a 100644 |
| --- a/appengine/swarming/handlers_frontend.py |
| +++ b/appengine/swarming/handlers_frontend.py |
| @@ -616,6 +616,42 @@ class BaseTaskHandler(auth.AuthenticatingHandler): |
| class TaskHandler(BaseTaskHandler): |
| """Show the full text of a task request and its result.""" |
| + class PinInfo(object): |
| + def __init__(self, pkg, pin): |
| + assert pin is None or pkg.path == pin.path |
| + self.pkg = pkg |
| + self.pin = pin |
| + |
| + |
| + @staticmethod |
| + def pininfos_grouped_by_path(inputs, outputs): |
| + """Returns sorted [(path, [PinInfo, ...])]. |
| + |
| + PinInfo is a namedtuple with two fields 'pkg' and 'pin'. 'pkg' is the |
| + CipdPackage that was specified in the task request. 'pin' is the CipdPackage |
| + that was resolved by the bot at runtime, and contains a full package name as |
| + well as a package instance id. |
| + |
| + If pinning information is unavailable pin is None. |
| + |
| + Used by user_task.html. |
| + """ |
| + packages = inputs.packages |
| + pins = None |
| + if outputs: |
| + pins = outputs.packages |
|
M-A Ruel
2016/08/26 23:19:51
this code assumes the order is the same but this w
iannucci
2016/08/29 22:08:40
sgtm, I considered this, but thought you might pre
|
| + |
| + assert pins is None or len(pins) == len(packages) |
|
M-A Ruel
2016/08/26 23:19:51
This assert should be done at the time the entity
iannucci
2016/08/29 22:08:40
yep, done
|
| + pinned = pins is not None |
| + |
| + retval = collections.defaultdict(list) |
| + for i, pkg in enumerate(packages): |
| + retval[pkg.path].append(TaskHandler.PinInfo( |
| + pkg, pins[i] if pinned else None)) |
| + for pkgs in retval.itervalues(): |
| + pkgs.sort() |
|
M-A Ruel
2016/08/26 23:19:51
see comment in task_request.py
|
| + return sorted(retval.iteritems()) |
| + |
| @auth.autologin |
| @auth.require(acl.is_user) |
| def get(self, task_id): |
| @@ -663,9 +699,24 @@ class TaskHandler(BaseTaskHandler): |
| parent_task = parent_task_future.get_result() |
| children_tasks = [c.get_result() for c in children_tasks_futures] |
| + cipd = None |
| + cipd_pinned = False |
| + if request.properties.cipd_input: |
| + cipd_pinned = result.cipd_pins is not None |
|
M-A Ruel
2016/08/26 23:19:51
do one for input, one for pinned without mixing bo
|
| + cipd = { |
| + 'server': request.properties.cipd_input.server, |
| + 'client_package': TaskHandler.PinInfo( |
| + request.properties.cipd_input.client_package, |
| + result.cipd_pins.client_package if cipd_pinned else None), |
| + 'packages': self.pininfos_grouped_by_path(request.properties.cipd_input, |
| + result.cipd_pins), |
| + } |
| + |
| params = { |
| 'bot': bot_future.get_result() if bot_future else None, |
| 'children_tasks': children_tasks, |
| + 'cipd': cipd, |
| + 'cipd_pinned': cipd_pinned, |
| 'is_admin': acl.is_admin(), |
| 'is_gae_admin': users.is_current_user_admin(), |
| 'is_privileged_user': acl.is_privileged_user(), |
| @@ -679,6 +730,7 @@ class TaskHandler(BaseTaskHandler): |
| 'task': result, |
| 'xsrf_token': self.generate_xsrf_token(), |
| } |
| + |
|
M-A Ruel
2016/08/26 23:19:51
remove
|
| self.response.write(template.render('swarming/user_task.html', params)) |