Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: appengine/swarming/swarming_bot/bot_code/task_runner.py

Issue 2069903003: swarming: custom cipd package paths (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@cipd-win
Patch Set: test "." and None custom path Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2013 The LUCI Authors. All rights reserved. 1 # Copyright 2013 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0 2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file. 3 # that can be found in the LICENSE file.
4 4
5 """Runs a Swarming task. 5 """Runs a Swarming task.
6 6
7 Downloads all the necessary files to run the task, executes the command and 7 Downloads all the necessary files to run the task, executes the command and
8 streams results back to the Swarming server. 8 streams results back to the Swarming server.
9 9
10 The process exit code is 0 when the task was executed, even if the task itself 10 The process exit code is 0 when the task was executed, even if the task itself
11 failed. If there's any failure in the setup or teardown, like invalid packet 11 failed. If there's any failure in the setup or teardown, like invalid packet
12 response, failure to contact the server, etc, a non zero exit code is used. It's 12 response, failure to contact the server, etc, a non zero exit code is used. It's
13 up to the calling process (bot_main.py) to signal that there was an internal 13 up to the calling process (bot_main.py) to signal that there was an internal
14 failure and to cancel this task run and ask the server to retry it. 14 failure and to cancel this task run and ask the server to retry it.
15 """ 15 """
16 16
17 import base64 17 import base64
18 import json 18 import json
19 import logging 19 import logging
20 import optparse 20 import optparse
21 import os 21 import os
22 import signal 22 import signal
23 import sys 23 import sys
24 import time 24 import time
25 25
26 from utils import file_path
26 from utils import net 27 from utils import net
27 from utils import on_error 28 from utils import on_error
28 from utils import subprocess42 29 from utils import subprocess42
29 from utils import zip_package 30 from utils import zip_package
30 31
31 import bot_auth 32 import bot_auth
32 import file_reader 33 import file_reader
33 34
34 35
35 # Path to this file or the zip containing this file. 36 # Path to this file or the zip containing this file.
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 75
75 def get_run_isolated(): 76 def get_run_isolated():
76 """Returns the path to itself to run run_isolated. 77 """Returns the path to itself to run run_isolated.
77 78
78 Mocked in test to point to the real run_isolated.py script. 79 Mocked in test to point to the real run_isolated.py script.
79 """ 80 """
80 return [sys.executable, THIS_FILE, 'run_isolated'] 81 return [sys.executable, THIS_FILE, 'run_isolated']
81 82
82 83
83 def get_isolated_cmd( 84 def get_isolated_cmd(
84 work_dir, task_details, isolated_result, min_free_space, bot_file): 85 work_dir, task_details, isolated_result, bot_file, package_list,
86 min_free_space):
85 """Returns the command to call run_isolated. Mocked in tests.""" 87 """Returns the command to call run_isolated. Mocked in tests."""
86 assert (bool(task_details.command) != 88 assert (bool(task_details.command) !=
87 bool(task_details.isolated and task_details.isolated.get('input'))) 89 bool(task_details.isolated and task_details.isolated.get('input')))
88 bot_dir = os.path.dirname(work_dir) 90 bot_dir = os.path.dirname(work_dir)
89 if os.path.isfile(isolated_result): 91 if os.path.isfile(isolated_result):
90 os.remove(isolated_result) 92 os.remove(isolated_result)
91 cmd = get_run_isolated() 93 cmd = get_run_isolated()
92 94
93 if task_details.isolated: 95 if task_details.isolated:
94 cmd.extend( 96 cmd.extend(
95 [ 97 [
96 '-I', task_details.isolated['server'].encode('utf-8'), 98 '-I', task_details.isolated['server'].encode('utf-8'),
97 '--namespace', task_details.isolated['namespace'].encode('utf-8'), 99 '--namespace', task_details.isolated['namespace'].encode('utf-8'),
98 ]) 100 ])
99 isolated_input = task_details.isolated.get('input') 101 isolated_input = task_details.isolated.get('input')
100 if isolated_input: 102 if isolated_input:
101 cmd.extend( 103 cmd.extend(
102 [ 104 [
103 '--isolated', isolated_input, 105 '--isolated', isolated_input,
104 ]) 106 ])
105 107
106 if task_details.cipd_input and task_details.cipd_input.get('packages'): 108 if task_details.cipd_input and task_details.cipd_input.get('packages'):
107 to_pkg = lambda p: '%s:%s' % (p['package_name'], p['version']) 109 package_json = {
110 # Package JSON object format matches.
M-A Ruel 2016/06/15 17:28:27 Can't parse this sentence
nodir 2016/06/15 17:53:42 Done.
111 'packages': task_details.cipd_input['packages'],
112 }
113 with open(package_list, 'w') as f:
M-A Ruel 2016/06/15 17:28:27 'wb'
nodir 2016/06/15 17:53:42 Done.
114 json.dump(package_json, f)
108 cmd.extend( 115 cmd.extend(
109 [ 116 [
110 '--cipd-cache', os.path.join(bot_dir, 'cipd_cache'), 117 '--cipd-cache', os.path.join(bot_dir, 'cipd_cache'),
111 '--cipd-client-package', 118 '--cipd-client-package',
112 to_pkg(task_details.cipd_input.get('client_package')), 119 task_details.cipd_input['client_package']['package_name'],
120 '--cipd-client-version',
121 task_details.cipd_input['client_package']['version'],
122 '--cipd-package-list', package_list,
113 '--cipd-server', task_details.cipd_input.get('server'), 123 '--cipd-server', task_details.cipd_input.get('server'),
114 ]) 124 ])
115 for p in task_details.cipd_input['packages']:
116 cmd.extend(['--cipd-package', to_pkg(p)])
117 125
118 cmd.extend( 126 cmd.extend(
119 [ 127 [
120 '--json', isolated_result, 128 '--json', isolated_result,
121 '--log-file', os.path.join(bot_dir, 'logs', 'run_isolated.log'), 129 '--log-file', os.path.join(bot_dir, 'logs', 'run_isolated.log'),
122 '--cache', os.path.join(bot_dir, 'isolated_cache'), 130 '--cache', os.path.join(bot_dir, 'isolated_cache'),
123 '--root-dir', os.path.join(work_dir, 'isolated'), 131 '--root-dir', os.path.join(work_dir, 'isolated'),
124 ]) 132 ])
125 if min_free_space: 133 if min_free_space:
126 cmd.extend(('--min-free-space', str(min_free_space))) 134 cmd.extend(('--min-free-space', str(min_free_space)))
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 # Signal the command is about to be started. 370 # Signal the command is about to be started.
363 last_packet = start = now = monotonic_time() 371 last_packet = start = now = monotonic_time()
364 params = { 372 params = {
365 'cost_usd': cost_usd_hour * (now - task_start) / 60. / 60., 373 'cost_usd': cost_usd_hour * (now - task_start) / 60. / 60.,
366 'id': task_details.bot_id, 374 'id': task_details.bot_id,
367 'task_id': task_details.task_id, 375 'task_id': task_details.task_id,
368 } 376 }
369 post_update(swarming_server, headers_cb(), params, None, '', 0) 377 post_update(swarming_server, headers_cb(), params, None, '', 0)
370 378
371 isolated_result = os.path.join(work_dir, 'isolated_result.json') 379 isolated_result = os.path.join(work_dir, 'isolated_result.json')
380 package_list = os.path.join(work_dir, 'package_list.json')
372 cmd = get_isolated_cmd( 381 cmd = get_isolated_cmd(
373 work_dir, task_details, isolated_result, min_free_space, bot_file) 382 work_dir, task_details, isolated_result, bot_file, package_list,
383 min_free_space)
374 # Hard timeout enforcement is deferred to run_isolated. Grace is doubled to 384 # Hard timeout enforcement is deferred to run_isolated. Grace is doubled to
375 # give one 'grace_period' slot to the child process and one slot to upload 385 # give one 'grace_period' slot to the child process and one slot to upload
376 # the results back. 386 # the results back.
377 task_details.hard_timeout = 0 387 task_details.hard_timeout = 0
378 if task_details.grace_period: 388 if task_details.grace_period:
379 task_details.grace_period *= 2 389 task_details.grace_period *= 2
380 390
381 try: 391 try:
382 # TODO(maruel): Support both channels independently and display stderr in 392 # TODO(maruel): Support both channels independently and display stderr in
383 # red. 393 # red.
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 swarming_server, headers_cb(), params, exit_code, 567 swarming_server, headers_cb(), params, exit_code,
558 stdout, output_chunk_start) 568 stdout, output_chunk_start)
559 return { 569 return {
560 u'exit_code': exit_code, 570 u'exit_code': exit_code,
561 u'hard_timeout': had_hard_timeout, 571 u'hard_timeout': had_hard_timeout,
562 u'io_timeout': had_io_timeout, 572 u'io_timeout': had_io_timeout,
563 u'must_signal_internal_failure': must_signal_internal_failure, 573 u'must_signal_internal_failure': must_signal_internal_failure,
564 u'version': OUT_VERSION, 574 u'version': OUT_VERSION,
565 } 575 }
566 finally: 576 finally:
567 try: 577 file_path.try_remove(unicode(isolated_result))
568 os.remove(isolated_result) 578 file_path.try_remove(unicode(package_list))
569 except OSError:
570 pass
571 stop_headers_reader() 579 stop_headers_reader()
572 580
573 581
574 def main(args): 582 def main(args):
575 subprocess42.inhibit_os_error_reporting() 583 subprocess42.inhibit_os_error_reporting()
576 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) 584 parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
577 parser.add_option('--in-file', help='Name of the request file') 585 parser.add_option('--in-file', help='Name of the request file')
578 parser.add_option( 586 parser.add_option(
579 '--out-file', help='Name of the JSON file to write a task summary to') 587 '--out-file', help='Name of the JSON file to write a task summary to')
580 parser.add_option( 588 parser.add_option(
(...skipping 19 matching lines...) Expand all
600 options.start = now 608 options.start = now
601 609
602 try: 610 try:
603 load_and_run( 611 load_and_run(
604 options.in_file, options.swarming_server, options.cost_usd_hour, 612 options.in_file, options.swarming_server, options.cost_usd_hour,
605 options.start, options.out_file, options.min_free_space, 613 options.start, options.out_file, options.min_free_space,
606 options.bot_file) 614 options.bot_file)
607 return 0 615 return 0
608 finally: 616 finally:
609 logging.info('quitting') 617 logging.info('quitting')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698