| 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 |