@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env v python3
# 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,62 @@ _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 :
response = session . get ( " https://www.googleapis.com/oauth2/v1/userinfo " )
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 ( )
return account and not account . endswith ( " @google.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 :
@ -209,6 +271,18 @@ def main(args):
use_goma = True
use_goma = True
break
break
if use_remoteexec or use_siso :
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
# Strip -o/--offline so ninja doesn't see them.
# Strip -o/--offline so ninja doesn't see them.
input_args = [ arg for arg in input_args if arg not in ( " -o " , " --offline " ) ]
input_args = [ arg for arg in input_args if arg not in ( " -o " , " --offline " ) ]