Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 1 | # Copyright 2023 The Chromium Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | """This helper provides a build context that handles |
| 5 | the reclient lifecycle safely. It will automatically start |
| 6 | reproxy before running ninja and stop reproxy when build stops |
| 7 | for any reason e.g. build completion, keyboard interrupt etc.""" |
| 8 | |
| 9 | import contextlib |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 10 | import datetime |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 11 | import hashlib |
| 12 | import os |
Ben Segall | 2e67384 | 2023-06-21 14:23:37 +0000 | [diff] [blame] | 13 | import shutil |
Ben Segall | b64ee7f | 2023-09-07 15:11:31 +0000 | [diff] [blame] | 14 | import socket |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 15 | import subprocess |
| 16 | import sys |
Bruce Dawson | 6d0c235 | 2023-08-06 02:38:51 +0000 | [diff] [blame] | 17 | import time |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 18 | import uuid |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 19 | |
| 20 | import gclient_paths |
Ben Segall | 530d86d | 2023-05-29 16:11:00 +0000 | [diff] [blame] | 21 | import reclient_metrics |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 22 | |
| 23 | |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 24 | THIS_DIR = os.path.dirname(__file__) |
| 25 | RECLIENT_LOG_CLEANUP = os.path.join(THIS_DIR, 'reclient_log_cleanup.py') |
| 26 | |
| 27 | |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 28 | def find_reclient_bin_dir(): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 29 | tools_path = gclient_paths.GetBuildtoolsPath() |
| 30 | if not tools_path: |
| 31 | return None |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 32 | |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 33 | reclient_bin_dir = os.path.join(tools_path, 'reclient') |
| 34 | if os.path.isdir(reclient_bin_dir): |
| 35 | return reclient_bin_dir |
| 36 | return None |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 37 | |
| 38 | |
| 39 | def find_reclient_cfg(): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 40 | tools_path = gclient_paths.GetBuildtoolsPath() |
| 41 | if not tools_path: |
| 42 | return None |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 43 | |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 44 | reclient_cfg = os.path.join(tools_path, 'reclient_cfgs', 'reproxy.cfg') |
| 45 | if os.path.isfile(reclient_cfg): |
| 46 | return reclient_cfg |
| 47 | return None |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 48 | |
| 49 | |
| 50 | def run(cmd_args): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 51 | if os.environ.get('NINJA_SUMMARIZE_BUILD') == '1': |
| 52 | print(' '.join(cmd_args)) |
| 53 | return subprocess.call(cmd_args) |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 54 | |
| 55 | |
| 56 | def start_reproxy(reclient_cfg, reclient_bin_dir): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 57 | return run([ |
| 58 | os.path.join(reclient_bin_dir, |
| 59 | 'bootstrap' + gclient_paths.GetExeSuffix()), |
| 60 | '--re_proxy=' + os.path.join(reclient_bin_dir, |
| 61 | 'reproxy' + gclient_paths.GetExeSuffix()), |
| 62 | '--cfg=' + reclient_cfg |
| 63 | ]) |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 64 | |
| 65 | |
| 66 | def stop_reproxy(reclient_cfg, reclient_bin_dir): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 67 | return run([ |
| 68 | os.path.join(reclient_bin_dir, |
| 69 | 'bootstrap' + gclient_paths.GetExeSuffix()), '--shutdown', |
| 70 | '--cfg=' + reclient_cfg |
| 71 | ]) |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 72 | |
| 73 | |
| 74 | def find_ninja_out_dir(args): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 75 | # Ninja uses getopt_long, which allows to intermix non-option arguments. |
| 76 | # To leave non supported parameters untouched, we do not use getopt. |
| 77 | for index, arg in enumerate(args[1:]): |
| 78 | if arg == '-C': |
| 79 | # + 1 to get the next argument and +1 because we trimmed off args[0] |
| 80 | return args[index + 2] |
| 81 | if arg.startswith('-C'): |
| 82 | # Support -Cout/Default |
| 83 | return arg[2:] |
| 84 | return '.' |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 85 | |
| 86 | |
Ben Segall | 7a0fe8b | 2023-04-24 20:36:55 +0000 | [diff] [blame] | 87 | def find_cache_dir(tmp_dir): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 88 | """Helper to find the correct cache directory for a build. |
Ben Segall | 7a0fe8b | 2023-04-24 20:36:55 +0000 | [diff] [blame] | 89 | |
| 90 | tmp_dir should be a build specific temp directory within the out directory. |
| 91 | |
| 92 | If this is called from within a gclient checkout, the cache dir will be: |
| 93 | <gclient_root>/.reproxy_cache/md5(tmp_dir)/ |
| 94 | If this is not called from within a gclient checkout, the cache dir will be: |
| 95 | tmp_dir/cache |
| 96 | """ |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 97 | gclient_root = gclient_paths.FindGclientRoot(os.getcwd()) |
| 98 | if gclient_root: |
| 99 | return os.path.join(gclient_root, '.reproxy_cache', |
| 100 | hashlib.md5(tmp_dir.encode()).hexdigest()) |
| 101 | return os.path.join(tmp_dir, 'cache') |
Ben Segall | 7a0fe8b | 2023-04-24 20:36:55 +0000 | [diff] [blame] | 102 | |
| 103 | |
Ben Segall | 29282b5 | 2023-09-07 14:52:08 +0000 | [diff] [blame] | 104 | def auth_cache_status(): |
| 105 | cred_file = os.path.join(os.environ["RBE_cache_dir"], "reproxy.creds") |
| 106 | if not os.path.isfile(cred_file): |
| 107 | return "missing", "UNSPECIFIED" |
| 108 | try: |
| 109 | with open(cred_file) as f: |
| 110 | status = "valid" |
| 111 | mechanism = "UNSPECIFIED" |
| 112 | for line in f.readlines(): |
| 113 | if "seconds:" in line: |
| 114 | exp = int(line.strip()[len("seconds:"):].strip()) |
| 115 | if exp < (time.time() + 5 * 60): |
| 116 | status = "expired" |
| 117 | elif "mechanism:" in line: |
| 118 | mechanism = line.strip()[len("mechanism:"):].strip() |
| 119 | return status, mechanism |
| 120 | except OSError: |
| 121 | return "missing", "UNSPECIFIED" |
| 122 | |
| 123 | |
Ben Segall | b64ee7f | 2023-09-07 15:11:31 +0000 | [diff] [blame] | 124 | def get_hostname(): |
| 125 | hostname = socket.gethostname() |
Anas Sulaiman | 1e503bf | 2023-11-15 04:30:40 +0000 | [diff] [blame] | 126 | # In case that returned an address, make a best effort attempt to get |
| 127 | # the hostname and ignore any errors. |
Ben Segall | b64ee7f | 2023-09-07 15:11:31 +0000 | [diff] [blame] | 128 | try: |
| 129 | return socket.gethostbyaddr(hostname)[0] |
Anas Sulaiman | 1e503bf | 2023-11-15 04:30:40 +0000 | [diff] [blame] | 130 | except Exception: |
Ben Segall | b64ee7f | 2023-09-07 15:11:31 +0000 | [diff] [blame] | 131 | return hostname |
| 132 | |
| 133 | |
Ben Segall | e49349b | 2023-06-01 02:54:56 +0000 | [diff] [blame] | 134 | def set_reproxy_metrics_flags(tool): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 135 | """Helper to setup metrics collection flags for reproxy. |
Ben Segall | 530d86d | 2023-05-29 16:11:00 +0000 | [diff] [blame] | 136 | |
| 137 | The following env vars are set if not already set: |
| 138 | RBE_metrics_project=chromium-reclient-metrics |
| 139 | RBE_invocation_id=$AUTONINJA_BUILD_ID |
| 140 | RBE_metrics_table=rbe_metrics.builds |
Ben Segall | e49349b | 2023-06-01 02:54:56 +0000 | [diff] [blame] | 141 | RBE_metrics_labels=source=developer,tool={tool} |
Ben Segall | 530d86d | 2023-05-29 16:11:00 +0000 | [diff] [blame] | 142 | RBE_metrics_prefix=go.chromium.org |
| 143 | """ |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 144 | autoninja_id = os.environ.get("AUTONINJA_BUILD_ID") |
| 145 | if autoninja_id is not None: |
Ben Segall | b64ee7f | 2023-09-07 15:11:31 +0000 | [diff] [blame] | 146 | os.environ.setdefault("RBE_invocation_id", |
| 147 | "%s/%s" % (get_hostname(), autoninja_id)) |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 148 | os.environ.setdefault("RBE_metrics_project", "chromium-reclient-metrics") |
| 149 | os.environ.setdefault("RBE_metrics_table", "rbe_metrics.builds") |
Ben Segall | 29282b5 | 2023-09-07 14:52:08 +0000 | [diff] [blame] | 150 | labels = "source=developer,tool=" + tool |
| 151 | auth_status, auth_mechanism = auth_cache_status() |
| 152 | labels += ",creds_cache_status=" + auth_status |
| 153 | labels += ",creds_cache_mechanism=" + auth_mechanism |
| 154 | os.environ.setdefault("RBE_metrics_labels", labels) |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 155 | os.environ.setdefault("RBE_metrics_prefix", "go.chromium.org") |
Ben Segall | 530d86d | 2023-05-29 16:11:00 +0000 | [diff] [blame] | 156 | |
| 157 | |
Ben Segall | 3589c48 | 2023-07-24 17:42:55 +0000 | [diff] [blame] | 158 | def remove_mdproxy_from_path(): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 159 | os.environ["PATH"] = os.pathsep.join( |
| 160 | d for d in os.environ.get("PATH", "").split(os.pathsep) |
| 161 | if "mdproxy" not in d) |
Ben Segall | 3589c48 | 2023-07-24 17:42:55 +0000 | [diff] [blame] | 162 | |
| 163 | |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 164 | # Mockable datetime.datetime.utcnow for testing. |
| 165 | def datetime_now(): |
| 166 | return datetime.datetime.utcnow() |
| 167 | |
| 168 | |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 169 | def set_reproxy_path_flags(out_dir, make_dirs=True): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 170 | """Helper to setup the logs and cache directories for reclient. |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 171 | |
| 172 | Creates the following directory structure if make_dirs is true: |
Ben Segall | 7a0fe8b | 2023-04-24 20:36:55 +0000 | [diff] [blame] | 173 | If in a gclient checkout |
| 174 | out_dir/ |
| 175 | .reproxy_tmp/ |
| 176 | logs/ |
| 177 | <gclient_root> |
| 178 | .reproxy_cache/ |
| 179 | md5(out_dir/.reproxy_tmp)/ |
| 180 | |
| 181 | If not in a gclient checkout |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 182 | out_dir/ |
| 183 | .reproxy_tmp/ |
| 184 | logs/ |
| 185 | cache/ |
| 186 | |
| 187 | The following env vars are set if not already set: |
| 188 | RBE_output_dir=out_dir/.reproxy_tmp/logs |
| 189 | RBE_proxy_log_dir=out_dir/.reproxy_tmp/logs |
| 190 | RBE_log_dir=out_dir/.reproxy_tmp/logs |
| 191 | RBE_cache_dir=out_dir/.reproxy_tmp/cache |
| 192 | *Nix Only: |
| 193 | RBE_server_address=unix://out_dir/.reproxy_tmp/reproxy.sock |
| 194 | Windows Only: |
| 195 | RBE_server_address=pipe://md5(out_dir/.reproxy_tmp)/reproxy.pipe |
| 196 | """ |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 197 | os.environ.setdefault("AUTONINJA_BUILD_ID", str(uuid.uuid4())) |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 198 | tmp_dir = os.path.abspath(os.path.join(out_dir, '.reproxy_tmp')) |
| 199 | log_dir = os.path.join(tmp_dir, 'logs') |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 200 | run_log_dir = os.path.join( |
| 201 | log_dir, |
| 202 | datetime_now().strftime('%Y%m%dT%H%M%S.%f') + "_" + |
| 203 | os.environ["AUTONINJA_BUILD_ID"]) |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 204 | racing_dir = os.path.join(tmp_dir, 'racing') |
| 205 | cache_dir = find_cache_dir(tmp_dir) |
| 206 | if make_dirs: |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 207 | if os.path.isfile(os.path.join(log_dir, "rbe_metrics.txt")): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 208 | try: |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 209 | # Delete entire log dir if it is in the old format |
| 210 | # which had no subdirectories for each build. |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 211 | shutil.rmtree(log_dir) |
| 212 | except OSError: |
| 213 | print( |
| 214 | "Couldn't clear logs because reproxy did " |
| 215 | "not shutdown after the last build", |
| 216 | file=sys.stderr) |
| 217 | os.makedirs(tmp_dir, exist_ok=True) |
| 218 | os.makedirs(log_dir, exist_ok=True) |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 219 | os.makedirs(run_log_dir, exist_ok=True) |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 220 | os.makedirs(cache_dir, exist_ok=True) |
| 221 | os.makedirs(racing_dir, exist_ok=True) |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 222 | old_log_dirs = os.listdir(log_dir) |
| 223 | if len(old_log_dirs) > 5: |
| 224 | old_log_dirs.sort(key=lambda dir: dir.split("_"), reverse=True) |
| 225 | for d in old_log_dirs[5:]: |
Takuto Ikuta | 5388959 | 2023-10-31 04:55:37 +0000 | [diff] [blame] | 226 | shutil.rmtree(os.path.join(log_dir, d)) |
| 227 | |
Ben Segall | 27ea34f | 2023-10-24 16:03:33 +0000 | [diff] [blame] | 228 | os.environ.setdefault("RBE_output_dir", run_log_dir) |
| 229 | os.environ.setdefault("RBE_proxy_log_dir", run_log_dir) |
| 230 | os.environ.setdefault("RBE_log_dir", run_log_dir) |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 231 | os.environ.setdefault("RBE_cache_dir", cache_dir) |
| 232 | os.environ.setdefault("RBE_racing_tmp_dir", racing_dir) |
| 233 | if sys.platform.startswith('win'): |
| 234 | pipe_dir = hashlib.md5(tmp_dir.encode()).hexdigest() |
| 235 | os.environ.setdefault("RBE_server_address", |
| 236 | "pipe://%s/reproxy.pipe" % pipe_dir) |
| 237 | else: |
| 238 | # unix domain socket has path length limit, so use fixed size path here. |
| 239 | # ref: https://www.man7.org/linux/man-pages/man7/unix.7.html |
| 240 | os.environ.setdefault( |
| 241 | "RBE_server_address", "unix:///tmp/reproxy_%s.sock" % |
| 242 | hashlib.sha256(tmp_dir.encode()).hexdigest()) |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 243 | |
| 244 | |
Ben Segall | d3e43dd | 2023-07-25 02:32:31 +0000 | [diff] [blame] | 245 | def set_racing_defaults(): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 246 | os.environ.setdefault("RBE_local_resource_fraction", "0.2") |
| 247 | os.environ.setdefault("RBE_racing_bias", "0.95") |
Ben Segall | d3e43dd | 2023-07-25 02:32:31 +0000 | [diff] [blame] | 248 | |
Ben Segall | 04ca383 | 2023-07-19 01:50:59 +0000 | [diff] [blame] | 249 | |
Junji Watanabe | 607284d | 2023-04-20 03:14:52 +0000 | [diff] [blame] | 250 | @contextlib.contextmanager |
Ben Segall | e49349b | 2023-06-01 02:54:56 +0000 | [diff] [blame] | 251 | def build_context(argv, tool): |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 252 | # If use_remoteexec is set, but the reclient binaries or configs don't |
| 253 | # exist, display an error message and stop. Otherwise, the build will |
| 254 | # attempt to run with rewrapper wrapping actions, but will fail with |
| 255 | # possible non-obvious problems. |
| 256 | reclient_bin_dir = find_reclient_bin_dir() |
| 257 | reclient_cfg = find_reclient_cfg() |
| 258 | if reclient_bin_dir is None or reclient_cfg is None: |
| 259 | print( |
| 260 | 'Build is configured to use reclient but necessary binaries ' |
| 261 | "or config files can't be found.\n" |
| 262 | 'Please check if `"download_remoteexec_cfg": True` custom var is ' |
| 263 | 'set in `.gclient`, and run `gclient sync`.', |
| 264 | file=sys.stderr) |
| 265 | yield 1 |
| 266 | return |
Ben Segall | 530d86d | 2023-05-29 16:11:00 +0000 | [diff] [blame] | 267 | |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 268 | ninja_out = find_ninja_out_dir(argv) |
Ben Segall | 530d86d | 2023-05-29 16:11:00 +0000 | [diff] [blame] | 269 | |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 270 | try: |
| 271 | set_reproxy_path_flags(ninja_out) |
| 272 | except OSError: |
| 273 | print("Error creating reproxy_tmp in output dir", file=sys.stderr) |
| 274 | yield 1 |
| 275 | return |
Ben Segall | 530d86d | 2023-05-29 16:11:00 +0000 | [diff] [blame] | 276 | |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 277 | if reclient_metrics.check_status(ninja_out): |
| 278 | set_reproxy_metrics_flags(tool) |
Ben Segall | 530d86d | 2023-05-29 16:11:00 +0000 | [diff] [blame] | 279 | |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 280 | if os.environ.get('RBE_instance', None): |
| 281 | print('WARNING: Using RBE_instance=%s\n' % |
| 282 | os.environ.get('RBE_instance', '')) |
Fumitoshi Ukai | dedeb88 | 2023-06-15 03:58:35 +0000 | [diff] [blame] | 283 | |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 284 | remote_disabled = os.environ.get('RBE_remote_disabled') |
| 285 | if remote_disabled not in ('1', 't', 'T', 'true', 'TRUE', 'True'): |
| 286 | set_racing_defaults() |
Ben Segall | d3e43dd | 2023-07-25 02:32:31 +0000 | [diff] [blame] | 287 | |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 288 | # TODO(b/292523514) remove this once a fix is landed in reproxy |
| 289 | remove_mdproxy_from_path() |
Ben Segall | 3589c48 | 2023-07-24 17:42:55 +0000 | [diff] [blame] | 290 | |
Bruce Dawson | 6d0c235 | 2023-08-06 02:38:51 +0000 | [diff] [blame] | 291 | start = time.time() |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 292 | reproxy_ret_code = start_reproxy(reclient_cfg, reclient_bin_dir) |
Ben Segall | c18c91e | 2023-09-14 15:25:04 +0000 | [diff] [blame] | 293 | if os.environ.get('NINJA_SUMMARIZE_BUILD') == '1': |
| 294 | elapsed = time.time() - start |
| 295 | print('%1.3f s to start reproxy' % elapsed) |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 296 | if reproxy_ret_code != 0: |
| 297 | yield reproxy_ret_code |
| 298 | return |
| 299 | try: |
| 300 | yield |
| 301 | finally: |
Mike Frysinger | 124bb8e | 2023-09-06 05:48:55 +0000 | [diff] [blame] | 302 | start = time.time() |
| 303 | stop_reproxy(reclient_cfg, reclient_bin_dir) |
Ben Segall | c18c91e | 2023-09-14 15:25:04 +0000 | [diff] [blame] | 304 | if os.environ.get('NINJA_SUMMARIZE_BUILD') == '1': |
| 305 | elapsed = time.time() - start |
| 306 | print('%1.3f s to stop reproxy' % elapsed) |