OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2012 The LUCI Authors. All rights reserved. | 2 # Copyright 2012 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 """Runs a command with optional isolated input/output. | 6 """Runs a command with optional isolated input/output. |
7 | 7 |
8 Despite name "run_isolated", can run a generic non-isolated command specified as | 8 Despite name "run_isolated", can run a generic non-isolated command specified as |
9 args. | 9 args. |
10 | 10 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 else: | 137 else: |
138 raise ValueError( | 138 raise ValueError( |
139 'change_tree_read_only(%s, %s): Unknown flag %s' % | 139 'change_tree_read_only(%s, %s): Unknown flag %s' % |
140 (rootdir, read_only, read_only)) | 140 (rootdir, read_only, read_only)) |
141 | 141 |
142 | 142 |
143 def process_command(command, out_dir): | 143 def process_command(command, out_dir): |
144 """Replaces isolated specific variables in a command line.""" | 144 """Replaces isolated specific variables in a command line.""" |
145 def fix(arg): | 145 def fix(arg): |
146 if ISOLATED_OUTDIR_PARAMETER in arg: | 146 if ISOLATED_OUTDIR_PARAMETER in arg: |
| 147 assert out_dir |
147 arg = arg.replace(ISOLATED_OUTDIR_PARAMETER, out_dir) | 148 arg = arg.replace(ISOLATED_OUTDIR_PARAMETER, out_dir) |
148 # Replace slashes only if ISOLATED_OUTDIR_PARAMETER is present | 149 # Replace slashes only if ISOLATED_OUTDIR_PARAMETER is present |
149 # because of arguments like '${ISOLATED_OUTDIR}/foo/bar' | 150 # because of arguments like '${ISOLATED_OUTDIR}/foo/bar' |
150 arg = arg.replace('/', os.sep) | 151 arg = arg.replace('/', os.sep) |
151 return arg | 152 return arg |
152 | 153 |
153 return [fix(arg) for arg in command] | 154 return [fix(arg) for arg in command] |
154 | 155 |
155 | 156 |
156 def run_command(command, cwd, tmp_dir, hard_timeout, grace_period): | 157 def run_command(command, cwd, tmp_dir, hard_timeout, grace_period): |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 'outputs_ref': None, | 343 'outputs_ref': None, |
343 'version': 3, | 344 'version': 3, |
344 } | 345 } |
345 if root_dir: | 346 if root_dir: |
346 file_path.ensure_tree(root_dir, 0700) | 347 file_path.ensure_tree(root_dir, 0700) |
347 prefix = u'' | 348 prefix = u'' |
348 else: | 349 else: |
349 root_dir = os.path.dirname(cache.cache_dir) if cache.cache_dir else None | 350 root_dir = os.path.dirname(cache.cache_dir) if cache.cache_dir else None |
350 prefix = u'isolated_' | 351 prefix = u'isolated_' |
351 run_dir = make_temp_dir(prefix + u'run', root_dir) | 352 run_dir = make_temp_dir(prefix + u'run', root_dir) |
352 out_dir = make_temp_dir(prefix + u'out', root_dir) | 353 out_dir = make_temp_dir(prefix + u'out', root_dir) if storage else None |
353 tmp_dir = make_temp_dir(prefix + u'tmp', root_dir) | 354 tmp_dir = make_temp_dir(prefix + u'tmp', root_dir) |
354 cwd = run_dir | 355 cwd = run_dir |
355 | 356 |
356 try: | 357 try: |
357 if isolated_hash: | 358 if isolated_hash: |
358 bundle, result['stats']['download'] = fetch_and_measure( | 359 bundle, result['stats']['download'] = fetch_and_measure( |
359 isolated_hash=isolated_hash, | 360 isolated_hash=isolated_hash, |
360 storage=storage, | 361 storage=storage, |
361 cache=cache, | 362 cache=cache, |
362 outdir=run_dir) | 363 outdir=run_dir) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 if not success: | 425 if not success: |
425 print >> sys.stderr, ( | 426 print >> sys.stderr, ( |
426 'Failed to delete the temporary directory, forcibly failing\n' | 427 'Failed to delete the temporary directory, forcibly failing\n' |
427 'the task because of it. No zombie process can outlive a\n' | 428 'the task because of it. No zombie process can outlive a\n' |
428 'successful task run and still be marked as successful.\n' | 429 'successful task run and still be marked as successful.\n' |
429 'Fix your stuff.') | 430 'Fix your stuff.') |
430 if result['exit_code'] == 0: | 431 if result['exit_code'] == 0: |
431 result['exit_code'] = 1 | 432 result['exit_code'] = 1 |
432 | 433 |
433 # This deletes out_dir if leak_temp_dir is not set. | 434 # This deletes out_dir if leak_temp_dir is not set. |
434 result['outputs_ref'], success, result['stats']['upload'] = ( | 435 if out_dir: |
435 delete_and_upload(storage, out_dir, leak_temp_dir)) | 436 result['outputs_ref'], success, result['stats']['upload'] = ( |
| 437 delete_and_upload(storage, out_dir, leak_temp_dir)) |
436 if not success and result['exit_code'] == 0: | 438 if not success and result['exit_code'] == 0: |
437 result['exit_code'] = 1 | 439 result['exit_code'] = 1 |
438 except Exception as e: | 440 except Exception as e: |
439 # Swallow any exception in the main finally clause. | 441 # Swallow any exception in the main finally clause. |
440 logging.exception('Leaking out_dir %s: %s', out_dir, e) | 442 if out_dir: |
| 443 logging.exception('Leaking out_dir %s: %s', out_dir, e) |
441 result['internal_failure'] = str(e) | 444 result['internal_failure'] = str(e) |
442 return result | 445 return result |
443 | 446 |
444 | 447 |
445 def run_tha_test( | 448 def run_tha_test( |
446 command, isolated_hash, storage, cache, leak_temp_dir, result_json, | 449 command, isolated_hash, storage, cache, leak_temp_dir, result_json, |
447 root_dir, hard_timeout, grace_period, extra_args): | 450 root_dir, hard_timeout, grace_period, extra_args): |
448 """Runs an executable and records execution metadata. | 451 """Runs an executable and records execution metadata. |
449 | 452 |
450 Either command or isolated_hash must be specified. | 453 Either command or isolated_hash must be specified. |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 return run_tha_test( | 619 return run_tha_test( |
617 command, options.isolated, None, cache, options.leak_temp_dir, | 620 command, options.isolated, None, cache, options.leak_temp_dir, |
618 options.json, options.root_dir, options.hard_timeout, | 621 options.json, options.root_dir, options.hard_timeout, |
619 options.grace_period, args) | 622 options.grace_period, args) |
620 | 623 |
621 | 624 |
622 if __name__ == '__main__': | 625 if __name__ == '__main__': |
623 # Ensure that we are always running with the correct encoding. | 626 # Ensure that we are always running with the correct encoding. |
624 fix_encoding.fix_encoding() | 627 fix_encoding.fix_encoding() |
625 sys.exit(main(sys.argv[1:])) | 628 sys.exit(main(sys.argv[1:])) |
OLD | NEW |