Beispiel #1
0
    def get(self, request):
        """Returns information about a known bot.

    This includes its state and dimensions, and if it is currently running a
    task.
    """
        logging.debug('%s', request)
        bot_id = request.bot_id
        bot = bot_management.get_info_key(bot_id).get()
        deleted = False
        if not bot:
            # If there is not BotInfo, look if there are BotEvent child of this
            # entity. If this is the case, it means the bot was deleted but it's
            # useful to show information about it to the user even if the bot was
            # deleted.
            events = bot_management.get_events_query(bot_id, True).fetch(1)
            if not events:
                raise endpoints.NotFoundException('%s not found.' % bot_id)
            bot = bot_management.BotInfo(
                key=bot_management.get_info_key(bot_id),
                dimensions_flat=task_queues.dimensions_to_flat(
                    events[0].dimensions),
                state=events[0].state,
                external_ip=events[0].external_ip,
                authenticated_as=events[0].authenticated_as,
                version=events[0].version,
                quarantined=events[0].quarantined,
                maintenance_msg=events[0].maintenance_msg,
                task_id=events[0].task_id,
                last_seen_ts=events[0].ts)
            deleted = True

        return message_conversion.bot_info_to_rpc(bot, deleted=deleted)
def _gen_bot_info(key_id, last_seen_ts, **kwargs):
    args = {
        'key': ndb.Key('BotRoot', key_id, 'BotInfo', 'info'),
        'last_seen_ts': last_seen_ts,
        'dimensions': {
            'os': ['Linux', 'Ubuntu'],
            'bot_id': [key_id],
        },
    }
    args.update(**kwargs)
    args['dimensions_flat'] = bot_management._dimensions_to_flat(
        args.pop('dimensions'))
    return bot_management.BotInfo(**args)
Beispiel #3
0
  def get(self, bot_id):
    # pagination is currently for tasks, not events.
    limit = int(self.request.get('limit', 100))
    cursor = datastore_query.Cursor(urlsafe=self.request.get('cursor'))
    run_results_future = task_result.TaskRunResult.query(
        task_result.TaskRunResult.bot_id == bot_id).order(
            -task_result.TaskRunResult.started_ts).fetch_page_async(
                limit, start_cursor=cursor)
    bot_future = bot_management.get_info_key(bot_id).get_async()
    events_future = bot_management.get_events_query(
        bot_id, True).fetch_async(100)

    now = utils.utcnow()

    # Calculate the time this bot was idle.
    idle_time = datetime.timedelta()
    run_time = datetime.timedelta()
    run_results, cursor, more = run_results_future.get_result()
    if run_results:
      run_time = run_results[0].duration_now(now) or datetime.timedelta()
      if not cursor and run_results[0].state != task_result.State.RUNNING:
        # Add idle time since last task completed. Do not do this when a cursor
        # is used since it's not representative.
        idle_time = now - run_results[0].ended_ts
      for index in xrange(1, len(run_results)):
        # .started_ts will always be set by definition but .ended_ts may be None
        # if the task was abandoned. We can't count idle time since the bot may
        # have been busy running *another task*.
        # TODO(maruel): One option is to add a third value "broken_time".
        # Looking at timestamps specifically could help too, e.g. comparing
        # ended_ts of this task vs the next one to see if the bot was assigned
        # two tasks simultaneously.
        if run_results[index].ended_ts:
          idle_time += (
              run_results[index-1].started_ts - run_results[index].ended_ts)
          # We are taking the whole time the bot was doing work, not just the
          # duration associated with the task.
          duration = run_results[index].duration_as_seen_by_server
          if duration:
            run_time += duration

    events = events_future.get_result()
    bot = bot_future.get_result()
    if not bot and events:
      # If there is not BotInfo, look if there are BotEvent child of this
      # entity. If this is the case, it means the bot was deleted but it's
      # useful to show information about it to the user even if the bot was
      # deleted. For example, it could be an auto-scaled bot.
      bot = bot_management.BotInfo(
          key=bot_management.get_info_key(bot_id),
          dimensions_flat=bot_management.dimensions_to_flat(
              events[0].dimensions),
          state=events[0].state,
          external_ip=events[0].external_ip,
          authenticated_as=events[0].authenticated_as,
          version=events[0].version,
          quarantined=events[0].quarantined,
          task_id=events[0].task_id,
          last_seen_ts=events[0].ts)

    params = {
      'bot': bot,
      'bot_id': bot_id,
      'current_version': bot_code.get_bot_version(self.request.host_url),
      'cursor': cursor.urlsafe() if cursor and more else None,
      'events': events,
      'idle_time': idle_time,
      'is_admin': acl.is_admin(),
      'limit': limit,
      'now': now,
      'run_results': run_results,
      'run_time': run_time,
      'try_link': '/bot?id=%s' % bot_id,
      'xsrf_token': self.generate_xsrf_token(),
    }
    self.response.write(
        template.render('swarming/restricted_bot.html', params))