OLD | NEW |
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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 p._pre_put_hook() | 326 p._pre_put_hook() |
327 if not p.path: | 327 if not p.path: |
328 raise datastore_errors.BadValueError( | 328 raise datastore_errors.BadValueError( |
329 'package %s:%s: path is required' % (p.package_name, p.version)) | 329 'package %s:%s: path is required' % (p.package_name, p.version)) |
330 if p.package_name in package_names: | 330 if p.package_name in package_names: |
331 raise datastore_errors.BadValueError( | 331 raise datastore_errors.BadValueError( |
332 'package %s is specified more than once' % p.package_name) | 332 'package %s is specified more than once' % p.package_name) |
333 package_names.add(p.package_name) | 333 package_names.add(p.package_name) |
334 self.packages.sort(key=lambda p: p.package_name) | 334 self.packages.sort(key=lambda p: p.package_name) |
335 | 335 |
336 def packages_grouped_by_path(self): | 336 def packages_grouped_by_path(self, pins): |
337 """Returns sorted [(path), [package]) list. Used by user_task.html.""" | 337 """Returns sorted [(path, [PinInfo, ...])]. |
| 338 |
| 339 PinInfo is a namedtuple with two fields 'pkg' and 'pin'. 'pkg' is the |
| 340 CipdPackage that was specified in the task request. 'pin' is the CipdPackage |
| 341 that was resolved by the bot at runtime, and contains a full package name as |
| 342 well as a package instance id. |
| 343 |
| 344 If pinning information is unavailable, or if 'pkg' already specifies a full |
| 345 pin, 'pin' is None. If 'version' or 'package_name' are the same between |
| 346 'pkg' and 'pin', then the field in 'pin' is None. |
| 347 |
| 348 Args: |
| 349 pins - a list of CipdPackages which represent the pin counterparts of |
| 350 self.packages. |
| 351 |
| 352 Used by user_task.html. |
| 353 """ |
| 354 assert pins is None or len(pins) == len(self.packages) |
| 355 PinInfo = collections.namedtuple('PinInfo', ['pkg', 'pin']) |
| 356 pinned = pins is not None |
| 357 |
338 packages = collections.defaultdict(list) | 358 packages = collections.defaultdict(list) |
339 for p in self.packages: | 359 for i, pkg in enumerate(self.packages): |
340 packages[p.path].append(p) | 360 pin = None |
| 361 if pinned: |
| 362 pin = pins[i] |
| 363 if pkg.package_name == pin.package_name: |
| 364 pin.package_name = None |
| 365 if pkg.version == pin.version: |
| 366 pin.version = None |
| 367 if pin.package_name is None and pin.version is None: |
| 368 pin = None |
| 369 packages[pkg.path].append(PinInfo(pkg, pin)) |
341 for pkgs in packages.itervalues(): | 370 for pkgs in packages.itervalues(): |
342 pkgs.sort() | 371 pkgs.sort() |
343 return sorted(packages.iteritems()) | 372 return sorted(packages.iteritems()) |
344 | 373 |
345 | 374 |
346 class TaskProperties(ndb.Model): | 375 class TaskProperties(ndb.Model): |
347 """Defines all the properties of a task to be run on the Swarming | 376 """Defines all the properties of a task to be run on the Swarming |
348 infrastructure. | 377 infrastructure. |
349 | 378 |
350 This entity is not saved in the DB as a standalone entity, instead it is | 379 This entity is not saved in the DB as a standalone entity, instead it is |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 init_new_request(request, allow_high_priority) | 820 init_new_request(request, allow_high_priority) |
792 return request | 821 return request |
793 | 822 |
794 | 823 |
795 def validate_priority(priority): | 824 def validate_priority(priority): |
796 """Throws ValueError if priority is not a valid value.""" | 825 """Throws ValueError if priority is not a valid value.""" |
797 if 0 > priority or MAXIMUM_PRIORITY < priority: | 826 if 0 > priority or MAXIMUM_PRIORITY < priority: |
798 raise datastore_errors.BadValueError( | 827 raise datastore_errors.BadValueError( |
799 'priority (%d) must be between 0 and %d (inclusive)' % | 828 'priority (%d) must be between 0 and %d (inclusive)' % |
800 (priority, MAXIMUM_PRIORITY)) | 829 (priority, MAXIMUM_PRIORITY)) |
OLD | NEW |