Index: appengine/swarming/swarming_bot/bot_code/task_runner.py |
diff --git a/appengine/swarming/swarming_bot/bot_code/task_runner.py b/appengine/swarming/swarming_bot/bot_code/task_runner.py |
index 146a8f2cc48b781e053c44264d733c082e4f1f69..11e188254f49e349682193b3fa88c38d3b0f423f 100644 |
--- a/appengine/swarming/swarming_bot/bot_code/task_runner.py |
+++ b/appengine/swarming/swarming_bot/bot_code/task_runner.py |
@@ -157,7 +157,8 @@ class MustExit(Exception): |
def load_and_run( |
- in_file, swarming_server, cost_usd_hour, start, out_file, min_free_space): |
+ in_file, swarming_server, auth_headers_file, cost_usd_hour, start, |
+ out_file, min_free_space): |
"""Loads the task's metadata and execute it. |
This may throw all sorts of exceptions in case of failure. It's up to the |
@@ -182,8 +183,8 @@ def load_and_run( |
task_details = TaskDetails(json.load(f)) |
task_result = run_command( |
- swarming_server, task_details, work_dir, cost_usd_hour, start, |
- min_free_space) |
+ swarming_server, task_details, work_dir, auth_headers_file, |
+ cost_usd_hour, start, min_free_space) |
except MustExit as e: |
# This normally means run_command() didn't get the chance to run, as it |
# itself trap MustExit and will report accordingly. In this case, we want |
@@ -206,11 +207,14 @@ def load_and_run( |
json.dump(task_result, f) |
-def post_update(swarming_server, params, exit_code, stdout, output_chunk_start): |
+def post_update( |
+ swarming_server, auth_headers_file, params, exit_code, |
+ stdout, output_chunk_start): |
"""Posts task update to task_update. |
Arguments: |
swarming_server: Base URL to Swarming server. |
+ auth_headers_file: file to read HTTP authentication headers from. |
params: Default JSON parameters for the POST. |
exit_code: Process exit code, only when a command completed. |
stdout: Incremental output since last call, if any. |
@@ -225,11 +229,14 @@ def post_update(swarming_server, params, exit_code, stdout, output_chunk_start): |
# chunks are processed and saved in the DB in order. |
params['output'] = base64.b64encode(stdout) |
params['output_chunk_start'] = output_chunk_start |
+ headers = read_auth_headers(auth_headers_file) if auth_headers_file else None |
# TODO(maruel): Support early cancellation. |
# https://code.google.com/p/swarming/issues/detail?id=62 |
resp = net.url_read_json( |
swarming_server+'/swarming/api/v1/bot/task_update/%s' % params['task_id'], |
- data=params) |
+ data=params, |
+ headers=headers, |
+ follow_redirects=False) |
logging.debug('post_update() = %s', resp) |
if not resp or resp.get('error'): |
# Abandon it. This will force a process exit. |
@@ -249,6 +256,16 @@ def should_post_update(stdout, now, last_packet): |
return len(stdout) >= MAX_CHUNK_SIZE or (now - last_packet) > packet_interval |
+def read_auth_headers(path): |
+ """Reads authentication headers from the given file. |
+ |
+ The file is kept up-to-date by the main bot process (see AuthHeadersDumper in |
+ bot_main.py). |
+ """ |
+ # TODO(vadimsh): Implement. |
+ return {} |
+ |
+ |
def calc_yield_wait(task_details, start, last_io, timed_out, stdout): |
"""Calculates the maximum number of seconds to wait in yield_any().""" |
now = monotonic_time() |
@@ -282,8 +299,8 @@ def kill_and_wait(proc, grace_period, reason): |
def run_command( |
- swarming_server, task_details, work_dir, cost_usd_hour, task_start, |
- min_free_space): |
+ swarming_server, task_details, work_dir, auth_headers_file, cost_usd_hour, |
+ task_start, min_free_space): |
"""Runs a command and sends packets to the server to stream results back. |
Implements both I/O and hard timeouts. Sends the packets numbered, so the |
@@ -300,7 +317,7 @@ def run_command( |
'id': task_details.bot_id, |
'task_id': task_details.task_id, |
} |
- post_update(swarming_server, params, None, '', 0) |
+ post_update(swarming_server, auth_headers_file, params, None, '', 0) |
isolated_result = os.path.join(work_dir, 'isolated_result.json') |
cmd = get_isolated_cmd( |
@@ -342,7 +359,7 @@ def run_command( |
params['duration'] = now - start |
params['io_timeout'] = False |
params['hard_timeout'] = False |
- post_update(swarming_server, params, 1, stdout, 0) |
+ post_update(swarming_server, auth_headers_file, params, 1, stdout, 0) |
return { |
u'exit_code': 1, |
u'hard_timeout': False, |
@@ -374,7 +391,9 @@ def run_command( |
last_packet = monotonic_time() |
params['cost_usd'] = ( |
cost_usd_hour * (last_packet - task_start) / 60. / 60.) |
- post_update(swarming_server, params, None, stdout, output_chunk_start) |
+ post_update( |
+ swarming_server, auth_headers_file, params, None, |
+ stdout, output_chunk_start) |
output_chunk_start += len(stdout) |
stdout = '' |
@@ -480,7 +499,9 @@ def run_command( |
if exit_code is None: |
exit_code = -1 |
params['hard_timeout'] = had_hard_timeout |
- post_update(swarming_server, params, exit_code, stdout, output_chunk_start) |
+ post_update( |
+ swarming_server, auth_headers_file, params, exit_code, |
+ stdout, output_chunk_start) |
return { |
u'exit_code': exit_code, |
u'hard_timeout': had_hard_timeout, |
@@ -504,6 +525,9 @@ def main(args): |
parser.add_option( |
'--swarming-server', help='Swarming server to send data back') |
parser.add_option( |
+ '--auth-headers-file', |
+ help='Name of the file to read authentication headers from') |
+ parser.add_option( |
'--cost-usd-hour', type='float', help='Cost of this VM in $/h') |
parser.add_option('--start', type='float', help='Time this task was started') |
parser.add_option( |
@@ -523,8 +547,9 @@ def main(args): |
try: |
load_and_run( |
- options.in_file, options.swarming_server, options.cost_usd_hour, |
- options.start, options.out_file, options.min_free_space) |
+ options.in_file, options.swarming_server, options.auth_headers_file, |
+ options.cost_usd_hour, options.start, options.out_file, |
+ options.min_free_space) |
return 0 |
finally: |
logging.info('quitting') |