コード例 #1
0
    def ListDebuggees(self, include_inactive=False, include_stale=False):
        """Lists all debug targets registered with the debug service.

    Args:
      include_inactive: If true, also include debuggees that are not currently
        running.
      include_stale: If false, filter out any debuggees that refer to
        stale minor versions. A debugge represents a stale minor version if it
        meets the following criteria:
            1. It has a minorversion label.
            2. All other debuggees with the same name (i.e., all debuggees with
               the same module and version, in the case of app engine) have a
               minorversion label.
            3. The minorversion value for the debuggee is less than the
               minorversion value for at least one other debuggee with the same
               name.
    Returns:
      [Debuggee] A list of debuggees.
    """
        request = self._debug_messages.ClouddebuggerDebuggerDebuggeesListRequest(
            project=self._project,
            includeInactive=include_inactive,
            clientVersion=self.CLIENT_VERSION)
        try:
            response = self._debug_client.debugger_debuggees.List(request)
        except apitools_exceptions.HttpError as error:
            raise errors.UnknownHttpError(error)

        result = [Debuggee(debuggee) for debuggee in response.debuggees]

        if not include_stale:
            return _FilterStaleMinorVersions(result)

        return result
コード例 #2
0
    def WaitForBreakpointSet(self,
                             breakpoint_id,
                             original_location,
                             timeout=None,
                             retry_ms=500):
        """Waits for a breakpoint to be set by at least one agent.

      Breakpoint set can be detected in two ways: it can be completed, or the
      location may change if the breakpoint could not be set at the specified
      location. A breakpoint may also be set without any change being reported
      to the server, in which case this function will wait until the timeout
      is reached.
    Args:
      breakpoint_id: A breakpoint ID.
      original_location: string, the user-specified breakpoint location. If a
        response has a different location, the function will return immediately.
      timeout: The number of seconds to wait for completion.
      retry_ms: Milliseconds to wait betweeen retries.
    Returns:
      The Breakpoint message, or None if the breakpoint did not get set before
      the timeout.
    """
        def MovedOrFinal(r):
            return (r.breakpoint.isFinalState
                    or (original_location and original_location !=
                        _FormatLocation(r.breakpoint.location)))

        try:
            return self.WaitForBreakpoint(breakpoint_id=breakpoint_id,
                                          timeout=timeout,
                                          retry_ms=retry_ms,
                                          completion_test=MovedOrFinal)
        except apitools_exceptions.HttpError as error:
            raise errors.UnknownHttpError(error)
コード例 #3
0
    def RegisterDebuggee(self, description, uniquifier, agent_version=None):
        """Register a debuggee with the Cloud Debugger.

    This method is primarily intended to simplify testing, since it registering
    a debuggee is only a small part of the functionality of a debug agent, and
    the rest of the API is not supported here.
    Args:
      description: A concise description of the debuggee.
      uniquifier: A string uniquely identifying the debug target. Note that the
        uniquifier distinguishes between different deployments of a service,
        not between different replicas of a single deployment. I.e., all
        replicas of a single deployment should report the same uniquifier.
      agent_version: A string describing the program registering the debuggee.
        Defaults to "google.com/gcloud/NNN" where NNN is the gcloud version.
    Returns:
      The registered Debuggee.
    """
        if not agent_version:
            agent_version = self.CLIENT_VERSION
        request = self._debug_messages.RegisterDebuggeeRequest(
            debuggee=self._debug_messages.Debuggee(project=self._project,
                                                   description=description,
                                                   uniquifier=uniquifier,
                                                   agentVersion=agent_version))
        try:
            response = self._debug_client.controller_debuggees.Register(
                request)
        except apitools_exceptions.HttpError as error:
            raise errors.UnknownHttpError(error)
        return Debuggee(response.debuggee)
コード例 #4
0
  def CreateLogpoint(self, location, log_format_string, log_level=None,
                     condition=None, user_email=None, labels=None):
    """Creates a logpoint in the debuggee.

    Args:
      location: The breakpoint source location, which will be interpreted by
        the debug agents on the machines running the Debuggee. Usually of the
        form file:line-number
      log_format_string: The message to log, optionally containin {expression}-
        style formatting.
      log_level: String (case-insensitive), one of 'info', 'warning', or
        'error', indicating the log level that should be used for logging.
      condition: An optional conditional expression in the target's programming
        language. The snapshot will be taken when the expression is true.
      user_email: The email of the user who created the snapshot.
      labels: A dictionary containing key-value pairs which will be stored
        with the snapshot definition and reported when the snapshot is queried.
    Returns:
      The created Breakpoint message.
    Raises:
      InvalidLocationException: if location is empty or malformed.
      InvalidLogFormatException: if log_format is empty or malformed.
    """
    if not location:
      raise errors.InvalidLocationException(
          'The location must not be empty.')
    if not log_format_string:
      raise errors.InvalidLogFormatException(
          'The log format string must not be empty.')
    labels_value = None
    if labels:
      labels_value = self._debug_messages.Breakpoint.LabelsValue(
          additionalProperties=[
              self._debug_messages.Breakpoint.LabelsValue.AdditionalProperty(
                  key=key, value=value)
              for key, value in six.iteritems(labels)])
    location = self._LocationFromString(location)
    if log_level:
      log_level = (
          self._debug_messages.Breakpoint.LogLevelValueValuesEnum(
              log_level.upper()))
    log_message_format, expressions = SplitLogExpressions(log_format_string)
    request = (
        self._debug_messages.
        ClouddebuggerDebuggerDebuggeesBreakpointsSetRequest(
            debuggeeId=self.target_id,
            breakpoint=self._debug_messages.Breakpoint(
                location=location, condition=condition, logLevel=log_level,
                logMessageFormat=log_message_format, expressions=expressions,
                labels=labels_value, userEmail=user_email,
                action=(self._debug_messages.Breakpoint.
                        ActionValueValuesEnum.LOG)),
            clientVersion=self.CLIENT_VERSION))
    try:
      response = self._debug_client.debugger_debuggees_breakpoints.Set(request)
    except apitools_exceptions.HttpError as error:
      raise errors.UnknownHttpError(error)
    return self.AddTargetInfo(response.breakpoint)
コード例 #5
0
    def CreateSnapshot(self,
                       location,
                       condition=None,
                       expressions=None,
                       user_email=None,
                       labels=None):
        """Creates a "snapshot" breakpoint.

    Args:
      location: The breakpoint source location, which will be interpreted by
        the debug agents on the machines running the Debuggee. Usually of the
        form file:line-number
      condition: An optional conditional expression in the target's programming
        language. The snapshot will be taken when the expression is true.
      expressions: A list of expressions to evaluate when the snapshot is
        taken.
      user_email: The email of the user who created the snapshot.
      labels: A dictionary containing key-value pairs which will be stored
        with the snapshot definition and reported when the snapshot is queried.
    Returns:
      The created Breakpoint message.
    """
        self._CheckClient()
        labels_value = None
        if labels:
            labels_value = self._debug_messages.Breakpoint.LabelsValue(
                additionalProperties=[
                    self._debug_messages.Breakpoint.LabelsValue.
                    AdditionalProperty(key=key, value=value)
                    for key, value in labels.iteritems()
                ])
        location = self._LocationFromString(location)
        if not expressions:
            expressions = []
        request = (self._debug_messages.
                   ClouddebuggerDebuggerDebuggeesBreakpointsSetRequest(
                       debuggeeId=self.target_id,
                       breakpoint=self._debug_messages.Breakpoint(
                           location=location,
                           condition=condition,
                           expressions=expressions,
                           labels=labels_value,
                           userEmail=user_email,
                           action=(self._debug_messages.Breakpoint.
                                   ActionValueValuesEnum.CAPTURE)),
                       clientVersion=self.CLIENT_VERSION))
        try:
            response = self._debug_client.debugger_debuggees_breakpoints.Set(
                request)
        except apitools_exceptions.HttpError as error:
            raise errors.UnknownHttpError(error)
        return self.AddTargetInfo(response.breakpoint)
コード例 #6
0
  def DeleteBreakpoint(self, breakpoint_id):
    """Deletes a breakpoint.

    Args:
      breakpoint_id: A breakpoint ID.
    """
    request = (self._debug_messages.
               ClouddebuggerDebuggerDebuggeesBreakpointsDeleteRequest(
                   breakpointId=breakpoint_id, debuggeeId=self.target_id,
                   clientVersion=self.CLIENT_VERSION))
    try:
      self._debug_client.debugger_debuggees_breakpoints.Delete(request)
    except apitools_exceptions.HttpError as error:
      raise errors.UnknownHttpError(error)
コード例 #7
0
  def GetBreakpoint(self, breakpoint_id):
    """Gets the details for a breakpoint.

    Args:
      breakpoint_id: A breakpoint ID.
    Returns:
      The full Breakpoint message for the ID.
    """
    request = (self._debug_messages.
               ClouddebuggerDebuggerDebuggeesBreakpointsGetRequest(
                   breakpointId=breakpoint_id, debuggeeId=self.target_id,
                   clientVersion=self.CLIENT_VERSION))
    try:
      response = self._debug_client.debugger_debuggees_breakpoints.Get(request)
    except apitools_exceptions.HttpError as error:
      raise errors.UnknownHttpError(error)
    return self.AddTargetInfo(response.breakpoint)
コード例 #8
0
    def WaitForBreakpoint(self,
                          breakpoint_id,
                          timeout=None,
                          retry_ms=500,
                          completion_test=None):
        """Waits for a breakpoint to be completed.

    Args:
      breakpoint_id: A breakpoint ID.
      timeout: The number of seconds to wait for completion.
      retry_ms: Milliseconds to wait betweeen retries.
      completion_test: A function that accepts a Breakpoint message and
        returns True if the breakpoint wait is not finished. If not specified,
        defaults to a function which just checks the isFinalState flag.
    Returns:
      The Breakpoint message, or None if the breakpoint did not complete before
      the timeout,
    """
        if not completion_test:
            completion_test = lambda r: r.breakpoint.isFinalState
        retry_if = lambda r, _: not completion_test(r)
        retryer = retry.Retryer(max_wait_ms=1000 *
                                timeout if timeout is not None else None,
                                wait_ceiling_ms=1000)
        request = (self._debug_messages.
                   ClouddebuggerDebuggerDebuggeesBreakpointsGetRequest(
                       breakpointId=breakpoint_id,
                       debuggeeId=self.target_id,
                       clientVersion=self.CLIENT_VERSION))
        try:
            result = retryer.RetryOnResult(self._CallGet, [request],
                                           should_retry_if=retry_if,
                                           sleep_ms=retry_ms)
        except retry.RetryException:
            # Timeout before the beakpoint was finalized.
            return None
        except apitools_exceptions.HttpError as error:
            raise errors.UnknownHttpError(error)
        if not completion_test(result):
            # Termination condition was not met
            return None
        return self.AddTargetInfo(result.breakpoint)
コード例 #9
0
    def ListBreakpoints(self,
                        location_regexp=None,
                        resource_ids=None,
                        include_all_users=False,
                        include_inactive=False,
                        restrict_to_type=None):
        """Returns all breakpoints matching the given IDs or patterns.

    Lists all breakpoints for this debuggee, and returns every breakpoint
    where the location field contains the given pattern or the ID is exactly
    equal to the pattern (there can be at most one breakpoint matching by ID).

    Args:
      location_regexp: A list of regular expressions to compare against the
        location ('path:line') of the breakpoints. If both location_regexp and
        resource_ids are empty or None, all breakpoints will be returned.
      resource_ids: Zero or more resource IDs in the form expected by the
        resource parser. These breakpoints will be retrieved regardless
        of the include_all_users or include_inactive flags
      include_all_users: If true, search breakpoints created by all users.
      include_inactive: If true, search breakpoints that are in the final state.
        This option controls whether regular expressions can match inactive
        breakpoints. If an object is specified by ID, it will be returned
        whether or not this flag is set.
      restrict_to_type: An optional breakpoint type (LOGPOINT_TYPE or
        SNAPSHOT_TYPE)
    Returns:
      A list of all matching breakpoints.
    Raises:
      InvalidLocationException if a regular expression is not valid.
    """
        resource_ids = resource_ids or []
        location_regexp = location_regexp or []
        ids = set([
            self._resource_parser.Parse(
                r,
                params={
                    'debuggeeId': self.target_id
                },
                collection='clouddebugger.debugger.debuggees.breakpoints').
            Name() for r in resource_ids
        ])
        patterns = []
        for r in location_regexp:
            try:
                patterns.append(re.compile(r'^(.*/)?(' + r + ')$'))
            except re.error as e:
                raise errors.InvalidLocationException(
                    'The location pattern "{0}" is not a valid Python regular '
                    'expression: {1}'.format(r, e))

        request = (self._debug_messages.
                   ClouddebuggerDebuggerDebuggeesBreakpointsListRequest(
                       debuggeeId=self.target_id,
                       includeAllUsers=include_all_users,
                       includeInactive=include_inactive or bool(ids),
                       clientVersion=self.CLIENT_VERSION))
        try:
            response = self._debug_client.debugger_debuggees_breakpoints.List(
                request)
        except apitools_exceptions.HttpError as error:
            raise errors.UnknownHttpError(error)
        if not patterns and not ids:
            return self._FilteredDictListWithInfo(response.breakpoints,
                                                  restrict_to_type)

        if include_inactive:
            # Match everything (including inactive breakpoints) against all ids and
            # patterns.
            result = [
                bp for bp in response.breakpoints
                if _BreakpointMatchesIdOrRegexp(bp, ids, patterns)
            ]
        else:
            # Return everything that is listed by ID, plus every breakpoint that
            # is not inactive (i.e. isFinalState is false) which matches any pattern.
            # Breakpoints that are inactive should not be matched against the
            # patterns.
            result = [
                bp
                for bp in response.breakpoints if _BreakpointMatchesIdOrRegexp(
                    bp, ids, [] if bp.isFinalState else patterns)
            ]
        # Check if any ids were missing, and fetch them individually. This can
        # happen if an ID for another user's breakpoint was specified, but the
        # all_users flag was false. This code will also raise an error for any
        # missing IDs.
        missing_ids = ids - set([bp.id for bp in result])
        if missing_ids:
            raise errors.BreakpointNotFoundError(
                missing_ids, self._BreakpointDescription(restrict_to_type))

        # Verify that all patterns matched at least one breakpoint.
        for p in patterns:
            if not [
                    bp for bp in result
                    if _BreakpointMatchesIdOrRegexp(bp, [], [p])
            ]:
                raise errors.NoMatchError(
                    self._BreakpointDescription(restrict_to_type), p.pattern)
        return self._FilteredDictListWithInfo(result, restrict_to_type)
コード例 #10
0
    def ListBreakpoints(self,
                        location_regexp_or_ids=None,
                        include_all_users=False,
                        include_inactive=False,
                        restrict_to_type=None):
        """Returns all breakpoints matching the given IDs or patterns.

    Lists all breakpoints for this debuggee, and returns every breakpoint
    where the location field contains the given pattern or the ID is exactly
    equal to the pattern (there can be at most one breakpoint matching by ID).

    Args:
      location_regexp_or_ids: A list of regular expressions or breakpoint IDs.
        Regular expressions will be compared against the location ('path:line')
        of the breakpoints. Exact breakpoint IDs will be retrieved regardless
        of the include_all_users or include_inactive flags.  If empty or None,
        all breakpoints will be returned.
      include_all_users: If true, search breakpoints created by all users.
      include_inactive: If true, search breakpoints that are in the final state.
        This option controls whether regular expressions can match inactive
        breakpoints. If an object is specified by ID, it will be returned
        whether or not this flag is set.
      restrict_to_type: An optional breakpoint type (LOGPOINT_TYPE or
        SNAPSHOT_TYPE)
    Returns:
      A list of all matching breakpoints.
    Raises:
      InvalidArgumentException if a regular expression is not valid.
    """
        self._CheckClient()
        # Try using the resource parser on every argument, and save the resulting
        # (argument, resource) pairs
        parsed_args = [
            (arg,
             self.TryParse(
                 arg,
                 params={'debuggeeId': self.target_id},
                 collection='clouddebugger.debugger.debuggees.breakpoints'))
            for arg in location_regexp_or_ids or []
        ]

        # Pass through the results and find anything that looks like a breakpoint
        # ID. This will include things that looked like an ID originally, plus
        # any IDs the resource parser detected.
        ids = set([
            r.Name() for _, r in parsed_args
            if r and _BREAKPOINT_ID_PATTERN.match(r.Name())
        ])

        # Treat everything that's not an ID (i.e. everything that either wasn't
        # parsable as a resource or whose name doesn't look like an ID) as a reqular
        # expression to be checked against the breakpoint location. Tweak the RE
        # so it will also match just the trailing file name component(s) + line
        # number, since the server may chose to return the full path.
        try:
            patterns = [
                re.compile(r'^(.*/)?(' + arg + ')$') for arg, r in parsed_args
                if not r or (r.Name() not in ids)
            ]
        except re.error as e:
            raise exceptions.InvalidArgumentException('LOCATION-REGEXP',
                                                      str(e))

        request = (self._debug_messages.
                   ClouddebuggerDebuggerDebuggeesBreakpointsListRequest(
                       debuggeeId=self.target_id,
                       includeAllUsers=include_all_users,
                       includeInactive=include_inactive or bool(ids),
                       clientVersion=self.CLIENT_VERSION))
        try:
            response = self._debug_client.debugger_debuggees_breakpoints.List(
                request)
        except apitools_exceptions.HttpError as error:
            raise errors.UnknownHttpError(error)
        if not location_regexp_or_ids:
            return self._FilteredDictListWithInfo(response.breakpoints,
                                                  restrict_to_type)

        if include_inactive:
            # Match everything (including inactive breakpoints) against all ids and
            # patterns.
            result = [
                bp for bp in response.breakpoints
                if _BreakpointMatchesIdOrRegexp(bp, ids, patterns)
            ]
        else:
            # Return everything that is listed by ID, plus every breakpoint that
            # is not inactive (i.e. isFinalState is false) which matches any pattern.
            # Breakpoints that are inactive should not be matched against the
            # patterns.
            result = [
                bp
                for bp in response.breakpoints if _BreakpointMatchesIdOrRegexp(
                    bp, ids, [] if bp.isFinalState else patterns)
            ]

        # Check if any ids were missing, and fetch them individually. This can
        # happen if an ID for another user's breakpoint was specified, but the
        # all_users flag was false. This code will also raise an error for any
        # missing IDs.
        missing_ids = ids - set([bp.id for bp in result])
        if missing_ids:
            raise errors.BreakpointNotFoundError(
                missing_ids, self._BreakpointDescription(restrict_to_type))

        # Verify that all patterns matched at least one breakpoint.
        for p in patterns:
            if not [
                    bp for bp in result
                    if _BreakpointMatchesIdOrRegexp(bp, [], [p])
            ]:
                raise errors.NoMatchError(
                    self._BreakpointDescription(restrict_to_type), p.pattern)
        return self._FilteredDictListWithInfo(result, restrict_to_type)