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)) |