|
@@ -1,4 +1,4 @@
|
|
-#!/usr/bin/env python3
|
|
|
|
|
|
+#!/usr/bin/env vpython3
|
|
# Copyright (c) 2017 The Chromium Authors. All rights reserved.
|
|
# Copyright (c) 2017 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
# found in the LICENSE file.
|
|
@@ -14,13 +14,19 @@ does handle import statements, but it can't handle conditional setting of build
|
|
settings.
|
|
settings.
|
|
"""
|
|
"""
|
|
|
|
|
|
|
|
+import json
|
|
import multiprocessing
|
|
import multiprocessing
|
|
import os
|
|
import os
|
|
import platform
|
|
import platform
|
|
import re
|
|
import re
|
|
import shlex
|
|
import shlex
|
|
|
|
+import shutil
|
|
import subprocess
|
|
import subprocess
|
|
import sys
|
|
import sys
|
|
|
|
+import warnings
|
|
|
|
+
|
|
|
|
+import google.auth
|
|
|
|
+from google.auth.transport.requests import AuthorizedSession
|
|
|
|
|
|
import autosiso
|
|
import autosiso
|
|
import ninja
|
|
import ninja
|
|
@@ -43,6 +49,72 @@ _UNSAFE_FOR_CMD = set("^<>&|()%")
|
|
_ALL_META_CHARS = _UNSAFE_FOR_CMD.union(set('"'))
|
|
_ALL_META_CHARS = _UNSAFE_FOR_CMD.union(set('"'))
|
|
|
|
|
|
|
|
|
|
|
|
+def _adc_account():
|
|
|
|
+ """Returns account used to authenticate with GCP application default credentials."""
|
|
|
|
+
|
|
|
|
+ try:
|
|
|
|
+ # Suppress warnings from google.auth.default.
|
|
|
|
+ # https://github.com/googleapis/google-auth-library-python/issues/271
|
|
|
|
+ warnings.filterwarnings(
|
|
|
|
+ "ignore",
|
|
|
|
+ "Your application has authenticated using end user credentials from"
|
|
|
|
+ " Google Cloud SDK without a quota project.",
|
|
|
|
+ )
|
|
|
|
+ credentials, _ = google.auth.default(
|
|
|
|
+ scopes=["https://www.googleapis.com/auth/userinfo.email"])
|
|
|
|
+ except google.auth.exceptions.DefaultCredentialsError:
|
|
|
|
+ # Application Default Crendetials is not configured.
|
|
|
|
+ return None
|
|
|
|
+ finally:
|
|
|
|
+ warnings.resetwarnings()
|
|
|
|
+
|
|
|
|
+ with AuthorizedSession(credentials) as session:
|
|
|
|
+ try:
|
|
|
|
+ response = session.get(
|
|
|
|
+ "https://www.googleapis.com/oauth2/v1/userinfo")
|
|
|
|
+ except Exception:
|
|
|
|
+ # Ignore exception.
|
|
|
|
+ return None
|
|
|
|
+
|
|
|
|
+ return response.json().get("email")
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def _gcloud_auth_account():
|
|
|
|
+ """Returns active account authenticated with `gcloud auth login`."""
|
|
|
|
+ if shutil.which("gcloud") is None:
|
|
|
|
+ return None
|
|
|
|
+
|
|
|
|
+ accounts = json.loads(
|
|
|
|
+ subprocess.check_output("gcloud auth list --format=json",
|
|
|
|
+ shell=True,
|
|
|
|
+ text=True))
|
|
|
|
+ for account in accounts:
|
|
|
|
+ if account["status"] == "ACTIVE":
|
|
|
|
+ return account["account"]
|
|
|
|
+ return None
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def _is_google_corp_machine():
|
|
|
|
+ """This assumes that corp machine has gcert binary in known location."""
|
|
|
|
+ return shutil.which("gcert") is not None
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def _is_google_corp_machine_using_external_account():
|
|
|
|
+ if not _is_google_corp_machine():
|
|
|
|
+ return False
|
|
|
|
+
|
|
|
|
+ account = _adc_account()
|
|
|
|
+ if account and not account.endswith("@google.com"):
|
|
|
|
+ return True
|
|
|
|
+
|
|
|
|
+ account = _gcloud_auth_account()
|
|
|
|
+ if not account:
|
|
|
|
+ return False
|
|
|
|
+ # Handle service account and google account as internal account.
|
|
|
|
+ return not (account.endswith("@google.com")
|
|
|
|
+ or account.endswith("gserviceaccount.com"))
|
|
|
|
+
|
|
|
|
+
|
|
def _quote_for_cmd(arg):
|
|
def _quote_for_cmd(arg):
|
|
# First, escape the arg so that CommandLineToArgvW will parse it properly.
|
|
# First, escape the arg so that CommandLineToArgvW will parse it properly.
|
|
if arg == "" or " " in arg or '"' in arg:
|
|
if arg == "" or " " in arg or '"' in arg:
|
|
@@ -163,6 +235,18 @@ def main(args):
|
|
use_siso = True
|
|
use_siso = True
|
|
continue
|
|
continue
|
|
|
|
|
|
|
|
+ if use_remoteexec:
|
|
|
|
+ if _is_google_corp_machine_using_external_account():
|
|
|
|
+ print(
|
|
|
|
+ "You can't use a non-@google.com account (%s and/or %s) on"
|
|
|
|
+ " a corp machine.\n"
|
|
|
|
+ "Please login via `gcloud auth login --update-adc` with"
|
|
|
|
+ " your @google.com account instead.\n" %
|
|
|
|
+ (_adc_account(), _gcloud_auth_account()),
|
|
|
|
+ file=sys.stderr,
|
|
|
|
+ )
|
|
|
|
+ return 1
|
|
|
|
+
|
|
siso_marker = os.path.join(output_dir, ".siso_deps")
|
|
siso_marker = os.path.join(output_dir, ".siso_deps")
|
|
if use_siso:
|
|
if use_siso:
|
|
# autosiso generates a .ninja_log file so the mere existence of a
|
|
# autosiso generates a .ninja_log file so the mere existence of a
|