def CredentialsFromP12Key(private_key, account, password=None): """Creates creadentials object from given private key and account name.""" log.warning('.p12 service account keys are not recomended unless it is ' 'necessary for backwards compatability. Please switch to ' 'a newer .json service account key for this account.') try: cred = service_account.ServiceAccountCredentials.from_p12_keyfile_buffer( service_account_email=account, file_buffer=io.BytesIO(private_key), private_key_password=password, scopes=config.CLOUDSDK_SCOPES, token_uri=c_creds.GetEffectiveTokenUri({})) except NotImplementedError: if not encoding.GetEncodedValue(os.environ, 'CLOUDSDK_PYTHON_SITEPACKAGES'): raise UnsupportedCredentialsType(( 'PyOpenSSL is not available. If you have already installed ' 'PyOpenSSL, you will need to enable site packages by ' 'setting the environment variable CLOUDSDK_PYTHON_SITEPACKAGES ' 'to 1. If that does not work, see ' 'https://developers.google.com/cloud/sdk/crypto for details ' 'or consider using .json private key instead.')) else: raise UnsupportedCredentialsType( ('PyOpenSSL is not available. See ' 'https://developers.google.com/cloud/sdk/crypto for details ' 'or consider using .json private key instead.')) # pylint: disable=protected-access cred.user_agent = cred._user_agent = config.CLOUDSDK_USER_AGENT return cred
def _SendRecvPort(request, port): """Communicate with the devshell access token service.""" # pylint:disable=g-import-not-at-top, Delay for performance. import socket data = MessageToJSON(request) n = len(data) nstr = '%d' % n if len(nstr) > 5: raise ValueError('length too long') if (socket.has_ipv6 and encoding.GetEncodedValue( os.environ, DEVSHELL_ENV_IPV6_ENABLED) is not None): s = socket.socket(socket.AF_INET6) else: s = socket.socket() s.connect(('localhost', port)) msg = ('%s\n%s' % (nstr, data)).encode('utf8') s.sendall(msg) resp_1 = s.recv(6).decode('utf8') if '\n' not in resp_1: raise CommunicationError('saw no newline in the first 6 bytes') nstr, extra = resp_1.split('\n', 1) resp_buffer = extra n = int(nstr) to_read = n - len(extra) if to_read > 0: resp_buffer += s.recv(to_read, socket.MSG_WAITALL).decode('utf8') return JSONToMessage(resp_buffer, CredentialInfoResponse)
def main(): pargs = ParseArgs() update_manager.RestartIfUsingBundledPython( sdk_root=config.Paths().sdk_root, command=__file__) reinstall_components = encoding.GetEncodedValue( os.environ, 'CLOUDSDK_REINSTALL_COMPONENTS') try: if reinstall_components: ReInstall(reinstall_components.split(',')) else: Prompts(pargs.usage_reporting) bootstrapping.CommandStart('INSTALL', component_id='core') if not config.INSTALLATION_CONFIG.disable_updater: Install(pargs.override_components, pargs.additional_components) platforms_install.UpdateRC( completion_update=pargs.command_completion, path_update=pargs.path_update, rc_path=pargs.rc_path, bin_path=bootstrapping.BIN_DIR, sdk_root=bootstrapping.SDK_ROOT, ) print("""\ For more information on how to get started, please visit: https://cloud.google.com/sdk/docs/quickstarts """) except exceptions.ToolException as e: print(e) sys.exit(1)
def ArgsForPythonTool(executable_path, *args, **kwargs): """Constructs an argument list for calling the Python interpreter. Args: executable_path: str, The full path to the Python main file. *args: args for the command **kwargs: python: str, path to Python executable to use (defaults to automatically detected) Returns: An argument list to execute the Python interpreter Raises: TypeError: if an unexpected keyword argument is passed """ unexpected_arguments = set(kwargs) - set(['python']) if unexpected_arguments: raise TypeError( ("ArgsForPythonTool() got unexpected keyword arguments " "'[{0}]'").format(', '.join(unexpected_arguments))) python_executable = kwargs.get('python') or GetPythonExecutable() python_args_str = encoding.GetEncodedValue(os.environ, 'CLOUDSDK_PYTHON_ARGS', '') python_args = python_args_str.split() return _GetToolArgs(python_executable, python_args, executable_path, *args)
def __init__(self): self.sdk_root = config.Paths().sdk_root self.release_channel = config.INSTALLATION_CONFIG.release_channel self.repo_url = config.INSTALLATION_CONFIG.snapshot_url repos = properties.VALUES.component_manager.additional_repositories.Get( validate=False) self.additional_repos = repos.split(',') if repos else [] # Keep it as array for structured output. self.path = encoding.GetEncodedValue( os.environ, 'PATH', '').split(os.pathsep) self.python_path = sys.path if self.sdk_root: manager = update_manager.UpdateManager() self.components = manager.GetCurrentVersionsInformation() self.old_tool_paths = manager.FindAllOldToolsOnPath() self.duplicate_tool_paths = manager.FindAllDuplicateToolsOnPath() paths = [os.path.realpath(p) for p in self.path] this_path = os.path.realpath( os.path.join(self.sdk_root, update_manager.UpdateManager.BIN_DIR_NAME)) # TODO(b/36055867): Validate symlinks in /usr/local/bin when we start # creating them. self.on_path = this_path in paths else: self.components = {} self.old_tool_paths = [] self.duplicate_tool_paths = [] self.on_path = False self.kubectl = file_utils.SearchForExecutableOnPath('kubectl') if self.kubectl: self.kubectl = self.kubectl[0]
def _ActiveConfigNameFromEnv(): """Gets the currently active configuration according to the environment. Returns: str, The name of the active configuration or None. """ return encoding.GetEncodedValue(os.environ, config.CLOUDSDK_ACTIVE_CONFIG_NAME, None)
def ADCEnvVariable(): """Gets the value of the ADC environment variable. Returns: str, The value of the env var or None if unset. """ return encoding.GetEncodedValue(os.environ, environment_vars.CREDENTIALS, None)
def _GetNewConfigDirectory(): # Return the value of $DOCKER_CONFIG, if it exists, otherwise ~/.docker # see https://github.com/docker/docker/blob/master/cliconfig/config.go docker_config = encoding.GetEncodedValue(os.environ, 'DOCKER_CONFIG') if docker_config is not None: return docker_config else: return os.path.join(_GetUserHomeDir(), '.docker')
def SetUp(self): # Clear the environment variable set by the test housing so that we fall # through to config.Paths().sdk_root when getting the runtime definition # root. self.old_runtime_root = encoding.GetEncodedValue( os.environ, 'CLOUDSDK_APP_RUNTIME_ROOT') if self.old_runtime_root is not None: del os.environ['CLOUDSDK_APP_RUNTIME_ROOT']
def _GetDefaultLocale(self): """Determines the locale from the program's environment. Returns: String: Default locale, with a fallback to locale environment variables. """ env_vars = [ '%s:%s' % (var, encoding.GetEncodedValue(os.environ, var)) for var in ['LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'] if encoding.GetEncodedValue(os.environ, var) ] fallback_locale = '; '.join(env_vars) try: return locale.getdefaultlocale() except ValueError: return fallback_locale
def AdcEnvVariable(): """Gets the value of the ADC environment variable. Returns: str, The value of the env var or None if unset. """ return encoding.GetEncodedValue( os.environ, client.GOOGLE_APPLICATION_CREDENTIALS, None)
def _GetGKEKubeconfig(api_adapter, project, location_id, cluster_id, temp_kubeconfig_dir, internal_ip, cross_connect_subnetwork, private_endpoint_fqdn): """The kubeconfig of GKE Cluster is fetched using the GKE APIs. The 'KUBECONFIG' value in `os.environ` will be temporarily updated with the temporary kubeconfig's path if the kubeconfig arg is not None. Consequently, subprocesses started with googlecloudsdk.core.execution_utils.Exec will see the temporary KUBECONFIG environment variable. Using GKE APIs the GKE cluster is validated, and the ClusterConfig object, is persisted in the temporarily updated 'KUBECONFIG'. Args: api_adapter: the GKE api adapter used for running kubernetes commands project: string, the project id of the cluster for which kube config is to be fetched location_id: string, the id of the location to which the cluster belongs cluster_id: string, the id of the cluster temp_kubeconfig_dir: TemporaryDirectory object internal_ip: whether to persist the internal IP of the endpoint. cross_connect_subnetwork: full path of the cross connect subnet whose endpoint to persist (optional) private_endpoint_fqdn: whether to persist the private fqdn. Raises: Error: If unable to get credentials for kubernetes cluster. Returns: the path to the kubeconfig file """ kubeconfig = os.path.join(temp_kubeconfig_dir.path, 'kubeconfig') old_kubeconfig = encoding.GetEncodedValue(os.environ, 'KUBECONFIG') try: encoding.SetEncodedValue(os.environ, 'KUBECONFIG', kubeconfig) if api_adapter is None: api_adapter = gke_api_adapter.NewAPIAdapter('v1') cluster_ref = api_adapter.ParseCluster(cluster_id, location_id, project) cluster = api_adapter.GetCluster(cluster_ref) auth = cluster.masterAuth valid_creds = auth and auth.clientCertificate and auth.clientKey # c_util.ClusterConfig.UseGCPAuthProvider() checks for # container/use_client_certificate setting if not valid_creds and not c_util.ClusterConfig.UseGCPAuthProvider(): raise c_util.Error( 'Unable to get cluster credentials. User must have edit ' 'permission on {}'.format(cluster_ref.projectId)) c_util.ClusterConfig.Persist(cluster, cluster_ref.projectId, internal_ip, cross_connect_subnetwork, private_endpoint_fqdn) finally: if old_kubeconfig: encoding.SetEncodedValue(os.environ, 'KUBECONFIG', old_kubeconfig) else: del os.environ['KUBECONFIG'] return kubeconfig
def __init__(self, encoding=None, suppress_output=False): """Constructor. Args: encoding: Encoding override. ascii -- ASCII art. This is the default. utf8 -- UTF-8 unicode. win -- Windows code page 437. suppress_output: True to create a ConsoleAttr that doesn't want to output anything. """ # Normalize the encoding name. if not encoding: encoding = self._GetConsoleEncoding() elif encoding == 'win': encoding = 'cp437' self._encoding = encoding or 'ascii' self._term = '' if suppress_output else encoding_util.GetEncodedValue( os.environ, 'TERM', '').lower() # ANSI "standard" attributes. if self.SupportsAnsi(): # Select Graphic Rendition paramaters from # http://en.wikipedia.org/wiki/ANSI_escape_code#graphics # Italic '3' would be nice here but its not widely supported. self._csi = '\x1b[' self._font_bold = '1' self._font_italic = '4' else: self._csi = None self._font_bold = '' self._font_italic = '' # Encoded character attributes. is_screen_reader = properties.VALUES.accessibility.screen_reader.GetBool( ) if self._encoding == 'utf-8' and not is_screen_reader: self._box_line_characters = BoxLineCharactersUnicode() self._bullets = self._BULLETS_UNICODE self._progress_tracker_symbols = ProgressTrackerSymbolsUnicode() elif self._encoding == 'cp437' and not is_screen_reader: self._box_line_characters = BoxLineCharactersUnicode() self._bullets = self._BULLETS_WINDOWS # Windows does not suport the unicode characters used for the spinner. self._progress_tracker_symbols = ProgressTrackerSymbolsAscii() else: self._box_line_characters = BoxLineCharactersAscii() if is_screen_reader: self._box_line_characters = BoxLineCharactersScreenReader() self._bullets = self._BULLETS_ASCII self._progress_tracker_symbols = ProgressTrackerSymbolsAscii() # OS specific attributes. self._get_raw_key = [console_attr_os.GetRawKeyFunction()] self._term_size = ((0, 0) if suppress_output else console_attr_os.GetTermSize()) self._display_width_cache = {}
def __init__(self, stdout=1, stderr=2): super(_UnixCoshell, self).__init__() # The dup/close/dup dance preserves caller fds that collide with SHELL_*_FD. try: caller_shell_status_fd = os.dup(self.SHELL_STATUS_FD) except OSError: caller_shell_status_fd = -1 os.dup2(1, self.SHELL_STATUS_FD) try: caller_shell_stdin_fd = os.dup(self.SHELL_STDIN_FD) except OSError: caller_shell_stdin_fd = -1 os.dup2(0, self.SHELL_STDIN_FD) self._status_fd, w = os.pipe() os.dup2(w, self.SHELL_STATUS_FD) os.close(w) # Check for an alternate coshell command. coshell_command_line = encoding.GetEncodedValue( os.environ, COSHELL_ENV) if coshell_command_line: shell_command = coshell_command_line.split(' ') else: shell_command = [self.SHELL_PATH] # Python 3 adds a restore_signals kwarg to subprocess.Popen that defaults to # True, and has the effect of restoring the subprocess's SIGPIPE handler to # the default action. Python 2, on the other hand, keeps the modified # SIGPIPE handler for the subprocess. The coshell relies on the latter # behavior. additional_kwargs = {} if six.PY2 else {'restore_signals': False} self._shell = subprocess.Popen( shell_command, env=os.environ, # NOTE: Needed to pass mocked environ to children. stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, close_fds=False, **additional_kwargs) if caller_shell_status_fd >= 0: os.dup2(caller_shell_status_fd, self.SHELL_STATUS_FD) os.close(caller_shell_status_fd) else: os.close(self.SHELL_STATUS_FD) if caller_shell_stdin_fd >= 0: os.dup2(caller_shell_stdin_fd, self.SHELL_STDIN_FD) os.close(caller_shell_stdin_fd) else: os.close(self.SHELL_STDIN_FD) self._GetUserConfigDefaults()
def More(contents, out=None, prompt=None, check_pager=True): """Run a user specified pager or fall back to the internal pager. Args: contents: The entire contents of the text lines to page. out: The output stream, log.out (effectively) if None. prompt: The page break prompt. check_pager: Checks the PAGER env var and uses it if True. """ if not IsInteractive(output=True): if not out: out = log.out out.write(contents) return if not out: # Rendered help to the log file. log.file_only_logger.info(contents) # Paging shenanigans to stdout. out = sys.stdout if check_pager: pager = encoding.GetEncodedValue(os.environ, 'PAGER', None) if pager == '-': # Use the fallback Pager. pager = None elif not pager: # Search for a pager that handles ANSI escapes. for command in ('less', 'pager'): if files.FindExecutableOnPath(command): pager = command break if pager: # If the pager is less(1) then instruct it to display raw ANSI escape # sequences to enable colors and font embellishments. less_orig = encoding.GetEncodedValue(os.environ, 'LESS', None) less = '-R' + (less_orig or '') encoding.SetEncodedValue(os.environ, 'LESS', less) p = subprocess.Popen(pager, stdin=subprocess.PIPE, shell=True) enc = console_attr.GetConsoleAttr().GetEncoding() p.communicate(input=contents.encode(enc)) p.wait() if less_orig is None: encoding.SetEncodedValue(os.environ, 'LESS', None) return # Fall back to the internal pager. console_pager.Pager(contents, out, prompt).Run()
def ExecutePythonTool(tool_dir, exec_name, *args): """Execute the given python script with the given args and command line. Args: tool_dir: the directory the tool is located in exec_name: additional path to the executable under the tool_dir *args: args for the command """ py_path = None # Let execution_utils resolve the path. # Gsutil allows users to set the desired Python interpreter using a separate # environment variable, so as to allow users to run gsutil using Python 3 # without forcing the rest of the Cloud SDK to use Python 3 (as it would # likely break at the time this comment was written). if exec_name == 'gsutil': gsutil_py = encoding.GetEncodedValue(os.environ, 'CLOUDSDK_GSUTIL_PYTHON') if gsutil_py: py_path = gsutil_py if exec_name == 'bq.py': bq_py = encoding.GetEncodedValue(os.environ, 'CLOUDSDK_BQ_PYTHON') if bq_py: py_path = bq_py if exec_name == 'dev_appserver.py': if platforms.OperatingSystem.Current() != platforms.OperatingSystem.WINDOWS: # Hard code the python to 'python2' which should exist on most Unix based # systems. py_path = 'python2' else: # On windows attempt to use the bundled PY2 component. bundled_py2 = os.path.join( SDK_ROOT, 'platform', 'bundledpython2', 'python.exe') if os.path.exists(bundled_py2): py_path = bundled_py2 # Set this ENV var to explicitly select the python binary to use for # dev_appserver.py devapp_env_py = encoding.GetEncodedValue(os.environ, 'CLOUDSDK_DEVAPPSERVER_PYTHON') if devapp_env_py: py_path = devapp_env_py _ExecuteTool( execution_utils.ArgsForPythonTool( _FullPath(tool_dir, exec_name), *args, python=py_path))
def GetKubeconfigAndContext(self, flags): """Gets the kubeconfig and cluster context from arguments and defaults. Args: flags: the flags passed to the enclosing command. It must include kubeconfig and context. Returns: the kubeconfig filepath and context name Raises: calliope_exceptions.MinimumArgumentException: if a kubeconfig file cannot be deduced from the command line flags or environment exceptions.Error: if the context does not exist in the deduced kubeconfig file """ # We need to support in-cluster configuration so that gcloud can run from # a container on the Cluster we are registering. if not flags.kubeconfig and encoding.GetEncodedValue( os.environ, 'KUBERNETES_SERVICE_PORT') and encoding.GetEncodedValue( os.environ, 'KUBERNETES_SERVICE_HOST'): return None, None kubeconfig_file = (flags.kubeconfig or encoding.GetEncodedValue( os.environ, 'KUBECONFIG') or '~/.kube/config') kubeconfig = files.ExpandHomeDir(kubeconfig_file) if not kubeconfig: raise calliope_exceptions.MinimumArgumentException( ['--kubeconfig'], 'Please specify --kubeconfig, set the $KUBECONFIG environment ' 'variable, or ensure that $HOME/.kube/config exists') kc = kconfig.Kubeconfig.LoadFromFile(kubeconfig) context_name = flags.context if not context_name: raise exceptions.Error('argument --context: Must be specified.') if context_name not in kc.contexts: raise exceptions.Error( 'context [{}] does not exist in kubeconfig [{}]'.format( context_name, kubeconfig)) return kubeconfig, context_name
def GetChangedFiles(): with open(encoding.GetEncodedValue(os.environ, 'PRESUBMIT_FILE')) as f: lines = f.readlines() for line in lines: line = line.strip() if line.startswith(DEPOT_PREFIX): line = line[DEPOT_PREFIX_LEN:] yield line
def testSetEncodedValueAscii(self): d = {} self.assertEqual(d, {}) value = 'ascii' encoding.SetEncodedValue(d, 'foo', value) raw = d['foo'] # If we're in python 3, the raw value is not encoded. In python 2, the raw # value is encoded. self.assertEqual(six.PY3, isinstance(raw, six.text_type)) actual = encoding.GetEncodedValue(d, 'foo') self.assertTrue(isinstance(actual, six.text_type)) self.assertEqual(value, actual) actual = encoding.GetEncodedValue(d, 'bar') self.assertEqual(None, actual) actual = encoding.GetEncodedValue(d, 'bar', '') self.assertEqual('', actual)
def GetPythonExecutable(): """Gets the path to the Python interpreter that should be used.""" cloudsdk_python = encoding.GetEncodedValue(os.environ, 'CLOUDSDK_PYTHON') if cloudsdk_python: return cloudsdk_python python_bin = sys.executable if not python_bin: raise ValueError('Could not find Python executable.') return python_bin
def MakeProxyFromEnvironmentVariables(): """Returns the proxy string for use by grpc from environment variable.""" # The lowercase versions of these environment variable are already supported # by grpc. We add uppercase support for backwards-compatibility with http # API clients. for env in ['GRPC_PROXY', 'HTTP_PROXY', 'HTTPS_PROXY']: proxy = encoding.GetEncodedValue(os.environ, env) if proxy: return proxy return None
def _GetNewConfigDirectory(): # Return the value of $DOCKER_CONFIG, if it exists, otherwise ~/.docker # see https://github.com/moby/moby/blob/master/cli/config/configdir.go # NOTE: The preceding link is not owned by Google and cannot yet be updated to # address disrespectful term. docker_config = encoding.GetEncodedValue(os.environ, 'DOCKER_CONFIG') if docker_config is not None: return docker_config else: return os.path.join(_GetUserHomeDir(), '.docker')
def _GetGlobalConfigDir(): """Returns the path to the user's global config area. Returns: str: The path to the user's global config area. """ # Name of the directory that roots a cloud SDK workspace. global_config_dir = encoding.GetEncodedValue(os.environ, CLOUDSDK_CONFIG) if global_config_dir: return global_config_dir if platforms.OperatingSystem.Current() != platforms.OperatingSystem.WINDOWS: return os.path.join(file_utils.GetHomeDir(), '.config', _CLOUDSDK_GLOBAL_CONFIG_DIR_NAME) appdata = encoding.GetEncodedValue(os.environ, 'APPDATA') if appdata: return os.path.join(appdata, _CLOUDSDK_GLOBAL_CONFIG_DIR_NAME) # This shouldn't happen unless someone is really messing with things. drive = encoding.GetEncodedValue(os.environ, 'SystemDrive', 'C:') return os.path.join(drive, os.path.sep, _CLOUDSDK_GLOBAL_CONFIG_DIR_NAME)
def _Authenticate(self): """Authenticates the user. The authentication process works as follows: 1) We get a username and password from the user 2) We use ClientLogin to obtain an AUTH token for the user (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). 3) We pass the auth token to /_ah/login on the server to obtain an authentication cookie. If login was successful, it tries to redirect us to the URL we provided. If we attempt to access the upload API without first obtaining an authentication cookie, it returns a 401 response and directs us to authenticate ourselves with ClientLogin. """ for unused_i in range(self.auth_tries): credentials = self.auth_function() try: auth_token = self._GetAuthToken(credentials[0], credentials[1]) if encoding.GetEncodedValue(os.environ, "APPENGINE_RPC_USE_SID", "0") == "1": return except ClientLoginError as e: # TODO(user): some of these cases probably only pertain to the # obsolete username/password authentication. if e.reason == "CaptchaRequired": print >> sys.stderr, ( "Please go to\n" "https://www.google.com/accounts/DisplayUnlockCaptcha\n" "and verify you are a human. Then try again.") break if e.reason == "NotVerified": print >> sys.stderr, "Account not verified." break if e.reason == "TermsNotAgreed": print >> sys.stderr, "User has not agreed to TOS." break if e.reason == "AccountDeleted": print >> sys.stderr, "The user account has been deleted." break if e.reason == "AccountDisabled": print >> sys.stderr, "The user account has been disabled." break if e.reason == "ServiceDisabled": print >> sys.stderr, ( "The user's access to the service has been " "disabled.") break if e.reason == "ServiceUnavailable": print >> sys.stderr, "The service is not available; try again later." break raise self._GetAuthCookie(auth_token) return
def main(): sys.path = reorder_sys_path(sys.path) # pylint:disable=g-import-not-at-top from googlecloudsdk.core.util import encoding if encoding.GetEncodedValue(os.environ, '_ARGCOMPLETE'): try: # pylint:disable=g-import-not-at-top import googlecloudsdk.command_lib.static_completion.lookup as lookup lookup.Complete() return except Exception: # pylint:disable=broad-except, hide completion errors if encoding.GetEncodedValue(os.environ, '_ARGCOMPLETE_TRACE') == 'static': raise try: _fix_google_module() gcloud_main = _import_gcloud_main() except Exception as err: # pylint: disable=broad-except # We want to catch *everything* here to display a nice message to the user # pylint:disable=g-import-not-at-top import traceback # We DON'T want to suggest `gcloud components reinstall` here (ex. as # opposed to the similar message in gcloud_main.py), as we know that no # commands will work. sys.stderr.write(( 'ERROR: gcloud failed to load: {0}\n{1}\n\n' 'This usually indicates corruption in your gcloud installation or ' 'problems with your Python interpreter.\n\n' 'Please verify that the following is the path to a working Python 2.7 ' 'or 3.5+ executable:\n' ' {2}\n\n' 'If it is not, please set the CLOUDSDK_PYTHON environment variable to ' 'point to a working Python 2.7 or 3.5+ executable.\n\n' 'If you are still experiencing problems, please reinstall the Cloud ' 'SDK using the instructions here:\n' ' https://cloud.google.com/sdk/\n').format( err, '\n'.join(traceback.format_exc().splitlines()[2::2]), sys.executable)) sys.exit(1) sys.exit(gcloud_main.main())
def Prompts(usage_reporting): """Display prompts to opt out of usage reporting. Args: usage_reporting: bool, If True, enable usage reporting. If None, check the environmental variable. If None, check if its alternate release channel. If not, ask. """ if usage_reporting is None: if encoding.GetEncodedValue( os.environ, 'CLOUDSDK_CORE_DISABLE_USAGE_REPORTING') is not None: usage_reporting = not encoding.GetEncodedValue( os.environ, 'CLOUDSDK_CORE_DISABLE_USAGE_REPORTING') else: if config.InstallationConfig.Load().IsAlternateReleaseChannel(): usage_reporting = True print(""" Usage reporting is always on for alternate release channels. """) else: print(""" To help improve the quality of this product, we collect anonymized usage data and anonymized stacktraces when crashes are encountered; additional information is available at <https://cloud.google.com/sdk/usage-statistics>. This data is handled in accordance with our privacy policy <https://cloud.google.com/terms/cloud-privacy-notice>. You may choose to opt in this collection now (by choosing 'Y' at the below prompt), or at any time in the future by running the following command: gcloud config set disable_usage_reporting false """) usage_reporting = console_io.PromptContinue( prompt_string= 'Do you want to help improve the Google Cloud CLI', default=False) properties.PersistProperty(properties.VALUES.core.disable_usage_reporting, not usage_reporting, scope=properties.Scope.INSTALLATION)
def IsInteractive(output=False, error=False, heuristic=False): """Determines if the current terminal session is interactive. sys.stdin must be a terminal input stream. Args: output: If True then sys.stdout must also be a terminal output stream. error: If True then sys.stderr must also be a terminal output stream. heuristic: If True then we also do some additional heuristics to check if we are in an interactive context. Checking home path for example. Returns: True if the current terminal session is interactive. """ try: if not sys.stdin.isatty(): return False if output and not sys.stdout.isatty(): return False if error and not sys.stderr.isatty(): return False except AttributeError: # This should only occur when one of the streams is not open. return False if heuristic: # Check the home path. Most startup scripts for example are executed by # users that don't have a home path set. Home is OS dependent though, so # check everything. # *NIX OS usually sets the HOME env variable. It is usually '/home/user', # but can also be '/root'. If it's just '/' we are most likely in an init # script. # Windows usually sets HOMEDRIVE and HOMEPATH. If they don't exist we are # probably being run from a task scheduler context. HOMEPATH can be '\' # when a user has a network mapped home directory. # Cygwin has it all! Both Windows and Linux. Checking both is perfect. home = encoding.GetEncodedValue(os.environ, 'HOME') homepath = encoding.GetEncodedValue(os.environ, 'HOMEPATH') if not homepath and (not home or home == '/'): return False return True
def testSetEncodedValueUnicode(self): self.StartObjectPatch(sys, 'getfilesystemencoding').return_value = 'utf-8' d = {} self.assertEqual(d, {}) value = 'Ṳᾔḯ¢◎ⅾℯ' encoding.SetEncodedValue(d, 'foo', value) raw = d['foo'] # If we're in python 3, the raw value is not encoded. In python 2, the raw # value is encoded. self.assertEqual(six.PY3, isinstance(raw, six.text_type)) actual = encoding.GetEncodedValue(d, 'foo') self.assertTrue(isinstance(actual, six.text_type)) self.assertEqual(value, actual)
def __init__(self, **kwargs): test_parameters = encoding.GetEncodedValue(os.environ, '_ARGCOMPLETE_TEST', 'parameters=bad') kwargs = dict(kwargs) for pair in test_parameters.split(','): name, value = pair.split('=') kwargs[name] = value if 'collection' not in kwargs or 'list_command' not in kwargs: raise TestParametersRequired( 'Specify test completer parameters in the _ARGCOMPLETE_TEST ' 'environment variable. It is a comma-separated separated list of ' 'name=value test parameters and must contain at least ' '"collection=COLLECTION,list_command=LIST COMMAND" parameters.') super(TestCompleter, self).__init__(**kwargs)
def SetUp(self): git_path = files.FindExecutableOnPath('git') if not git_path: self.skipTest('Git is not available') # The system under which we are testing could have credential manager # installed at system or global level. It could interfere with gcloud # credential manager. Overriding global to be empty will override system and # global setting. home_dir = os.path.join(self.temp_path, 'home') self.prev_home_dir = encoding.GetEncodedValue(os.environ, 'HOME') os.environ['HOME'] = home_dir self.Touch(home_dir, '.gitconfig', contents=GIT_CONFIG, makedirs=True) # Synthesize gcloud wrapper script and add it to the path so that git can # invoke it. This way we guarantee that gcloud under test will be invoked. if (platforms.OperatingSystem.Current() == platforms.OperatingSystem.WINDOWS): gcloud_ext = '.cmd' script_template = """\ @echo off "%COMSPEC%" /C "{} {} %*" "%COMSPEC%" /C exit %ERRORLEVEL% """ else: gcloud_ext = '' script_template = """\ #!/bin/bash {} {} $@ """ local_bin_dir = os.path.join(self.temp_path, 'bin') gcloud_script = self.Touch(local_bin_dir, 'gcloud' + gcloud_ext, contents=script_template.format( sys.executable, gcloud.__file__), makedirs=True) st = os.stat(gcloud_script) os.chmod(gcloud_script, st.st_mode | stat.S_IEXEC) self.old_bin_path = os.environ['PATH'] os.environ['PATH'] = os.pathsep.join( [local_bin_dir, self.old_bin_path]) # Make sure there is plenty of diagnosing data in case of test failure. os.environ['GIT_CURL_VERBOSE'] = '1' os.environ['GIT_TRACE'] = '1' properties.VALUES.core.print_unhandled_tracebacks.Set(True) properties.VALUES.core.print_handled_tracebacks.Set(True)