Esempio n. 1
0
def get_bot():
    """Returns a valid Bot instance.

  Should only be called once in the process lifetime.
  """
    # This variable is used to bootstrap the initial bot.Bot object, which then is
    # used to get the dimensions and state.
    attributes = {
        'dimensions': {
            u'id': ['none']
        },
        'state': {},
        'version': generate_version(),
    }
    config = get_config()
    assert not config['server'].endswith('/'), config

    base_dir = os.path.dirname(THIS_FILE)
    # Use temporary Bot object to call get_attributes. Attributes are needed to
    # construct the "real" bot.Bot.
    attributes = get_attributes(
        bot.Bot(remote_client.createRemoteClient(config['server'], None),
                attributes, config['server'], config['server_version'],
                base_dir, on_shutdown_hook))

    # Make remote client callback use the returned bot object. We assume here
    # RemoteClient doesn't call its callback in the constructor (since 'botobj' is
    # undefined during the construction).
    botobj = bot.Bot(
        remote_client.createRemoteClient(
            config['server'],
            lambda: get_authentication_headers(botobj)), attributes,
        config['server'], config['server_version'], base_dir, on_shutdown_hook)
    return botobj
Esempio n. 2
0
 def make_bot(self, auth_headers_cb=None):
     return bot.Bot(
         remote_client.createRemoteClient('https://localhost:1',
                                          auth_headers_cb, 'localhost',
                                          self.root_dir),
         copy.deepcopy(self.attributes), 'https://localhost:1', 'version1',
         six.ensure_text(self.root_dir), self.fail)
Esempio n. 3
0
 def setUp(self):
     super(TestBotMain, self).setUp()
     os.environ.pop('SWARMING_LOAD_TEST', None)
     self.root_dir = tempfile.mkdtemp(prefix='bot_main')
     self.old_cwd = os.getcwd()
     os.chdir(self.root_dir)
     # __main__ does it for us.
     os.mkdir('logs')
     self.server = xsrf_client.XsrfRemote('https://localhost:1/')
     self.attributes = {
         'dimensions': {
             'foo': ['bar'],
             'id': ['localhost'],
         },
         'state': {
             'cost_usd_hour': 3600.,
         },
         'version': '123',
     }
     self.mock(zip_package, 'generate_version', lambda: '123')
     self.bot = bot.Bot(self.server, self.attributes,
                        'https://localhost:1/', 'version1', self.root_dir,
                        self.fail)
     self.mock(self.bot, 'post_error', self.fail)
     self.mock(self.bot, 'restart', self.fail)
     self.mock(subprocess42, 'call', self.fail)
     self.mock(time, 'time', lambda: 100.)
     config_path = os.path.join(test_env_bot_code.BOT_DIR, 'config',
                                'config.json')
     with open(config_path, 'rb') as f:
         config = json.load(f)
     self.mock(bot_main, 'get_config', lambda: config)
     self.mock(bot_main, 'THIS_FILE',
               os.path.join(test_env_bot_code.BOT_DIR, 'swarming_bot.zip'))
Esempio n. 4
0
def main(args):
  # Add SWARMING_HEADLESS into environ so subcommands know that they are running
  # in a headless (non-interactive) mode.
  os.environ['SWARMING_HEADLESS'] = '1'

  # The only reason this is kept is to enable the unit test to use --help to
  # quit the process.
  parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
  _, args = parser.parse_args(args)

  # Enforces that only one process with a bot in this directory can be run on
  # this host at once.
  #
  # This is generally a problem with launchd which is a bit too much
  # 'restart-happy', causing 2 bots running concurrently on the host but it was
  # observed on linux too.
  if not SINGLETON.acquire():
    print >> sys.stderr, 'Found a previous bot, %d exiting.' % os.getpid()
    return 1

  for t in ('out', 'err'):
    log_path = os.path.join(
        os.path.dirname(THIS_FILE), 'logs', 'bot_std%s.log' % t)
    os_utilities.roll_log(log_path)
    os_utilities.trim_rolled_log(log_path)

  error = None
  if len(args) != 0:
    error = 'Unexpected arguments: %s' % args
  try:
    return run_bot(error)
  finally:
    call_hook(bot.Bot(None, None, None, None, os.path.dirname(THIS_FILE), None),
              'on_bot_shutdown')
Esempio n. 5
0
def get_bot():
  """Returns a valid Bot instance.

  Should only be called once in the process lifetime.
  """
  # This variable is used to bootstrap the initial bot.Bot object, which then is
  # used to get the dimensions and state.
  attributes = {
    'dimensions': {u'id': ['none']},
    'state': {},
    'version': generate_version(),
  }
  config = get_config()
  while True:
    try:
      # Handshake to get an XSRF token even if there were errors.
      remote = get_remote()
      remote.xsrf_request_params = attributes.copy()
      # Create a temporary object to call the hooks.
      botobj = bot.Bot(
          remote,
          attributes,
          config['server'],
          config['server_version'],
          os.path.dirname(THIS_FILE),
          on_shutdown_hook)
      attributes = get_attributes(botobj)
      remote.xsrf_request_params = attributes.copy()
      break
    except Exception:
      # Continue looping. The main reason to get into this situation is when the
      # network is down for > 20 minutes. It's worth continuing to loop until
      # the server is reachable again.
      logging.exception('Catastrophic failure')

  return bot.Bot(
      remote,
      attributes,
      config['server'],
      config['server_version'],
      os.path.dirname(THIS_FILE),
      on_shutdown_hook)
Esempio n. 6
0
def get_bot():
    """Returns a valid Bot instance.

  Should only be called once in the process lifetime.
  """
    # This variable is used to bootstrap the initial bot.Bot object, which then is
    # used to get the dimensions and state.
    attributes = {
        'dimensions': {
            u'id': ['none']
        },
        'state': {},
        'version': generate_version(),
    }
    config = get_config()
    assert not config['server'].endswith('/'), config

    # Create a temporary object to call the hooks.
    botobj = bot.Bot(attributes, config['server'], config['server_version'],
                     os.path.dirname(THIS_FILE), on_shutdown_hook)
    return bot.Bot(get_attributes(botobj),
                   config['server'], config['server_version'],
                   os.path.dirname(THIS_FILE), on_shutdown_hook)
Esempio n. 7
0
def main(args):
    # Add SWARMING_HEADLESS into environ so subcommands know that they are running
    # in a headless (non-interactive) mode.
    os.environ['SWARMING_HEADLESS'] = '1'

    # The only reason this is kept is to enable the unit test to use --help to
    # quit the process.
    parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
    _, args = parser.parse_args(args)
    error = None
    if len(args) != 0:
        error = 'Unexpected arguments: %s' % args
    try:
        return run_bot(error)
    finally:
        call_hook(
            bot.Bot(None, None, None, None, os.path.dirname(THIS_FILE), None),
            'on_bot_shutdown')
Esempio n. 8
0
def main(args):
    subprocess42.inhibit_os_error_reporting()
    # Add SWARMING_HEADLESS into environ so subcommands know that they are running
    # in a headless (non-interactive) mode.
    os.environ['SWARMING_HEADLESS'] = '1'

    # The only reason this is kept is to enable the unit test to use --help to
    # quit the process.
    parser = optparse.OptionParser(description=sys.modules[__name__].__doc__)
    _, args = parser.parse_args(args)

    # Enforces that only one process with a bot in this directory can be run on
    # this host at once.
    if not SINGLETON.acquire():
        if sys.platform == 'darwin':
            msg = ('Found a previous bot, %d rebooting as a workaround for '
                   'https://crbug.com/569610.') % os.getpid()
            print >> sys.stderr, msg
            os_utilities.restart(msg)
        else:
            print >> sys.stderr, 'Found a previous bot, %d exiting.' % os.getpid(
            )
        return 1

    base_dir = os.path.dirname(THIS_FILE)
    for t in ('out', 'err'):
        log_path = os.path.join(base_dir, 'logs', 'bot_std%s.log' % t)
        os_utilities.roll_log(log_path)
        os_utilities.trim_rolled_log(log_path)

    error = None
    if len(args) != 0:
        error = 'Unexpected arguments: %s' % args
    try:
        return run_bot(error)
    finally:
        call_hook(bot.Bot(None, None, None, None, base_dir, None),
                  'on_bot_shutdown')
        logging.info('main() returning')
Esempio n. 9
0
def get_bot():
    """Returns a valid Bot instance.

  Should only be called once in the process lifetime.
  """
    while True:
        try:
            attributes = get_attributes()

            # Handshake to get an XSRF token even if there were errors.
            remote = get_remote()
            remote.xsrf_request_params = attributes.copy()
            break
        except Exception:
            # Continue looping. The main reason to get into this situation is when the
            # network is down for > 20 minutes. It's worth continuing to loop until
            # the server is reachable again.
            logging.exception('Catastrophic failure')

    config = get_config()
    return bot.Bot(remote, attributes,
                   config['server'], config['server_version'],
                   os.path.dirname(THIS_FILE), on_shutdown_hook)
Esempio n. 10
0
 def make_bot(self, auth_headers_cb=None):
   return bot.Bot(
       remote_client.createRemoteClient('https://localhost:1',
                                        auth_headers_cb),
       self.attributes, 'https://localhost:1', 'version1',
       self.root_dir, self.fail)