You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
5.6 KiB
Python
214 lines
5.6 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright 2024 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import argparse
|
|
import json
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import textwrap
|
|
|
|
import utils
|
|
|
|
_DEFAULT_CONFIG_PATH = utils.depot_tools_config_path("build_telemetry.cfg")
|
|
|
|
_DEFAULT_COUNTDOWN = 10
|
|
|
|
VERSION = 1
|
|
|
|
|
|
class Config:
|
|
|
|
def __init__(self, config_path, countdown):
|
|
self._config_path = config_path
|
|
self._config = None
|
|
self._notice_displayed = False
|
|
self._countdown = countdown
|
|
|
|
def load(self):
|
|
"""Loads the build telemetry config."""
|
|
if self._config:
|
|
return
|
|
|
|
config = {}
|
|
if os.path.isfile(self._config_path):
|
|
with open(self._config_path) as f:
|
|
try:
|
|
config = json.load(f)
|
|
except Exception:
|
|
pass
|
|
if config.get("version") != VERSION:
|
|
config = None # Reset the state for version change.
|
|
|
|
if not config:
|
|
config = {
|
|
"user": check_auth().get("email", ""),
|
|
"status": None,
|
|
"countdown": self._countdown,
|
|
"version": VERSION,
|
|
}
|
|
if not config.get("user"):
|
|
config["user"] = check_auth().get("email", "")
|
|
|
|
|
|
self._config = config
|
|
|
|
def save(self):
|
|
with open(self._config_path, "w") as f:
|
|
json.dump(self._config, f)
|
|
|
|
@property
|
|
def path(self):
|
|
return self._config_path
|
|
|
|
@property
|
|
def is_googler(self):
|
|
return self.user.endswith("@google.com")
|
|
|
|
@property
|
|
def user(self):
|
|
if not self._config:
|
|
return
|
|
return self._config.get("user", "")
|
|
|
|
|
|
@property
|
|
def countdown(self):
|
|
if not self._config:
|
|
return
|
|
return self._config.get("countdown")
|
|
|
|
@property
|
|
def version(self):
|
|
if not self._config:
|
|
return
|
|
return self._config.get("version")
|
|
|
|
def enabled(self):
|
|
if not self._config:
|
|
print("WARNING: depot_tools.build_telemetry: %s is not loaded." %
|
|
self._config_path,
|
|
file=sys.stderr)
|
|
return False
|
|
if not self.is_googler:
|
|
return False
|
|
if self._config.get("status") == "opt-out":
|
|
return False
|
|
|
|
if self._should_show_notice():
|
|
remaining = max(0, self._config["countdown"] - 1)
|
|
self._show_notice(remaining)
|
|
self._notice_displayed = True
|
|
self._config["countdown"] = remaining
|
|
self.save()
|
|
|
|
# Telemetry collection will happen.
|
|
return True
|
|
|
|
def _should_show_notice(self):
|
|
if self._notice_displayed:
|
|
return False
|
|
if self._config.get("countdown") == 0:
|
|
return False
|
|
if self._config.get("status") == "opt-in":
|
|
return False
|
|
return True
|
|
|
|
def _show_notice(self, remaining):
|
|
"""Dispalys notice when necessary."""
|
|
print(
|
|
textwrap.dedent(f"""\
|
|
*** NOTICE ***
|
|
Google-internal telemetry (including build logs, username, and hostname) is collected on corp machines to diagnose performance and fix build issues. This reminder will be shown {remaining} more times. See http://go/chrome-build-telemetry for details. Hide this notice or opt out by running: build_telemetry [opt-in] [opt-out]
|
|
*** END NOTICE ***
|
|
"""))
|
|
|
|
def opt_in(self):
|
|
self._config["status"] = "opt-in"
|
|
self.save()
|
|
print("build telemetry collection is opted in")
|
|
|
|
def opt_out(self):
|
|
self._config["status"] = "opt-out"
|
|
self.save()
|
|
print("build telemetry collection is opted out")
|
|
|
|
def status(self):
|
|
return self._config["status"]
|
|
|
|
|
|
def load_config(cfg_path=_DEFAULT_CONFIG_PATH, countdown=_DEFAULT_COUNTDOWN):
|
|
"""Loads the config from the default location."""
|
|
cfg = Config(cfg_path, countdown)
|
|
cfg.load()
|
|
return cfg
|
|
|
|
|
|
def check_auth():
|
|
"""Checks auth information."""
|
|
try:
|
|
out = subprocess.check_output(
|
|
"cipd auth-info --json-output -",
|
|
text=True,
|
|
shell=True,
|
|
stderr=subprocess.DEVNULL,
|
|
timeout=3,
|
|
)
|
|
except Exception as e:
|
|
return {}
|
|
try:
|
|
return json.loads(out)
|
|
except json.JSONDecodeError as e:
|
|
logging.error(e)
|
|
return {}
|
|
|
|
def enabled():
|
|
"""Checks whether the build can upload build telemetry."""
|
|
cfg = load_config()
|
|
return cfg.enabled()
|
|
|
|
|
|
def print_status(cfg):
|
|
status = cfg.status()
|
|
if status == "opt-in":
|
|
print("build telemetry collection is enabled. You have opted in.")
|
|
elif status == "opt-out":
|
|
print("build telemetry collection is disabled. You have opted out.")
|
|
else:
|
|
print("build telemetry collection is enabled.")
|
|
print("")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(prog="build_telemetry")
|
|
parser.add_argument('status',
|
|
nargs='?',
|
|
choices=["opt-in", "opt-out", "status"])
|
|
args = parser.parse_args()
|
|
|
|
cfg = load_config()
|
|
|
|
if not cfg.is_googler:
|
|
cfg.save()
|
|
return
|
|
|
|
if args.status == "opt-in":
|
|
cfg.opt_in()
|
|
return
|
|
if args.status == "opt-out":
|
|
cfg.opt_out()
|
|
return
|
|
if args.status == "status":
|
|
print_status(cfg)
|
|
return
|
|
|
|
print_status(cfg)
|
|
parser.print_help()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|