Chromium Code Reviews| 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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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)) |
| OLD | NEW |