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 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 """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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 if not success: | 424 if not success: |
424 print >> sys.stderr, ( | 425 print >> sys.stderr, ( |
425 'Failed to delete the temporary directory, forcibly failing\n' | 426 'Failed to delete the temporary directory, forcibly failing\n' |
426 'the task because of it. No zombie process can outlive a\n' | 427 'the task because of it. No zombie process can outlive a\n' |
427 'successful task run and still be marked as successful.\n' | 428 'successful task run and still be marked as successful.\n' |
428 'Fix your stuff.') | 429 'Fix your stuff.') |
429 if result['exit_code'] == 0: | 430 if result['exit_code'] == 0: |
430 result['exit_code'] = 1 | 431 result['exit_code'] = 1 |
431 | 432 |
432 # This deletes out_dir if leak_temp_dir is not set. | 433 # This deletes out_dir if leak_temp_dir is not set. |
433 result['outputs_ref'], success, result['stats']['upload'] = ( | 434 if out_dir: |
434 delete_and_upload(storage, out_dir, leak_temp_dir)) | 435 result['outputs_ref'], success, result['stats']['upload'] = ( |
| 436 delete_and_upload(storage, out_dir, leak_temp_dir)) |
435 if not success and result['exit_code'] == 0: | 437 if not success and result['exit_code'] == 0: |
436 result['exit_code'] = 1 | 438 result['exit_code'] = 1 |
437 except Exception as e: | 439 except Exception as e: |
438 # Swallow any exception in the main finally clause. | 440 # Swallow any exception in the main finally clause. |
439 logging.exception('Leaking out_dir %s: %s', out_dir, e) | 441 if out_dir: |
| 442 logging.exception('Leaking out_dir %s: %s', out_dir, e) |
440 result['internal_failure'] = str(e) | 443 result['internal_failure'] = str(e) |
441 return result | 444 return result |
442 | 445 |
443 | 446 |
444 def run_tha_test( | 447 def run_tha_test( |
445 command, isolated_hash, storage, cache, leak_temp_dir, result_json, | 448 command, isolated_hash, storage, cache, leak_temp_dir, result_json, |
446 root_dir, hard_timeout, grace_period, extra_args): | 449 root_dir, hard_timeout, grace_period, extra_args): |
447 """Runs an executable and records execution metadata. | 450 """Runs an executable and records execution metadata. |
448 | 451 |
449 Either command or isolated_hash must be specified. | 452 Either command or isolated_hash must be specified. |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 return run_tha_test( | 618 return run_tha_test( |
616 command, options.isolated, None, cache, options.leak_temp_dir, | 619 command, options.isolated, None, cache, options.leak_temp_dir, |
617 options.json, options.root_dir, options.hard_timeout, | 620 options.json, options.root_dir, options.hard_timeout, |
618 options.grace_period, args) | 621 options.grace_period, args) |
619 | 622 |
620 | 623 |
621 if __name__ == '__main__': | 624 if __name__ == '__main__': |
622 # Ensure that we are always running with the correct encoding. | 625 # Ensure that we are always running with the correct encoding. |
623 fix_encoding.fix_encoding() | 626 fix_encoding.fix_encoding() |
624 sys.exit(main(sys.argv[1:])) | 627 sys.exit(main(sys.argv[1:])) |
OLD | NEW |