Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: appengine/components/tool_support/gae_sdk_utils.py

Issue 2987613002: Fix gae.py's detection of current active credentials. (Closed)
Patch Set: typo Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | appengine/components/tools/gae.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The LUCI Authors. All rights reserved. 1 # Copyright 2013 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0 2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file. 3 # that can be found in the LICENSE file.
4 4
5 """Set of functions to work with GAE SDK tools.""" 5 """Set of functions to work with GAE SDK tools."""
6 6
7 import collections 7 import collections
8 import glob 8 import glob
9 import json 9 import json
10 import logging 10 import logging
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 output, _ = proc.communicate() 331 output, _ = proc.communicate()
332 if proc.returncode: 332 if proc.returncode:
333 sys.stderr.write('\n' + output + '\n') 333 sys.stderr.write('\n' + output + '\n')
334 raise subprocess.CalledProcessError(proc.returncode, cmd, output) 334 raise subprocess.CalledProcessError(proc.returncode, cmd, output)
335 return output 335 return output
336 336
337 def run_appcfg(self, args): 337 def run_appcfg(self, args):
338 """Runs appcfg.py <args>, deserializes its output and returns it.""" 338 """Runs appcfg.py <args>, deserializes its output and returns it."""
339 if USE_GCLOUD: 339 if USE_GCLOUD:
340 raise Error('Attempting to run appcfg.py %s' % ' '.join(args)) 340 raise Error('Attempting to run appcfg.py %s' % ' '.join(args))
341 if not is_gcloud_oauth2_token_cached(): 341 if not is_appcfg_oauth_token_cached():
342 raise LoginRequiredError('Login first using \'gcloud auth login\'.') 342 raise LoginRequiredError('Login first using \'gae.py appcfg_login\'.')
343 cmd = [ 343 cmd = [
344 sys.executable, 344 sys.executable,
345 os.path.join(self._gae_sdk, 'appcfg.py'), 345 os.path.join(self._gae_sdk, 'appcfg.py'),
346 '--skip_sdk_update_check',
346 '--application', self.app_id, 347 '--application', self.app_id,
347 ] 348 ]
348 if self._verbose: 349 if self._verbose:
349 cmd.append('--verbose') 350 cmd.append('--verbose')
350 cmd.extend(args) 351 cmd.extend(args)
351 return yaml.safe_load(self.run_cmd(cmd)) 352 return yaml.safe_load(self.run_cmd(cmd))
352 353
353 def run_gcloud(self, args): 354 def run_gcloud(self, args):
354 """Runs 'gcloud <args> --project ... --format ...' and parses the output.""" 355 """Runs 'gcloud <args> --project ... --format ...' and parses the output."""
355 gcloud = find_gcloud() 356 gcloud = find_gcloud()
356 if not is_gcloud_oauth2_token_cached(): 357 if not is_gcloud_auth_set():
357 raise LoginRequiredError('Login first using \'gcloud auth login\'') 358 raise LoginRequiredError('Login first using \'gcloud auth login\'')
358 raw = self.run_cmd( 359 raw = self.run_cmd(
359 [gcloud] + args + ['--project', self.app_id, '--format', 'json']) 360 [gcloud] + args + ['--project', self.app_id, '--format', 'json'])
360 try: 361 try:
361 return json.loads(raw) 362 return json.loads(raw)
362 except ValueError: 363 except ValueError:
363 sys.stderr.write('Failed to decode gcloud output %r as JSON\n' % raw) 364 sys.stderr.write('Failed to decode gcloud output %r as JSON\n' % raw)
364 raise 365 raise
365 366
366 def list_versions(self): 367 def list_versions(self):
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 print(' Directory: %s' % os.path.basename(app.app_dir)) 707 print(' Directory: %s' % os.path.basename(app.app_dir))
707 print(' App ID: %s' % app.app_id) 708 print(' App ID: %s' % app.app_id)
708 print(' Version: %s' % version) 709 print(' Version: %s' % version)
709 print(' Modules: %s' % ', '.join(modules or app.modules)) 710 print(' Modules: %s' % ', '.join(modules or app.modules))
710 if default_yes: 711 if default_yes:
711 return raw_input('Continue? [Y/n] ') not in ('n', 'N') 712 return raw_input('Continue? [Y/n] ') not in ('n', 'N')
712 else: 713 else:
713 return raw_input('Continue? [y/N] ') in ('y', 'Y') 714 return raw_input('Continue? [y/N] ') in ('y', 'Y')
714 715
715 716
716 def is_gcloud_oauth2_token_cached(): 717 def is_gcloud_auth_set():
717 """Returns false if 'gcloud auth login' needs to be run.""" 718 """Returns false if 'gcloud auth login' needs to be run."""
718 p = os.path.join(os.path.expanduser('~'), '.config', 'gcloud', 'credentials')
719 try: 719 try:
720 with open(p) as f: 720 # This returns an email address of currently active account or empty string
721 return len(json.load(f)['data']) != 0 721 # if no account is active.
722 except (KeyError, IOError, OSError, ValueError): 722 output = subprocess.check_output([
723 find_gcloud(), 'auth', 'list',
724 '--filter=status:ACTIVE', '--format=value(account)',
725 ])
726 return bool(output.strip())
727 except subprocess.CalledProcessError as exc:
728 logging.error('Failed to check active gcloud account: %s', exc)
723 return False 729 return False
724 730
725 731
732 # TODO(vadimsh): Can be removed if using 'gcloud'.
733 def _appcfg_oauth2_tokens():
734 return os.path.join(os.path.expanduser('~'), '.appcfg_oauth2_tokens')
735
736
737 # TODO(vadimsh): Can be removed if using 'gcloud'.
738 def is_appcfg_oauth_token_cached():
739 """Returns true if ~/.appcfg_oauth2_tokens exists."""
740 return os.path.exists(_appcfg_oauth2_tokens())
741
742
743 # TODO(vadimsh): Can be removed if using 'gcloud'.
744 def appcfg_login(app):
745 """Starts appcfg.py's login flow."""
746 if not _GAE_SDK_PATH:
747 raise ValueError('Call setup_gae_sdk first')
748 if os.path.exists(_appcfg_oauth2_tokens()):
749 os.remove(_appcfg_oauth2_tokens())
750 # HACK: Call a command with no side effect to launch the flow.
751 subprocess.call([
752 sys.executable,
753 os.path.join(_GAE_SDK_PATH, 'appcfg.py'),
754 '--application', app.app_id,
755 '--noauth_local_webserver',
756 'list_versions',
757 ], cwd=app.app_dir)
758
759
726 def setup_gae_env(): 760 def setup_gae_env():
727 """Sets up App Engine Python test environment by modifying sys.path.""" 761 """Sets up App Engine Python test environment by modifying sys.path."""
728 sdk_path = find_gae_sdk() 762 sdk_path = find_gae_sdk()
729 if not sdk_path: 763 if not sdk_path:
730 raise BadEnvironmentError('Couldn\'t find GAE SDK.') 764 raise BadEnvironmentError('Couldn\'t find GAE SDK.')
731 setup_gae_sdk(sdk_path) 765 setup_gae_sdk(sdk_path)
OLDNEW
« no previous file with comments | « no previous file | appengine/components/tools/gae.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698