| 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 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 result['exit_code'] = 1 | 503 result['exit_code'] = 1 |
| 504 except Exception as e: | 504 except Exception as e: |
| 505 # Swallow any exception in the main finally clause. | 505 # Swallow any exception in the main finally clause. |
| 506 if out_dir: | 506 if out_dir: |
| 507 logging.exception('Leaking out_dir %s: %s', out_dir, e) | 507 logging.exception('Leaking out_dir %s: %s', out_dir, e) |
| 508 result['internal_failure'] = str(e) | 508 result['internal_failure'] = str(e) |
| 509 return result | 509 return result |
| 510 | 510 |
| 511 | 511 |
| 512 def run_tha_test( | 512 def run_tha_test( |
| 513 command, isolated_hash, storage, cache, leak_temp_dir, result_json, | 513 command, isolated_hash, storage, isolate_cache, leak_temp_dir, result_json, |
| 514 root_dir, hard_timeout, grace_period, bot_file, extra_args, | 514 root_dir, hard_timeout, grace_period, bot_file, extra_args, |
| 515 install_packages_fn, use_symlinks): | 515 install_packages_fn, use_symlinks): |
| 516 """Runs an executable and records execution metadata. | 516 """Runs an executable and records execution metadata. |
| 517 | 517 |
| 518 Either command or isolated_hash must be specified. | 518 Either command or isolated_hash must be specified. |
| 519 | 519 |
| 520 If isolated_hash is specified, downloads the dependencies in the cache, | 520 If isolated_hash is specified, downloads the dependencies in the cache, |
| 521 hardlinks them into a temporary directory and runs the command specified in | 521 hardlinks them into a temporary directory and runs the command specified in |
| 522 the .isolated. | 522 the .isolated. |
| 523 | 523 |
| 524 A temporary directory is created to hold the output files. The content inside | 524 A temporary directory is created to hold the output files. The content inside |
| 525 this directory will be uploaded back to |storage| packaged as a .isolated | 525 this directory will be uploaded back to |storage| packaged as a .isolated |
| 526 file. | 526 file. |
| 527 | 527 |
| 528 Arguments: | 528 Arguments: |
| 529 command: the command to run, a list of strings. Mutually exclusive with | 529 command: the command to run, a list of strings. Mutually exclusive with |
| 530 isolated_hash. | 530 isolated_hash. |
| 531 isolated_hash: the SHA-1 of the .isolated file that must be retrieved to | 531 isolated_hash: the SHA-1 of the .isolated file that must be retrieved to |
| 532 recreate the tree of files to run the target executable. | 532 recreate the tree of files to run the target executable. |
| 533 The command specified in the .isolated is executed. | 533 The command specified in the .isolated is executed. |
| 534 Mutually exclusive with command argument. | 534 Mutually exclusive with command argument. |
| 535 storage: an isolateserver.Storage object to retrieve remote objects. This | 535 storage: an isolateserver.Storage object to retrieve remote objects. This |
| 536 object has a reference to an isolateserver.StorageApi, which does | 536 object has a reference to an isolateserver.StorageApi, which does |
| 537 the actual I/O. | 537 the actual I/O. |
| 538 cache: an isolateserver.LocalCache to keep from retrieving the same objects | 538 isolate_cache: an isolateserver.LocalCache to keep from retrieving the |
| 539 constantly by caching the objects retrieved. Can be on-disk or | 539 same objects constantly by caching the objects retrieved. |
| 540 in-memory. | 540 Can be on-disk or in-memory. |
| 541 leak_temp_dir: if true, the temporary directory will be deliberately leaked | 541 leak_temp_dir: if true, the temporary directory will be deliberately leaked |
| 542 for later examination. | 542 for later examination. |
| 543 result_json: file path to dump result metadata into. If set, the process | 543 result_json: file path to dump result metadata into. If set, the process |
| 544 exit code is always 0 unless an internal error occurred. | 544 exit code is always 0 unless an internal error occurred. |
| 545 root_dir: path to the directory to use to create the temporary directory. If | 545 root_dir: path to the directory to use to create the temporary directory. If |
| 546 not specified, a random temporary directory is created. | 546 not specified, a random temporary directory is created. |
| 547 hard_timeout: kills the process if it lasts more than this amount of | 547 hard_timeout: kills the process if it lasts more than this amount of |
| 548 seconds. | 548 seconds. |
| 549 grace_period: number of seconds to wait between SIGTERM and SIGKILL. | 549 grace_period: number of seconds to wait between SIGTERM and SIGKILL. |
| 550 extra_args: optional arguments to add to the command stated in the .isolate | 550 extra_args: optional arguments to add to the command stated in the .isolate |
| (...skipping 17 matching lines...) Expand all Loading... |
| 568 'exit_code': None, | 568 'exit_code': None, |
| 569 'had_hard_timeout': False, | 569 'had_hard_timeout': False, |
| 570 'internal_failure': 'Was terminated before completion', | 570 'internal_failure': 'Was terminated before completion', |
| 571 'outputs_ref': None, | 571 'outputs_ref': None, |
| 572 'version': 5, | 572 'version': 5, |
| 573 } | 573 } |
| 574 tools.write_json(result_json, result, dense=True) | 574 tools.write_json(result_json, result, dense=True) |
| 575 | 575 |
| 576 # run_isolated exit code. Depends on if result_json is used or not. | 576 # run_isolated exit code. Depends on if result_json is used or not. |
| 577 result = map_and_run( | 577 result = map_and_run( |
| 578 command, isolated_hash, storage, cache, leak_temp_dir, root_dir, | 578 command, isolated_hash, storage, isolate_cache, leak_temp_dir, root_dir, |
| 579 hard_timeout, grace_period, bot_file, extra_args, install_packages_fn, | 579 hard_timeout, grace_period, bot_file, extra_args, install_packages_fn, |
| 580 use_symlinks) | 580 use_symlinks) |
| 581 logging.info('Result:\n%s', tools.format_json(result, dense=True)) | 581 logging.info('Result:\n%s', tools.format_json(result, dense=True)) |
| 582 | 582 |
| 583 if result_json: | 583 if result_json: |
| 584 # We've found tests to delete 'work' when quitting, causing an exception | 584 # We've found tests to delete 'work' when quitting, causing an exception |
| 585 # here. Try to recreate the directory if necessary. | 585 # here. Try to recreate the directory if necessary. |
| 586 file_path.ensure_tree(os.path.dirname(result_json)) | 586 file_path.ensure_tree(os.path.dirname(result_json)) |
| 587 tools.write_json(result_json, result, dense=True) | 587 tools.write_json(result_json, result, dense=True) |
| 588 # Only return 1 if there was an internal error. | 588 # Only return 1 if there was an internal error. |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 print >> sys.stderr, ex.message | 823 print >> sys.stderr, ex.message |
| 824 return 1 | 824 return 1 |
| 825 | 825 |
| 826 | 826 |
| 827 if __name__ == '__main__': | 827 if __name__ == '__main__': |
| 828 subprocess42.inhibit_os_error_reporting() | 828 subprocess42.inhibit_os_error_reporting() |
| 829 # Ensure that we are always running with the correct encoding. | 829 # Ensure that we are always running with the correct encoding. |
| 830 fix_encoding.fix_encoding() | 830 fix_encoding.fix_encoding() |
| 831 file_path.enable_symlink() | 831 file_path.enable_symlink() |
| 832 sys.exit(main(sys.argv[1:])) | 832 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |