Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: appengine/swarming/server/task_request.py

Issue 2267363004: Add CIPD pin reporting to swarming. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: comments and some tests Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # coding: utf-8 1 # coding: utf-8
2 # Copyright 2014 The LUCI Authors. All rights reserved. 2 # Copyright 2014 The LUCI Authors. All rights reserved.
3 # Use of this source code is governed under the Apache License, Version 2.0 3 # Use of this source code is governed under the Apache License, Version 2.0
4 # that can be found in the LICENSE file. 4 # that can be found in the LICENSE file.
5 5
6 """Tasks definition. 6 """Tasks definition.
7 7
8 Each user request creates a new TaskRequest. The TaskRequest instance saves the 8 Each user request creates a new TaskRequest. The TaskRequest instance saves the
9 metadata of the request, e.g. who requested it, when why, etc. It links to the 9 metadata of the request, e.g. who requested it, when why, etc. It links to the
10 actual data of the request in a TaskProperties. The TaskProperties represents 10 actual data of the request in a TaskProperties. The TaskProperties represents
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 return '%s:%s' % (self.package_name, self.version) 285 return '%s:%s' % (self.package_name, self.version)
286 286
287 def _pre_put_hook(self): 287 def _pre_put_hook(self):
288 super(CipdPackage, self)._pre_put_hook() 288 super(CipdPackage, self)._pre_put_hook()
289 if not self.package_name: 289 if not self.package_name:
290 raise datastore_errors.BadValueError('CIPD package name is required') 290 raise datastore_errors.BadValueError('CIPD package name is required')
291 if not self.version: 291 if not self.version:
292 raise datastore_errors.BadValueError('CIPD package version is required') 292 raise datastore_errors.BadValueError('CIPD package version is required')
293 293
294 294
295 PinInfo = collections.namedtuple('PinInfo', ['pkg', 'pin'])
296
297
295 class CipdInput(ndb.Model): 298 class CipdInput(ndb.Model):
296 """Specifies which CIPD client and packages to install, from which server. 299 """Specifies which CIPD client and packages to install, from which server.
297 300
298 A part of TaskProperties. 301 A part of TaskProperties.
299 """ 302 """
300 # URL of the CIPD server. Must start with "https://" or "http://". 303 # URL of the CIPD server. Must start with "https://" or "http://".
301 server = ndb.StringProperty(indexed=False, validator=_validate_url) 304 server = ndb.StringProperty(indexed=False, validator=_validate_url)
302 305
303 # CIPD package of CIPD client to use. 306 # CIPD package of CIPD client to use.
304 # client_package.version is required. 307 # client_package.version is required.
(...skipping 21 matching lines...) Expand all
326 p._pre_put_hook() 329 p._pre_put_hook()
327 if not p.path: 330 if not p.path:
328 raise datastore_errors.BadValueError( 331 raise datastore_errors.BadValueError(
329 'package %s:%s: path is required' % (p.package_name, p.version)) 332 'package %s:%s: path is required' % (p.package_name, p.version))
330 if p.package_name in package_names: 333 if p.package_name in package_names:
331 raise datastore_errors.BadValueError( 334 raise datastore_errors.BadValueError(
332 'package %s is specified more than once' % p.package_name) 335 'package %s is specified more than once' % p.package_name)
333 package_names.add(p.package_name) 336 package_names.add(p.package_name)
334 self.packages.sort(key=lambda p: p.package_name) 337 self.packages.sort(key=lambda p: p.package_name)
335 338
336 def packages_grouped_by_path(self): 339 def packages_grouped_by_path(self, pins):
337 """Returns sorted [(path), [package]) list. Used by user_task.html.""" 340 """Returns sorted [(path, [PinInfo, ...])].
341
342 PinInfo is a namedtuple with two fields 'pkg' and 'pin'. 'pkg' is the
343 CipdPackage that was specified in the task request. 'pin' is the CipdPackage
344 that was resolved by the bot at runtime, and contains a full package name as
M-A Ruel 2016/08/24 19:34:07 This is really part of the result, not the request
iannucci 2016/08/25 00:14:12 On 2016/08/24 at 19:34:07, M-A Ruel wrote: > This
345 well as a package instance id.
346
347 If pinning information is unavailable, or if 'pkg' already specifies a full
348 pin, 'pin' is None. If 'version' or 'package_name' are the same between
349 'pkg' and 'pin', then the field in 'pin' is None.
350
351 Args:
352 pins - a list of CipdPackages which represent the pin counterparts of
353 self.packages.
354
355 Used by user_task.html.
356 """
357 assert pins is None or len(pins) == len(self.packages)
358 pinned = pins is not None
359
338 packages = collections.defaultdict(list) 360 packages = collections.defaultdict(list)
339 for p in self.packages: 361 for i, pkg in enumerate(self.packages):
340 packages[p.path].append(p) 362 pin = None
363 if pinned:
364 pin = pins[i]
365 if pkg.package_name == pin.package_name:
366 pin.package_name = None
367 if pkg.version == pin.version:
368 pin.version = None
369 if pin.package_name is None and pin.version is None:
370 pin = None
371 packages[pkg.path].append(PinInfo(pkg, pin))
341 for pkgs in packages.itervalues(): 372 for pkgs in packages.itervalues():
342 pkgs.sort() 373 pkgs.sort(key=lambda x: (
374 x.pkg.package_name, x.pkg.version,
375 getattr(x.pin, 'package_name', None), getattr(x.pin, 'version', None)))
343 return sorted(packages.iteritems()) 376 return sorted(packages.iteritems())
344 377
345 378
346 class TaskProperties(ndb.Model): 379 class TaskProperties(ndb.Model):
347 """Defines all the properties of a task to be run on the Swarming 380 """Defines all the properties of a task to be run on the Swarming
348 infrastructure. 381 infrastructure.
349 382
350 This entity is not saved in the DB as a standalone entity, instead it is 383 This entity is not saved in the DB as a standalone entity, instead it is
351 embedded in a TaskRequest. 384 embedded in a TaskRequest.
352 385
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 init_new_request(request, allow_high_priority) 824 init_new_request(request, allow_high_priority)
792 return request 825 return request
793 826
794 827
795 def validate_priority(priority): 828 def validate_priority(priority):
796 """Throws ValueError if priority is not a valid value.""" 829 """Throws ValueError if priority is not a valid value."""
797 if 0 > priority or MAXIMUM_PRIORITY < priority: 830 if 0 > priority or MAXIMUM_PRIORITY < priority:
798 raise datastore_errors.BadValueError( 831 raise datastore_errors.BadValueError(
799 'priority (%d) must be between 0 and %d (inclusive)' % 832 'priority (%d) must be between 0 and %d (inclusive)' %
800 (priority, MAXIMUM_PRIORITY)) 833 (priority, MAXIMUM_PRIORITY))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698