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 |