Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Functions specific to handle goma related info. | 5 """Functions specific to handle goma related info. |
| 6 """ | 6 """ |
| 7 | 7 |
| 8 import base64 | 8 import base64 |
| 9 import datetime | 9 import datetime |
| 10 import getpass | 10 import getpass |
| 11 import glob | 11 import glob |
| 12 import gzip | 12 import gzip |
| 13 import json | 13 import json |
| 14 import multiprocessing | |
| 14 import os | 15 import os |
| 15 import re | 16 import re |
| 16 import shutil | 17 import shutil |
| 17 import socket | 18 import socket |
| 19 import subprocess | |
| 18 import sys | 20 import sys |
| 19 import tempfile | 21 import tempfile |
| 20 import time | 22 import time |
| 21 | 23 |
| 22 from common import chromium_utils | 24 from common import chromium_utils |
| 23 from slave import slave_utils | 25 from slave import slave_utils |
| 24 | 26 |
| 25 # The Google Cloud Storage bucket to store logs related to goma. | 27 # The Google Cloud Storage bucket to store logs related to goma. |
| 26 GOMA_LOG_GS_BUCKET = 'chrome-goma-log' | 28 GOMA_LOG_GS_BUCKET = 'chrome-goma-log' |
| 27 | 29 |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 retcode = chromium_utils.RunCommand( | 350 retcode = chromium_utils.RunCommand( |
| 349 cmd, filter_obj=cmd_filter, | 351 cmd, filter_obj=cmd_filter, |
| 350 max_time=30) | 352 max_time=30) |
| 351 if retcode: | 353 if retcode: |
| 352 print('Execution of send_ts_mon_values failed with code %s' | 354 print('Execution of send_ts_mon_values failed with code %s' |
| 353 % retcode) | 355 % retcode) |
| 354 print '\n'.join(cmd_filter.text) | 356 print '\n'.join(cmd_filter.text) |
| 355 | 357 |
| 356 except Exception as ex: | 358 except Exception as ex: |
| 357 print('error while sending ts mon json_file=%s: %s' % (json_file, ex)) | 359 print('error while sending ts mon json_file=%s: %s' % (json_file, ex)) |
| 360 | |
| 361 | |
| 362 def goma_setup(options, env): | |
| 363 """Sets up goma if necessary. | |
| 364 | |
| 365 If using the Goma compiler, first call goma_ctl to ensure the proxy is | |
| 366 available, and returns (True, instance of cloudtail subprocess). | |
| 367 If it failed to start up compiler_proxy, modify options.compiler and | |
| 368 options.goma_dir and returns (False, None) | |
|
ukai
2016/07/27 01:13:29
Args:
Returns:
?
tikuta
2016/07/27 02:33:30
Done.
| |
| 369 | |
| 370 """ | |
| 371 if options.compiler not in ('goma', 'goma-clang'): | |
| 372 # Unset goma_dir to make sure we'll not use goma. | |
| 373 options.goma_dir = None | |
| 374 return False, None | |
| 375 | |
| 376 hostname = GetShortHostname() | |
| 377 # HACK(shinyak, yyanagisawa, goma): Windows NO_NACL_GOMA (crbug.com/390764) | |
| 378 # Building NaCl untrusted code using goma brings large performance | |
| 379 # improvement but it sometimes cause build failure by race condition. | |
| 380 # Let me enable goma build on goma canary buildslaves to confirm the issue | |
| 381 # has been fixed by a workaround. | |
| 382 # vm*-m4 are trybots. build*-m1 and vm*-m1 are all goma canary bots. | |
| 383 if hostname in ['build28-m1', 'build58-m1', 'vm191-m1', 'vm480-m1', | |
| 384 'vm820-m1', 'vm821-m1', 'vm848-m1']: | |
| 385 env['NO_NACL_GOMA'] = 'false' | |
| 386 | |
| 387 if options.goma_fail_fast: | |
| 388 # startup fails when initial ping failed. | |
| 389 env['GOMA_FAIL_FAST'] = 'true' | |
| 390 else: | |
| 391 # If a network error continues 30 minutes, compiler_proxy make the compile | |
| 392 # failed. When people use goma, they expect using goma is faster than | |
| 393 # compile locally. If goma cannot guarantee that, let it make compile | |
| 394 # as error. | |
| 395 env['GOMA_ALLOWED_NETWORK_ERROR_DURATION'] = '1800' | |
| 396 | |
| 397 # HACK(yyanagisawa): reduce GOMA_BURST_MAX_PROCS crbug.com/592306 | |
| 398 # Recently, I sometimes see buildbot slave time out, one possibility I come | |
| 399 # up with is burst mode use up resource. | |
| 400 # Let me temporary set small values to GOMA_BURST_MAX_PROCS to confirm | |
| 401 # the possibility is true or false. | |
| 402 max_subprocs = '3' | |
| 403 max_heavy_subprocs = '1' | |
| 404 number_of_processors = 0 | |
| 405 try: | |
| 406 number_of_processors = multiprocessing.cpu_count() | |
| 407 except NotImplementedError: | |
| 408 print 'cpu_count() is not implemented, using default value.' | |
| 409 number_of_processors = 1 | |
| 410 if number_of_processors > 3: | |
| 411 max_subprocs = str(number_of_processors - 1) | |
| 412 max_heavy_subprocs = str(number_of_processors / 2) | |
| 413 env['GOMA_BURST_MAX_SUBPROCS'] = max_subprocs | |
| 414 env['GOMA_BURST_MAX_SUBPROCS_LOW'] = max_subprocs | |
| 415 env['GOMA_BURST_MAX_SUBPROCS_HEAVY'] = max_heavy_subprocs | |
| 416 | |
| 417 # Caches CRLs in GOMA_CACHE_DIR. | |
| 418 # Since downloading CRLs is usually slow, caching them may improves | |
| 419 # compiler_proxy start time. | |
| 420 if not os.path.exists(options.goma_cache_dir): | |
| 421 os.mkdir(options.goma_cache_dir, 0700) | |
| 422 env['GOMA_CACHE_DIR'] = options.goma_cache_dir | |
| 423 | |
| 424 # Enable DepsCache. DepsCache caches the list of files to send goma server. | |
| 425 # This will greatly improve build speed when cache is warmed. | |
| 426 # The cache file is stored in the target output directory. | |
| 427 env['GOMA_DEPS_CACHE_DIR'] = ( | |
| 428 options.goma_deps_cache_dir or options.target_output_dir) | |
| 429 | |
| 430 if not env.get('GOMA_HERMETIC'): | |
| 431 env['GOMA_HERMETIC'] = options.goma_hermetic | |
| 432 if options.goma_enable_remote_link: | |
| 433 env['GOMA_ENABLE_REMOTE_LINK'] = options.goma_enable_remote_link | |
| 434 if options.goma_store_local_run_output: | |
| 435 env['GOMA_STORE_LOCAL_RUN_OUTPUT'] = options.goma_store_local_run_output | |
| 436 if options.goma_enable_compiler_info_cache: | |
| 437 # Will be stored in GOMA_CACHE_DIR. | |
| 438 env['GOMA_COMPILER_INFO_CACHE_FILE'] = 'goma-compiler-info.cache' | |
| 439 | |
| 440 if options.build_data_dir: | |
| 441 env['GOMA_DUMP_STATS_FILE'] = os.path.join(options.build_data_dir, | |
| 442 'goma_stats_proto') | |
| 443 | |
| 444 # goma is requested. | |
| 445 goma_key = os.path.join(options.goma_dir, 'goma.key') | |
| 446 if os.path.exists(goma_key): | |
| 447 env['GOMA_API_KEY_FILE'] = goma_key | |
| 448 if options.goma_service_account_json_file: | |
| 449 env['GOMA_SERVICE_ACCOUNT_JSON_FILE'] = \ | |
| 450 options.goma_service_account_json_file | |
| 451 if chromium_utils.IsWindows(): | |
| 452 env['GOMA_RPC_EXTRA_PARAMS'] = '?win' | |
| 453 goma_start_command = ['restart'] | |
| 454 goma_ctl_cmd = [sys.executable, | |
| 455 os.path.join(options.goma_dir, 'goma_ctl.py')] | |
| 456 result = chromium_utils.RunCommand(goma_ctl_cmd + goma_start_command, env=env) | |
| 457 if not result: | |
| 458 # goma started sucessfully. | |
| 459 # Making cloudtail to upload the latest log. | |
| 460 # TODO(yyanagisawa): install cloudtail from CIPD. | |
| 461 cloudtail_path = '/opt/infra-tools/cloudtail' | |
| 462 if chromium_utils.IsWindows(): | |
| 463 cloudtail_path = 'C:\\infra-tools\\cloudtail' | |
| 464 try: | |
| 465 cloudtail_proc = subprocess.Popen( | |
| 466 [cloudtail_path, 'tail', '--log-id', 'goma_compiler_proxy', '--path', | |
| 467 GetLatestGomaCompilerProxyInfo()]) | |
| 468 except Exception as e: | |
| 469 print 'failed to invoke cloudtail: %s' % e | |
| 470 return True, None | |
| 471 return True, cloudtail_proc | |
| 472 | |
| 473 if options.goma_jsonstatus: | |
| 474 chromium_utils.RunCommand( | |
| 475 goma_ctl_cmd + ['jsonstatus', options.goma_jsonstatus], env=env) | |
| 476 SendGomaTsMon(options.goma_jsonstatus, -1) | |
| 477 | |
| 478 # Try to stop compiler_proxy so that it flushes logs and stores | |
| 479 # GomaStats. | |
| 480 if options.build_data_dir: | |
| 481 env['GOMACTL_CRASH_REPORT_ID_FILE'] = os.path.join(options.build_data_dir, | |
| 482 'crash_report_id_file') | |
| 483 chromium_utils.RunCommand(goma_ctl_cmd + ['stop'], env=env) | |
| 484 | |
| 485 override_gsutil = None | |
| 486 if options.gsutil_py_path: | |
| 487 override_gsutil = [sys.executable, options.gsutil_py_path] | |
| 488 | |
| 489 # Upload compiler_proxy.INFO to investigate the reason of compiler_proxy | |
| 490 # start-up failure. | |
| 491 UploadGomaCompilerProxyInfo(override_gsutil=override_gsutil) | |
| 492 # Upload GomaStats to make it monitored. | |
| 493 if env.get('GOMA_DUMP_STATS_FILE'): | |
| 494 SendGomaStats(env['GOMA_DUMP_STATS_FILE'], | |
| 495 env.get('GOMACTL_CRASH_REPORT_ID_FILE'), | |
| 496 options.build_data_dir) | |
| 497 | |
| 498 if options.goma_disable_local_fallback: | |
| 499 print 'error: failed to start goma; fallback has been disabled' | |
| 500 raise Exception('failed to start goma') | |
| 501 | |
| 502 print 'warning: failed to start goma. falling back to non-goma' | |
| 503 # Drop goma from options.compiler | |
| 504 options.compiler = options.compiler.replace('goma-', '') | |
| 505 if options.compiler == 'goma': | |
| 506 options.compiler = None | |
| 507 # Reset options.goma_dir. | |
| 508 options.goma_dir = None | |
| 509 env['GOMA_DISABLED'] = '1' | |
| 510 return False, None | |
| 511 | |
| 512 | |
| 513 def goma_teardown(options, env, exit_status, cloudtail_proc): | |
| 514 """Tears down goma if necessary. """ | |
| 515 if (options.compiler in ('goma', 'goma-clang') and | |
| 516 options.goma_dir): | |
| 517 override_gsutil = None | |
| 518 if options.gsutil_py_path: | |
| 519 override_gsutil = [sys.executable, options.gsutil_py_path] | |
| 520 | |
| 521 # If goma compiler_proxy crashes during the build, there could be crash | |
| 522 # dump. | |
| 523 if options.build_data_dir: | |
| 524 env['GOMACTL_CRASH_REPORT_ID_FILE'] = os.path.join(options.build_data_dir, | |
| 525 'crash_report_id_file') | |
| 526 goma_ctl_cmd = [sys.executable, | |
| 527 os.path.join(options.goma_dir, 'goma_ctl.py')] | |
| 528 if options.goma_jsonstatus: | |
| 529 chromium_utils.RunCommand( | |
| 530 goma_ctl_cmd + ['jsonstatus', options.goma_jsonstatus], env=env) | |
| 531 SendGomaTsMon(options.goma_jsonstatus, exit_status) | |
| 532 # Always stop the proxy for now to allow in-place update. | |
| 533 chromium_utils.RunCommand(goma_ctl_cmd + ['stop'], env=env) | |
| 534 UploadGomaCompilerProxyInfo(override_gsutil=override_gsutil) | |
| 535 if env.get('GOMA_DUMP_STATS_FILE'): | |
| 536 SendGomaStats(env['GOMA_DUMP_STATS_FILE'], | |
| 537 env.get('GOMACTL_CRASH_REPORT_ID_FILE'), | |
| 538 options.build_data_dir) | |
| 539 if cloudtail_proc: | |
| 540 cloudtail_proc.terminate() | |
| 541 cloudtail_proc.wait() | |
| 542 | |
| 543 | |
| 544 def determine_goma_jobs(): | |
| 545 # We would like to speed up build on Windows a bit, since it is slowest. | |
| 546 number_of_processors = 0 | |
| 547 try: | |
| 548 number_of_processors = multiprocessing.cpu_count() | |
| 549 except NotImplementedError: | |
| 550 print 'cpu_count() is not implemented, using default value 50.' | |
| 551 return 50 | |
| 552 | |
| 553 assert number_of_processors > 0 | |
| 554 | |
| 555 # When goma is used, 10 * number_of_processors is basically good in | |
| 556 # various situations according to our measurement. Build speed won't | |
| 557 # be improved if -j is larger than that. | |
| 558 # | |
| 559 # Since Mac had process number limitation before, we had to set | |
| 560 # the upper limit to 50. Now that the process number limitation is 2000, | |
| 561 # so we would be able to use 10 * number_of_processors. | |
| 562 # For the safety, we'd like to set the upper limit to 200. | |
| 563 # | |
| 564 # Note that currently most try-bot build slaves have 8 processors. | |
| 565 if chromium_utils.IsMac() or chromium_utils.IsWindows(): | |
| 566 return min(10 * number_of_processors, 200) | |
| 567 | |
| 568 # For Linux, we also would like to use 10 * cpu. However, not sure | |
| 569 # backend resource is enough, so let me set Linux and Linux x64 builder | |
| 570 # only for now. | |
| 571 hostname = GetShortHostname() | |
| 572 if hostname in ( | |
| 573 ['build14-m1', 'build48-m1'] + | |
| 574 # Also increasing cpus for v8/blink trybots. | |
| 575 ['build%d-m4' % x for x in xrange(45, 48)] + | |
| 576 # Also increasing cpus for LTO buildbots. | |
| 577 ['slave%d-c1' % x for x in [20, 33] + range(78, 108)]): | |
| 578 return min(10 * number_of_processors, 200) | |
| 579 | |
| 580 return 50 | |
| OLD | NEW |