def _PrintUrl(service_name, events_port, stop): """Read the local url of a service from the event stream and print it. Read the event stream api and find the portForward events. Print the local url as determined from the portFoward events. This function will continuously listen to the event stream and print out all local urls until eitherthe event stream connection closes or the stop event is set. Args: service_name: Name of the service. events_port: Port number of the skaffold events stream api. stop: threading.Event event. """ try: with contextlib.closing(_OpenEventStreamRetry(events_port, stop)) as response: for port in GetServiceLocalPort(response, service_name): # If the thread has been signaled to stop, don't print out the url if stop.is_set(): return con = console_attr.GetConsoleAttr() msg = 'Service URL: {bold}{url}{normal}'.format( bold=con.GetFontCode(bold=True), url='http://localhost:%s/' % port, normal=con.GetFontCode()) # Sleep for a second to make sure the URL is printed below the start # up logs printed by skaffold.' stop.wait(1) log.status.Print(con.Colorize(msg, color='blue')) except StopThreadError: return
def __init__(self, message, autotick, detail_message_callback, tick_delay, interruptable, aborted_message, spinner_override_message): self._stream = sys.stderr if message is None: self._spinner_only = True self._message = '' self._prefix = '' else: self._spinner_only = False self._message = message self._prefix = message + '...' self._detail_message_callback = detail_message_callback self.spinner_override_message = spinner_override_message self._ticks = 0 self._done = False self._lock = threading.Lock() self._tick_delay = tick_delay self._ticker = None console_width = console_attr.ConsoleAttr().GetTermSize()[0] if console_width < 0: # This can happen if we're on a pseudo-TTY. Set it to 0 and also # turn off output to prevent hanging. console_width = 0 self._output_enabled = log.IsUserOutputEnabled() and console_width != 0 # Don't bother autoticking if we aren't going to print anything. self.__autotick = autotick and self._output_enabled self._interruptable = interruptable self._aborted_message = aborted_message self._old_signal_handler = None self._symbols = console_attr.GetConsoleAttr().GetProgressTrackerSymbols()
def _Write(self, msg, styled_msg): """Just a helper so we don't have to double encode from Print and write. Args: msg: A text string that only has characters that are safe to encode with utf-8. styled_msg: A text string with the same properties as msg but also contains ANSI control sequences. """ # The log file always uses utf-8 encoding, just give it the string. self.__logger.info(msg) if self.__filter.enabled: # Make sure the string is safe to print in the console. The console might # have a more restrictive encoding than utf-8. stream_encoding = console_attr.GetConsoleAttr().GetEncoding() stream_msg = console_attr.SafeText(styled_msg, encoding=stream_encoding, escape=False) if six.PY2: # Encode to byte strings for output only on Python 2. stream_msg = styled_msg.encode(stream_encoding or 'utf8', 'replace') self.__stream_wrapper.stream.write(stream_msg) if self.__always_flush: self.flush()
def __init__(self, *args, **kwargs): """Creates a new TablePrinter.""" self._rows = [] super(TablePrinter, self).__init__(*args, by_columns=True, non_empty_projection_required=True, **kwargs) encoding = None for name in ['ascii', 'utf8', 'win']: if name in self.attributes: encoding = name break if not self._console_attr: self._console_attr = console_attr.GetConsoleAttr(encoding=encoding) self._csi = self._console_attr.GetControlSequenceIndicator() self._page_count = 0 # Check for subformat columns. self._optional = False self._subformats = [] self._has_subprinters = False has_subformats = False self._aggregate = True if self.column_attributes: for col in self.column_attributes.Columns(): if col.attribute.subformat or col.attribute.hidden: has_subformats = True else: self._aggregate = False if col.attribute.optional: self._optional = True if col.attribute.wrap: self._wrap = True defaults = resource_projection_spec.ProjectionSpec( symbols=self.column_attributes.symbols) index = 0 for col in self.column_attributes.Columns(): if col.attribute.subformat: # This initializes a nested Printer to a string stream. out = self._out if self._aggregate else io.StringIO() wrap = None printer = self.Printer(col.attribute.subformat, out=out, console_attr=self._console_attr, defaults=defaults) self._has_subprinters = True else: out = None printer = None wrap = col.attribute.wrap self._subformats.append( SubFormat(index, col.attribute.hidden, printer, out, wrap)) index += 1 self._visible = None if not has_subformats: self._subformats = None self._aggregate = False elif self._subformats and not self._aggregate: self._visible = [] for subformat in self._subformats: if not subformat.hidden and not subformat.printer: self._visible.append(subformat.index)
def __init__(self, message, stages, success_message, failure_message, autotick, tick_delay, interruptable, aborted_message, tracker_id, done_message_callback): super(_BaseStagedProgressTracker, self).__init__(stages) self._stream = sys.stderr # TODO(b/111637901): Support detailed message callback when true multiline # support is available. self._message = message self._success_message = success_message self._failure_message = failure_message self._aborted_message = aborted_message self._done_message_callback = done_message_callback self._tracker_id = tracker_id console_width = console_attr.ConsoleAttr().GetTermSize()[0] if console_width < 0: # This can happen if we're on a pseudo-TTY. Set it to 0 and also # turn off output to prevent hanging. console_width = 0 self._output_enabled = log.IsUserOutputEnabled() and console_width != 0 # Don't bother autoticking if we aren't going to print anything. self.__autotick = autotick and self._output_enabled self._interruptable = interruptable self._tick_delay = tick_delay self._symbols = console_attr.GetConsoleAttr().GetProgressTrackerSymbols() self._done = False self._exception_is_uncaught = True self._ticks = 0 self._ticker = None self._running_stages = set() self._completed_stages = [] self._lock = threading.Lock()
def __init__(self, height=0, encoding='utf8', compact=True, *args, **kwargs): super(TokenRenderer, self).__init__(*args, **kwargs) self._attr = console_attr.GetConsoleAttr(encoding=encoding) self._csi = self.CSI self._attr._csi = self._csi # pylint: disable=protected-access self._blank = True self._bullet = self._attr.GetBullets() self._compact = compact self._fill = 0 self._current_token_type = Token.Markdown.Normal self._height = height self._ignore_paragraph = False self._ignore_width = False self._indent = [self.Indent(compact)] self._level = 0 self._lines = [] self._table = False self._tokens = [] self._truncated = False self._rows = []
def __init__(self, contents, out=None, prompt=None): """Constructor. 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, a defalt prompt is used if None.. """ self._contents = contents self._out = out or sys.stdout self._search_pattern = None self._search_direction = None # prev_pos, prev_next values to force reprint self.prev_pos, self.prev_nxt = self.PREV_POS_NXT_REPRINT # Initialize the console attributes. self._attr = console_attr.GetConsoleAttr() self._width, self._height = self._attr.GetTermSize() # Initialize the prompt and the prompt clear string. if not prompt: prompt = '{bold}--({{percent}}%)--{normal}'.format( bold=self._attr.GetFontCode(bold=True), normal=self._attr.GetFontCode()) self._clear = '\r{0}\r'.format(' ' * (self._attr.DisplayWidth(prompt) - 6)) self._prompt = prompt # Initialize a list of lines with long lines split into separate display # lines. self._lines = [] for line in contents.splitlines(): self._lines += self._attr.SplitLine(line, self._width)
def MakeUserAgentString(cmd_path=None): """Return a user-agent string for this request. Contains 'gcloud' in addition to several other product IDs used for tracing in metrics reporting. Args: cmd_path: str representing the current command for tracing. Returns: str, User Agent string. """ return ( 'gcloud/{version}' ' command/{cmd}' ' invocation-id/{inv_id}' ' environment/{environment}' ' environment-version/{env_version}' ' interactive/{is_interactive}' ' from-script/{from_script}' ' python/{py_version}' ' term/{term}' ' {ua_fragment}').format( version=config.CLOUD_SDK_VERSION.replace(' ', '_'), cmd=(cmd_path or properties.VALUES.metrics.command_name.Get()), inv_id=uuid.uuid4().hex, environment=properties.GetMetricsEnvironment(), env_version=properties.VALUES.metrics.environment_version.Get(), is_interactive=console_io.IsInteractive(error=True, heuristic=True), py_version=platform.python_version(), ua_fragment=platforms.Platform.Current().UserAgentFragment(), from_script=console_io.IsRunFromShellScript(), term=console_attr.GetConsoleAttr().GetTermIdentifier())
def __init__(self, message, autotick, detail_message_callback, tick_delay, interruptable, aborted_message): if message is None: self._spinner_only = True self._message = '' self._prefix = '' self._suffix = '' else: self._spinner_only = False self._message = message self._prefix = message + '...' self._suffix = 'done.' self._stream = sys.stderr self._ticks = 0 self._done = False self._lock = threading.Lock() self._detail_message_callback = detail_message_callback self._multi_line = False self._last_display_message = '' self._tick_delay = tick_delay self._is_tty = console_io.IsInteractive(error=True) self._ticker = None self._output_enabled = log.IsUserOutputEnabled() # Don't bother autoticking if we aren't going to print anything. self.__autotick = autotick and self._output_enabled self._interruptable = interruptable self._aborted_message = aborted_message self._old_signal_handler = None self._symbols = console_attr.GetConsoleAttr( ).GetProgressTrackerSymbols()
def CallToAction(self, record): """Call to action to configure IP for the domain. Args: record: dict, the integration. Returns: A formatted string of the call to action message, or None if no call to action is required. """ resource_config = record.get('config') resource_status = record.get('status') if not resource_status or not resource_status: return None domain = resource_config.get('router', {}).get('domain') resource_components = resource_status.get('resourceComponentStatuses', {}) ssl_status = self._GetSSLStatus(resource_components) ip = resource_status.get('routerDetails', {}).get('ipAddress') if domain and ip and ssl_status != states.ACTIVE: domain_padding = len(domain) - len('NAME') padding_string = ' ' * domain_padding con = console_attr.GetConsoleAttr() return ('{0} To complete the process, please ensure the following ' 'DNS records are configured for the domain "{1}":\n' ' NAME{2} TTL TYPE DATA\n' ' {1} 3600 A {3}\n' 'It can take up to an hour for the certificate to be provisioned.' .format(con.Colorize('!', 'yellow'), domain, padding_string, ip)) return None
def __init__(self, *args, **kwargs): """Creates a new TablePrinter.""" self._rows = [] super(TablePrinter, self).__init__(*args, by_columns=True, non_empty_projection_required=True, **kwargs) encoding = None for name in ['ascii', 'utf8', 'win']: if name in self.attributes: encoding = name break if not self._console_attr: self._console_attr = console_attr.GetConsoleAttr(encoding=encoding, out=self._out) self._rows_per_page = self.attributes.get('page', 0) if self._rows_per_page: log.warn('The [page=N] printer attribute is deprecated. ' 'Use the --page-size=N flag instead.') self._page_count = 0 # Check for subformat columns. self._optional = False self._subformats = [] self._has_subprinters = False has_subformats = False self._aggregate = True if self.column_attributes: for col in self.column_attributes.Columns(): if col.attribute.subformat or col.attribute.hidden: has_subformats = True else: self._aggregate = False if col.attribute.optional: self._optional = True index = 0 for col in self.column_attributes.Columns(): if col.attribute.subformat: # This initializes a nested Printer to a string stream. out = self._out if self._aggregate else StringIO.StringIO() printer = self.Printer(col.attribute.subformat, out=out, console_attr=self._console_attr, defaults=self.column_attributes) self._has_subprinters = True else: out = None printer = None self._subformats.append( SubFormat(index, col.attribute.hidden, printer, out)) index += 1 self._visible = None if not has_subformats: self._subformats = None self._aggregate = False elif self._subformats and not self._aggregate: self._visible = [] for subformat in self._subformats: if not subformat.hidden and not subformat.printer: self._visible.append(subformat.index)
def _GetReadyMessage(self, record): if record.ready_condition and record.ready_condition['message']: symbol, color = record.ReadySymbolAndColor() return console_attr.GetConsoleAttr().Colorize( textwrap.fill('{} {}'.format( symbol, record.ready_condition['message']), 100), color) else: return ''
def __init__(self, out_stream): super(_ConsoleFormatter, self).__init__() use_color = not properties.VALUES.core.disable_color.GetBool( validate=False) use_color &= out_stream.isatty() use_color &= console_attr.GetConsoleAttr().SupportsAnsi() self._formats = (_ConsoleFormatter.COLOR_FORMATS if use_color else _ConsoleFormatter.FORMATS)
def __init__(self, ofile, timeout, tick_delay, background_ttl, autotick): self._ofile = ofile or self._GetStream() self._timeout = timeout self._tick_delay = tick_delay self.__autotick = autotick self._background_ttl = background_ttl self._ticks = 0 self._symbols = console_attr.GetConsoleAttr().GetProgressTrackerSymbols()
def testConsoleAttrStateResetTermSize(self): console_attr.ConsoleAttr._CONSOLE_ATTR_STATE = None console_attr.GetConsoleAttr() self.assertEqual(self._get_term_size_windows_mock.call_count, 1) console_attr.GetConsoleAttr() self.assertEqual(self._get_term_size_windows_mock.call_count, 1) console_attr.GetConsoleAttr(encoding='mock') self.assertEqual(self._get_term_size_windows_mock.call_count, 2) console_attr.GetConsoleAttr() self.assertEqual(self._get_term_size_windows_mock.call_count, 2) console_attr.ResetConsoleAttr() self.assertEqual(self._get_term_size_windows_mock.call_count, 3) console_attr.GetConsoleAttr() self.assertEqual(self._get_term_size_windows_mock.call_count, 3)
def __init__(self, set_spinner): self._done_loading = False self._spin_marks = console_attr.GetConsoleAttr()\ .GetProgressTrackerSymbols().spin_marks self._ticker = None self._ticker_index = 0 self._ticker_length = len(self._spin_marks) self._set_spinner = set_spinner
def _GetRevisionHeader(self, record): header = '' if record.status is None: header = 'Unknown revision' else: header = 'Revision {}'.format( record.status.latestCreatedRevisionName) return console_attr.GetConsoleAttr().Emphasize(header)
def _GetServiceHeader(self, record): con = console_attr.GetConsoleAttr() status = con.Colorize(*record.ReadySymbolAndColor()) try: place = 'region ' + record.region except KeyError: place = 'namespace ' + record.namespace return con.Emphasize('{} Service {} in {}'.format( status, record.name, place))
def CheckRedirectionPermission(project): con = console_attr.GetConsoleAttr() authorized = ar_requests.TestRedirectionIAMPermission(project) if not authorized: log.status.Print( con.Colorize("FAIL: ", "red") + "This operation requires " "the {} permission(s) on project {}.".format( ",".join(ar_requests.REDIRECT_PERMISSIONS), project)) return authorized
def __init__(self, *args, **kwargs): super(TextRenderer, self).__init__(*args, **kwargs) # We want the rendering to match the default console encoding. self._out # could be a file or pipe to a pager, either way we still want to see rich # encoding if the console supports it. encoding = console_attr.GetConsoleAttr().GetEncoding() self._attr = console_attr.GetConsoleAttr(out=self._out, encoding=encoding) self._blank = True self._bullet = self._attr.GetBullets() self._csi_char = self._attr.GetControlSequenceIndicator() if self._csi_char: self._csi_char = self._csi_char[0] self._fill = 0 self._ignore_width = False self._indent = [self.Indent()] self._level = 0 self._table = False
def GetReadySymbol(ready): encoding = console_attr.GetConsoleAttr().GetEncoding() if ready == kubernetes_consts.VAL_UNKNOWN: return _PickSymbol('\N{HORIZONTAL ELLIPSIS}', '.', encoding) elif (ready == kubernetes_consts.VAL_TRUE or ready == kubernetes_consts.VAL_READY): return _PickSymbol('\N{HEAVY CHECK MARK}', '+', encoding) else: return 'X'
def GetStyleMappings(console_attributes=None): console_attributes = console_attributes or console_attr.GetConsoleAttr() if console_attributes.SupportsAnsi(): if console_attributes._term == 'xterm-256color': # pylint: disable=protected-access return STYLE_MAPPINGS_ANSI_256 else: return STYLE_MAPPINGS_ANSI else: return STYLE_MAPPINGS_BASIC
def testEncodingStdOutUtf8(self): sys.stdout = mock.MagicMock() sys.stdout.encoding = 'UTF-8' log.Reset() attr = console_attr.GetConsoleAttr(reset=True) locale_encoding = locale.getpreferredencoding() if locale_encoding and 'cp1252' in locale_encoding: self.assertEqual(attr.GetEncoding(), 'ascii') else: self.assertEqual(attr.GetEncoding(), 'utf8')
def _ConvertNonAsciiArgsToUnicode(self, args): """Converts non-ascii args to unicode. The args most likely came from sys.argv, and Python 2.7 passes them in as bytestrings instead of unicode. Args: args: [str], The list of args to convert. Raises: InvalidCharacterInArgException if a non-ascii arg cannot be converted to unicode. Returns: A new list of args with non-ascii args converted to unicode. """ console_encoding = console_attr.GetConsoleAttr().GetEncoding() filesystem_encoding = sys.getfilesystemencoding() argv = [] for arg in args: try: arg.encode('ascii') # Already ascii. argv.append(arg) continue except UnicodeError: pass try: # Convert bytestring to unicode using the console encoding. argv.append(unicode(arg, console_encoding)) continue except TypeError: # Already unicode. argv.append(arg) continue except UnicodeError: pass try: # Convert bytestring to unicode using the filesystem encoding. # A pathname could have been passed in rather than typed, and # might not match the user terminal encoding, but still be a valid # path. For example: $ foo $(grep -l bar *) argv.append(unicode(arg, filesystem_encoding)) continue except UnicodeError: pass # Can't convert to unicode -- bail out. raise exceptions.InvalidCharacterInArgException([self.name] + args, arg) return argv
def _Print(prefix, color, msg, **formatters): """Helper function to avoid import-time races.""" con = console_attr.GetConsoleAttr() con.Colorize(prefix, color) formatters = formatters.copy() formatters.update({ 'bold': con.GetFontCode(bold=True), 'italic': con.GetFontCode(italic=True), 'reset': con.GetFontCode(), }) log.status.Print(msg.format(**formatters))
def __init__(self, *args, **kwargs): """Creates a new TablePrinter.""" self._rows = [] super(TablePrinter, self).__init__(*args, by_columns=True, **kwargs) encoding = None for name in ['ascii', 'utf8', 'win']: if name in self._attributes: encoding = name break self._console_attr = console_attr.GetConsoleAttr(encoding=encoding, out=self._out)
def _PrintCopyInstruction(self, auth_response): con = console_attr.GetConsoleAttr() log.status.write(self._COPY_AUTH_RESPONSE_INSTRUCTION + ' ') log.status.Print( self._COPY_AUTH_RESPONSE_WARNING.format( bold=con.GetFontCode(bold=True), command=self._target_command, normal=con.GetFontCode())) log.status.write('\n') log.status.Print(auth_response)
def __init__(self, *args, **kwargs): super(TextRenderer, self).__init__(*args, **kwargs) self._attr = console_attr.GetConsoleAttr() self._bullet = self._attr.GetBullets() self._csi_char = self._attr.GetControlSequenceIndicator() if self._csi_char: self._csi_char = self._csi_char[0] self._fill = 0 self._ignore_width = False self._indent = [self.Indent()] self._level = 0
def ready_symbol(self): """Return a symbol summarizing the status of this object.""" # NB: This can be overridden by subclasses to allow symbols for more # complex reasons the object isn't ready. Ex: Service overrides it to # provide '!' for "I'm serving, but not the revision you wanted." encoding = console_attr.GetConsoleAttr().GetEncoding() if self.ready is None: return self._PickSymbol('\N{HORIZONTAL ELLIPSIS}', '.', encoding) elif self.ready: return self._PickSymbol('\N{HEAVY CHECK MARK}', '+', encoding) else: return 'X'
def GetRedirectionEnablementReport(project): """Prints a redirection enablement report and returns mis-configured repos. This checks all the GCR repositories in the supplied project and checks if they each have a repository in Artifact Registry create to be the redirection target. It prints a report as it validates. Args: project: The project to validate Returns: A list of the GCR repos that do not have a redirection repo configured in Artifact Registry. """ locations = ar_requests.ListLocations(project, 100) # Sorting is performed so that Python2 & 3 agree on the order of API calls # in scenario tests. gcr_repos = GetExistingGCRBuckets( sorted(_GCR_BUCKETS.values(), key=lambda x: x["repository"]), project) failed_repos = [] repo_report = [] report_line = [] con = console_attr.GetConsoleAttr() # For each gcr repo in a location that our environment supports, # is there an associated repo in AR? for gcr_repo in gcr_repos: if gcr_repo["location"] in locations: report_line = [gcr_repo["repository"], gcr_repo["location"]] ar_repo_name = "projects/{}/locations/{}/repositories/{}".format( project, gcr_repo["location"], gcr_repo["repository"]) try: ar_repo = ar_requests.GetRepository(ar_repo_name) report_line.append(con.Colorize(ar_repo.name, "green")) except apitools_exceptions.HttpNotFoundError: report_line.append(con.Colorize("NOT FOUND", "red")) failed_repos.append(gcr_repo) repo_report.append(report_line) log.status.Print("Redirection enablement report:\n") printer = resource_printer.Printer("table", out=log.status) printer.AddHeading([ con.Emphasize("Container Registry Host", bold=True), con.Emphasize("Location", bold=True), con.Emphasize("Artifact Registry Repository", bold=True) ]) for line in repo_report: printer.AddRecord(line) printer.Finish() log.status.Print() return failed_repos