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 by the Apache v2.0 license that can be | 3 # Use of this source code is governed by the Apache v2.0 license that can be |
| 4 # found in the LICENSE file. | 4 # 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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 # Namespace on the isolate server. | 231 # Namespace on the isolate server. |
| 232 namespace = ndb.StringProperty(validator=_validate_namespace, indexed=False) | 232 namespace = ndb.StringProperty(validator=_validate_namespace, indexed=False) |
| 233 | 233 |
| 234 def _pre_put_hook(self): | 234 def _pre_put_hook(self): |
| 235 super(FilesRef, self)._pre_put_hook() | 235 super(FilesRef, self)._pre_put_hook() |
| 236 if not self.isolated or not self.isolatedserver or not self.namespace: | 236 if not self.isolated or not self.isolatedserver or not self.namespace: |
| 237 raise datastore_errors.BadValueError( | 237 raise datastore_errors.BadValueError( |
| 238 'isolated requires server and namespace') | 238 'isolated requires server and namespace') |
| 239 | 239 |
| 240 | 240 |
| 241 class IsolatedOutputsTarget(ndb.Model): | |
| 242 """Defines a target of isolated output.""" | |
| 243 # The hostname of the isolated server to use. | |
| 244 isolatedserver = ndb.StringProperty( | |
| 245 validator=_validate_hostname, indexed=False) | |
| 246 # Namespace on the isolate server. | |
| 247 namespace = ndb.StringProperty(validator=_validate_namespace, indexed=False) | |
| 248 | |
| 249 def _pre_put_hook(self): | |
| 250 super(IsolatedOutputsTarget, self)._pre_put_hook() | |
| 251 if not self.isolatedserver or not self.namespace: | |
| 252 raise datastore_errors.BadValueError( | |
| 253 'isolated outputs target requires server and namespace') | |
| 254 | |
| 255 | |
| 241 class CipdPackage(ndb.Model): | 256 class CipdPackage(ndb.Model): |
| 242 """A CIPD package to install in $CIPD_PATH and $PATH before task execution. | 257 """A CIPD package to install in $CIPD_PATH and $PATH before task execution. |
| 243 | 258 |
| 244 A part of TaskProperties. | 259 A part of TaskProperties. |
| 245 """ | 260 """ |
| 246 package_name = ndb.StringProperty( | 261 package_name = ndb.StringProperty( |
| 247 indexed=False, validator=_validate_package_name) | 262 indexed=False, validator=_validate_package_name) |
| 248 version = ndb.StringProperty( | 263 version = ndb.StringProperty( |
| 249 indexed=False, validator=_validate_package_version) | 264 indexed=False, validator=_validate_package_version) |
| 250 | 265 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 277 commands = datastore_utils.DeterministicJsonProperty( | 292 commands = datastore_utils.DeterministicJsonProperty( |
| 278 json_type=list, indexed=False) | 293 json_type=list, indexed=False) |
| 279 # Command to run. This is only relevant when self._inputs_ref is None. This is | 294 # Command to run. This is only relevant when self._inputs_ref is None. This is |
| 280 # what is called 'raw commands', in the sense that no inputs files are | 295 # what is called 'raw commands', in the sense that no inputs files are |
| 281 # declared. | 296 # declared. |
| 282 command = ndb.StringProperty(repeated=True, indexed=False) | 297 command = ndb.StringProperty(repeated=True, indexed=False) |
| 283 | 298 |
| 284 # File inputs of the task. Only inputs_ref or command&data can be specified. | 299 # File inputs of the task. Only inputs_ref or command&data can be specified. |
| 285 inputs_ref = ndb.LocalStructuredProperty(FilesRef) | 300 inputs_ref = ndb.LocalStructuredProperty(FilesRef) |
| 286 | 301 |
| 302 # Isolate output settings. Mutually exclusive with inputs_ref. | |
| 303 # If inputs_ref is not None, its server and namespace must be used for output. | |
| 304 outputs_target = ndb.LocalStructuredProperty(IsolatedOutputsTarget) | |
|
M-A Ruel
2016/05/03 14:01:23
Argh, in retrospect maybe I should have used inste
nodir
2016/05/03 16:29:30
No
M-A Ruel
2016/05/05 11:52:10
Ok I thought about this a lot. I think it's a bad
nodir
2016/05/10 18:17:39
Done, updated CL description.
| |
| 305 | |
| 287 # A list of CIPD packages to install $CIPD_PATH and $PATH before task | 306 # A list of CIPD packages to install $CIPD_PATH and $PATH before task |
| 288 # execution. | 307 # execution. |
| 289 packages = ndb.LocalStructuredProperty(CipdPackage, repeated=True) | 308 packages = ndb.LocalStructuredProperty(CipdPackage, repeated=True) |
| 290 | 309 |
| 291 # Filter to use to determine the required properties on the bot to run on. For | 310 # Filter to use to determine the required properties on the bot to run on. For |
| 292 # example, Windows or hostname. Encoded as json. Optional but highly | 311 # example, Windows or hostname. Encoded as json. Optional but highly |
| 293 # recommended. | 312 # recommended. |
| 294 dimensions = datastore_utils.DeterministicJsonProperty( | 313 dimensions = datastore_utils.DeterministicJsonProperty( |
| 295 validator=_validate_dimensions, json_type=dict, indexed=False) | 314 validator=_validate_dimensions, json_type=dict, indexed=False) |
| 296 | 315 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 if self.commands: | 381 if self.commands: |
| 363 raise datastore_errors.BadValueError( | 382 raise datastore_errors.BadValueError( |
| 364 'commands is not supported anymore') | 383 'commands is not supported anymore') |
| 365 if not self.is_terminate: | 384 if not self.is_terminate: |
| 366 if bool(self.command) == bool(self.inputs_ref): | 385 if bool(self.command) == bool(self.inputs_ref): |
| 367 raise datastore_errors.BadValueError('use one of command or inputs_ref') | 386 raise datastore_errors.BadValueError('use one of command or inputs_ref') |
| 368 if self.extra_args and not self.inputs_ref: | 387 if self.extra_args and not self.inputs_ref: |
| 369 raise datastore_errors.BadValueError('extra_args require inputs_ref') | 388 raise datastore_errors.BadValueError('extra_args require inputs_ref') |
| 370 if self.inputs_ref: | 389 if self.inputs_ref: |
| 371 self.inputs_ref._pre_put_hook() | 390 self.inputs_ref._pre_put_hook() |
| 391 if self.outputs_target: | |
| 392 raise datastore_errors.BadValueError( | |
| 393 'do not specify outputs_target with inputs_ref') | |
| 394 elif self.outputs_target: | |
| 395 self.outputs_target._pre_put_hook() | |
| 372 | 396 |
| 373 package_names = set() | 397 package_names = set() |
| 374 for p in self.packages: | 398 for p in self.packages: |
| 375 p._pre_put_hook() | 399 p._pre_put_hook() |
| 376 if p.package_name in package_names: | 400 if p.package_name in package_names: |
| 377 raise datastore_errors.BadValueError( | 401 raise datastore_errors.BadValueError( |
| 378 'package %s is specified more than once' % p.package_name) | 402 'package %s is specified more than once' % p.package_name) |
| 379 package_names.add(p.package_name) | 403 package_names.add(p.package_name) |
| 380 self.packages.sort(key=lambda p: p.package_name) | 404 self.packages.sort(key=lambda p: p.package_name) |
| 381 | 405 |
| 382 if self.idempotent: | 406 if self.idempotent: |
| 383 pinned = lambda p: cipd.is_pinned_version(p.version) | 407 pinned = lambda p: cipd.is_pinned_version(p.version) |
| 384 if self.packages and any(not pinned(p) for p in self.packages): | 408 if self.packages and any(not pinned(p) for p in self.packages): |
| 385 raise datastore_errors.BadValueError( | 409 raise datastore_errors.BadValueError( |
| 386 'an idempotent task cannot have unpinned packages; ' | 410 'an idempotent task cannot have unpinned packages; ' |
| 387 'use instance IDs or tags as package versions') | 411 'use instance IDs or tags as package versions') |
| 388 | 412 |
| 389 | 413 |
| 390 | |
| 391 class TaskRequest(ndb.Model): | 414 class TaskRequest(ndb.Model): |
| 392 """Contains a user request. | 415 """Contains a user request. |
| 393 | 416 |
| 394 Key id is a decreasing integer based on time since utils.EPOCH plus some | 417 Key id is a decreasing integer based on time since utils.EPOCH plus some |
| 395 randomness on lower order bits. See _new_request_key() for the complete gory | 418 randomness on lower order bits. See _new_request_key() for the complete gory |
| 396 details. | 419 details. |
| 397 | 420 |
| 398 There is also "old style keys" which inherit from a fake root entity | 421 There is also "old style keys" which inherit from a fake root entity |
| 399 TaskRequestShard. | 422 TaskRequestShard. |
| 400 TODO(maruel): Remove support 2015-10-01 once entities are deleted. | 423 TODO(maruel): Remove support 2015-10-01 once entities are deleted. |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 702 _put_request(request) | 725 _put_request(request) |
| 703 return request | 726 return request |
| 704 | 727 |
| 705 | 728 |
| 706 def validate_priority(priority): | 729 def validate_priority(priority): |
| 707 """Throws ValueError if priority is not a valid value.""" | 730 """Throws ValueError if priority is not a valid value.""" |
| 708 if 0 > priority or MAXIMUM_PRIORITY < priority: | 731 if 0 > priority or MAXIMUM_PRIORITY < priority: |
| 709 raise datastore_errors.BadValueError( | 732 raise datastore_errors.BadValueError( |
| 710 'priority (%d) must be between 0 and %d (inclusive)' % | 733 'priority (%d) must be between 0 and %d (inclusive)' % |
| 711 (priority, MAXIMUM_PRIORITY)) | 734 (priority, MAXIMUM_PRIORITY)) |
| OLD | NEW |