Beispiel #1
0
    def get_access_token(self, scopes, service_account_id=None,
                         service_account_name=None):
        """ Generates an access token from a service account.

        Args:
            scopes: A list of strings specifying scopes.
            service_account_id: An integer specifying a service account ID.
            service_account_name: A string specifying a service account name.
        Returns:
            An AccessToken.
        Raises:
            UnknownError if the service account is not configured.
        """
        # TODO: Check if it makes sense to store the audience with the service
        # account definition.
        default_audience = 'https://www.googleapis.com/oauth2/v4/token'

        if (service_account_name is None or
                (self._key is not None and
                 self._key.key_name == service_account_name)):
            lb_ip = random.choice(appscale_info.get_load_balancer_ips())
            url = 'https://{}:17441/oauth/token'.format(lb_ip)
            payload = urllib.urlencode({'scope': ' '.join(scopes),
                                        'grant_type': 'secret',
                                        'project_id': self.project_id,
                                        'secret': appscale_info.get_secret()})
            try:
                response = urllib2.urlopen(
                    url, payload, context=ssl._create_unverified_context())
            except urllib2.HTTPError as error:
                raise UnknownError(error.msg)
            except urllib2.URLError as error:
                raise UnknownError(error.reason)

            token_details = json.loads(response.read())
            expiration_time = int(time.time()) + token_details['expires_in']
            return AccessToken(token_details['access_token'], expiration_time)

        if service_account_id is not None:
            raise UnknownError(
                '{} is not configured'.format(service_account_id))

        service_account_node = '/'.join([self._service_accounts_node,
                                         service_account_name])
        try:
            account_details = self._zk_client.get(service_account_node)[0]
        except NoNodeError:
            raise UnknownError(
                '{} is not configured'.format(service_account_name))

        try:
            account_details = json.loads(account_details)
        except ValueError:
            raise UnknownError(
                '{} has invalid data'.format(service_account_node))

        pem = account_details['privateKey'].encode('utf-8')
        key = PrivateKey.from_pem(service_account_name, pem)
        assertion = key.generate_assertion(default_audience, scopes)
        return self._get_token(default_audience, assertion)
Beispiel #2
0
  def get_failed_instances(self):
    """ Fetches a list of failed instances on this machine according to HAProxy.

    Returns:
      A set of tuples specifying the version key and port of failed instances.
    """
    load_balancer = random.choice(appscale_info.get_load_balancer_ips())
    payload = {'include_lists': {
      'proxy': ['name', 'servers'],
      'proxy.server': ['private_ip', 'port', 'status']}
    }
    headers = {'AppScale-Secret': self._secret}
    url = 'http://{}:{}/stats/local/proxies'.format(load_balancer, HERMES_PORT)
    client = AsyncHTTPClient()

    response = yield client.fetch(url, headers=headers, body=json.dumps(payload),
                                  allow_nonstandard_methods=True)
    proxy_stats = json.loads(response.body)['proxies_stats']

    routed_versions = [server for server in proxy_stats
                       if server['name'].startswith(GAE_PREFIX)]
    failed_instances = set()
    for version in routed_versions:
      version_key = version['name'][len(GAE_PREFIX):]
      for server in version['servers']:
        if server['private_ip'] != self._private_ip:
          continue

        if not server['status'].startswith('DOWN'):
          continue

        failed_instances.add((version_key, server['port']))

    raise gen.Return(failed_instances)
Beispiel #3
0
  def get_failed_instances(self):
    """ Fetches a list of failed instances on this machine according to HAProxy.

    Returns:
      A set of tuples specifying the version key and port of failed instances.
    """
    load_balancer = random.choice(appscale_info.get_load_balancer_ips())
    payload = {'include_lists': {
      'proxy': ['name', 'servers'],
      'proxy.server': ['private_ip', 'port', 'status']}
    }
    headers = {'AppScale-Secret': self._secret}
    url = 'http://{}:{}/stats/local/proxies'.format(load_balancer, HERMES_PORT)
    client = AsyncHTTPClient()

    response = yield client.fetch(url, headers=headers, body=json.dumps(payload),
                                  allow_nonstandard_methods=True)
    proxy_stats = json.loads(response.body)['proxies_stats']

    routed_versions = [server for server in proxy_stats
                       if server['name'].startswith('gae_')]
    failed_instances = set()
    for version in routed_versions:
      version_key = version['name'][len('gae_'):]
      for server in version['servers']:
        if server['private_ip'] != self._private_ip:
          continue

        if not server['status'].startswith('DOWN'):
          continue

        failed_instances.add((version_key, server['port']))

    raise gen.Return(failed_instances)
Beispiel #4
0
def main():
  global datastore_path
  global deployment_config

  logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)

  parser = argparse.ArgumentParser()
  parser.add_argument('-p', '--port', type=int, default=DEFAULT_PORT,
                      required=True, help="The blobstore server's port")
  parser.add_argument('-d', '--datastore-path', required=True,
                      help='The location of the datastore server')
  args = parser.parse_args()

  datastore_path = args.datastore_path
  zk_ips = appscale_info.get_zk_node_ips()
  zk_client = KazooClient(hosts=','.join(zk_ips))
  zk_client.start()
  deployment_config = DeploymentConfig(zk_client)
  setup_env()

  http_server = tornado.httpserver.HTTPServer(
    Application(), max_buffer_size=MAX_REQUEST_BUFF_SIZE, xheaders=True)

  http_server.listen(args.port)

  # Make sure this server is accessible from each of the load balancers.
  secret = appscale_info.get_secret()
  for load_balancer in appscale_info.get_load_balancer_ips():
    acc = AppControllerClient(load_balancer, secret)
    acc.add_routing_for_blob_server()

  logger.info('Starting BlobServer on {}'.format(args.port))
  tornado.ioloop.IOLoop.instance().start()
Beispiel #5
0
def main():
  file_io.set_logging_format()
  logging.getLogger().setLevel(logging.INFO)

  zk_ips = appscale_info.get_zk_node_ips()
  zk_client = KazooClient(hosts=','.join(zk_ips))
  zk_client.start()

  deployment_config = DeploymentConfig(zk_client)
  projects_manager = GlobalProjectsManager(zk_client)
  thread_pool = ThreadPoolExecutor(MAX_BACKGROUND_WORKERS)
  source_manager = SourceManager(zk_client, thread_pool)
  source_manager.configure_automatic_fetch(projects_manager)
  monit_operator = MonitOperator()

  options.define('private_ip', appscale_info.get_private_ip())
  options.define('syslog_server', appscale_info.get_headnode_ip())
  options.define('db_proxy', appscale_info.get_db_proxy())
  options.define('load_balancer_ip', appscale_info.get_load_balancer_ips()[0])
  options.define('tq_proxy', appscale_info.get_tq_proxy())
  options.define('secret', appscale_info.get_secret())

  routing_client = RoutingClient(zk_client, options.private_ip, options.secret)
  instance_manager = InstanceManager(
    zk_client, monit_operator, routing_client, projects_manager,
    deployment_config, source_manager, options.syslog_server, thread_pool,
    options.private_ip)
  instance_manager.start()

  logger.info('Starting AppManager')

  io_loop = IOLoop.current()
  io_loop.run_sync(instance_manager.populate_api_servers)
  io_loop.start()
Beispiel #6
0
def main():
  """ Starts a web service for handing datastore requests. """

  global datastore_access
  global server_node
  global zookeeper
  zookeeper_locations = appscale_info.get_zk_locations_string()

  parser = argparse.ArgumentParser()
  parser.add_argument('-t', '--type', choices=dbconstants.VALID_DATASTORES,
                      default=dbconstants.VALID_DATASTORES[0],
                      help='Database type')
  parser.add_argument('-p', '--port', type=int,
                      default=dbconstants.DEFAULT_PORT,
                      help='Datastore server port')
  parser.add_argument('-v', '--verbose', action='store_true',
                      help='Output debug-level logging')
  args = parser.parse_args()

  if args.verbose:
    logging.getLogger('appscale').setLevel(logging.DEBUG)

  options.define('private_ip', appscale_info.get_private_ip())
  options.define('port', args.port)
  taskqueue_locations = get_load_balancer_ips()

  server_node = '{}/{}:{}'.format(DATASTORE_SERVERS_NODE, options.private_ip,
                                  options.port)

  datastore_batch = DatastoreFactory.getDatastore(
    args.type, log_level=logger.getEffectiveLevel())
  zookeeper = zktransaction.ZKTransaction(
    host=zookeeper_locations, db_access=datastore_batch,
    log_level=logger.getEffectiveLevel())

  zookeeper.handle.add_listener(zk_state_listener)
  zookeeper.handle.ensure_path(DATASTORE_SERVERS_NODE)
  # Since the client was started before adding the listener, make sure the
  # server node gets created.
  zk_state_listener(zookeeper.handle.state)
  zookeeper.handle.ChildrenWatch(DATASTORE_SERVERS_NODE, update_servers_watch)

  transaction_manager = TransactionManager(zookeeper.handle)
  datastore_access = DatastoreDistributed(
    datastore_batch, transaction_manager, zookeeper=zookeeper,
    log_level=logger.getEffectiveLevel(),
    taskqueue_locations=taskqueue_locations)
  index_manager = IndexManager(zookeeper.handle, datastore_access,
                               perform_admin=True)
  datastore_access.index_manager = index_manager

  server = tornado.httpserver.HTTPServer(pb_application)
  server.listen(args.port)

  IOLoop.current().start()
Beispiel #7
0
  def __init__(self, zk_client):
    """ DistributedTaskQueue Constructor.

    Args:
      zk_client: A KazooClient.
    """
    setup_env()

    self.load_balancers = appscale_info.get_load_balancer_ips()
    self.queue_manager = GlobalQueueManager(zk_client)
    self.service_manager = GlobalServiceManager(zk_client)
    self.datastore_client = DatastoreClient()
Beispiel #8
0
def main():
    """ Main. """
    parser = argparse.ArgumentParser()
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Output debug-level logging')
    args = parser.parse_args()

    logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)
    if args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)

    options.define('secret', appscale_info.get_secret())

    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGINT, signal_handler)

    my_ip = appscale_info.get_private_ip()
    is_master = (my_ip == appscale_info.get_headnode_ip())
    is_lb = (my_ip in appscale_info.get_load_balancer_ips())
    is_tq = (my_ip in appscale_info.get_taskqueue_nodes())
    is_db = (my_ip in appscale_info.get_db_ips())

    if is_master:
        global zk_client
        zk_client = KazooClient(hosts=','.join(
            appscale_info.get_zk_node_ips()),
                                connection_retry=ZK_PERSISTENT_RECONNECTS)
        zk_client.start()
        # Start watching profiling configs in ZooKeeper
        stats_app.ProfilingManager(zk_client)

    app = tornado.web.Application(
        stats_app.get_local_stats_api_routes(is_lb, is_tq, is_db) +
        stats_app.get_cluster_stats_api_routes(is_master),
        debug=False)
    app.listen(constants.HERMES_PORT)

    # Start loop for accepting http requests.
    IOLoop.instance().start()

    logger.info("Hermes is up and listening on port: {}.".format(
        constants.HERMES_PORT))
Beispiel #9
0
def main():
  """ Main. """
  parser = argparse.ArgumentParser()
  parser.add_argument(
    '-v', '--verbose', action='store_true',
    help='Output debug-level logging')
  args = parser.parse_args()

  logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)
  if args.verbose:
    logging.getLogger().setLevel(logging.DEBUG)

  options.define('secret', appscale_info.get_secret())

  signal.signal(signal.SIGTERM, signal_handler)
  signal.signal(signal.SIGINT, signal_handler)

  my_ip = appscale_info.get_private_ip()
  is_master = (my_ip == appscale_info.get_headnode_ip())
  is_lb = (my_ip in appscale_info.get_load_balancer_ips())
  is_tq = (my_ip in appscale_info.get_taskqueue_nodes())
  is_db = (my_ip in appscale_info.get_db_ips())

  if is_master:
    global zk_client
    zk_client = KazooClient(
      hosts=','.join(appscale_info.get_zk_node_ips()),
      connection_retry=ZK_PERSISTENT_RECONNECTS)
    zk_client.start()
    # Start watching profiling configs in ZooKeeper
    stats_app.ProfilingManager(zk_client)

  app = tornado.web.Application(
    stats_app.get_local_stats_api_routes(is_lb, is_tq, is_db)
    + stats_app.get_cluster_stats_api_routes(is_master),
    debug=False
  )
  app.listen(constants.HERMES_PORT)

  # Start loop for accepting http requests.
  IOLoop.instance().start()

  logger.info("Hermes is up and listening on port: {}."
               .format(constants.HERMES_PORT))
Beispiel #10
0
  def __init__(self, db_access, zk_client):
    """ DistributedTaskQueue Constructor.

    Args:
      db_access: A DatastoreProxy object.
      zk_client: A KazooClient.
    """
    setup_env()

    db_proxy = appscale_info.get_db_proxy()
    connection_str = '{}:{}'.format(db_proxy, str(constants.DB_SERVER_PORT))
    ds_distrib = datastore_distributed.DatastoreDistributed(
      constants.DASHBOARD_APP_ID, connection_str, require_indexes=False)
    apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', ds_distrib)
    os.environ['APPLICATION_ID'] = constants.DASHBOARD_APP_ID

    self.db_access = db_access
    self.load_balancers = appscale_info.get_load_balancer_ips()
    self.queue_manager = GlobalQueueManager(zk_client, db_access)
    self.service_manager = GlobalServiceManager(zk_client)
Beispiel #11
0
  def __init__(self, db_access, zk_client):
    """ DistributedTaskQueue Constructor.

    Args:
      db_access: A DatastoreProxy object.
      zk_client: A KazooClient.
    """
    setup_env()

    db_proxy = appscale_info.get_db_proxy()
    connection_str = '{}:{}'.format(db_proxy, str(constants.DB_SERVER_PORT))
    ds_distrib = datastore_distributed.DatastoreDistributed(
      constants.DASHBOARD_APP_ID, connection_str)
    apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', ds_distrib)
    os.environ['APPLICATION_ID'] = constants.DASHBOARD_APP_ID

    self.db_access = db_access
    self.load_balancers = appscale_info.get_load_balancer_ips()
    self.queue_manager = GlobalQueueManager(zk_client, db_access)
    self.service_manager = GlobalServiceManager(zk_client)
Beispiel #12
0
def wait_for_port_to_open(http_port, operation_id, deadline):
  """ Waits until port is open.

  Args:
    http_port: An integer specifying the version's port number.
    operation_id: A string specifying an operation ID.
    deadline: A float containing a unix timestamp.
  Raises:
    OperationTimeout if the deadline is exceeded.
  """
  logger.debug('Waiting for {} to open'.format(http_port))
  try:
    operation = operations[operation_id]
  except KeyError:
    raise OperationTimeout('Operation no longer in cache')

  while True:
    if time.time() > deadline:
      message = 'Deploy operation took too long.'
      operation.set_error(message)
      raise OperationTimeout(message)

    if utils.port_is_open(options.login_ip, http_port):
      break

    yield gen.sleep(1)

  for load_balancer in appscale_info.get_load_balancer_ips():
    while True:
      if time.time() > deadline:
        # The version is reachable from the login IP, but it's not reachable
        # from every registered load balancer. It makes more sense to mark the
        # operation as a success than a failure because the lagging load
        # balancers should eventually reflect the registered instances.
        break

      if utils.port_is_open(load_balancer, http_port):
        break

      yield gen.sleep(1)
Beispiel #13
0
def wait_for_port_to_open(http_port, operation_id, deadline):
  """ Waits until port is open.

  Args:
    http_port: An integer specifying the version's port number.
    operation_id: A string specifying an operation ID.
    deadline: A float containing a unix timestamp.
  Raises:
    OperationTimeout if the deadline is exceeded.
  """
  logger.debug('Waiting for {} to open'.format(http_port))
  try:
    operation = operations[operation_id]
  except KeyError:
    raise OperationTimeout('Operation no longer in cache')

  while True:
    if time.time() > deadline:
      message = 'Deploy operation took too long.'
      operation.set_error(message)
      raise OperationTimeout(message)

    if utils.port_is_open(options.login_ip, http_port):
      break

    yield gen.sleep(1)

  for load_balancer in appscale_info.get_load_balancer_ips():
    while True:
      if time.time() > deadline:
        # The version is reachable from the login IP, but it's not reachable
        # from every registered load balancer. It makes more sense to mark the
        # operation as a success than a failure because the lagging load
        # balancers should eventually reflect the registered instances.
        break

      if utils.port_is_open(load_balancer, http_port):
        break

      yield gen.sleep(1)
Beispiel #14
0
def main():
    global datastore_path
    global deployment_config

    logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)

    parser = argparse.ArgumentParser()
    parser.add_argument('-p',
                        '--port',
                        type=int,
                        default=DEFAULT_PORT,
                        required=True,
                        help="The blobstore server's port")
    parser.add_argument('-d',
                        '--datastore-path',
                        required=True,
                        help='The location of the datastore server')
    args = parser.parse_args()

    datastore_path = args.datastore_path
    zk_ips = appscale_info.get_zk_node_ips()
    zk_client = KazooClient(hosts=','.join(zk_ips))
    zk_client.start()
    deployment_config = DeploymentConfig(zk_client)
    setup_env()

    http_server = tornado.httpserver.HTTPServer(
        Application(), max_buffer_size=MAX_REQUEST_BUFF_SIZE, xheaders=True)

    http_server.listen(args.port)

    # Make sure this server is accessible from each of the load balancers.
    secret = appscale_info.get_secret()
    for load_balancer in appscale_info.get_load_balancer_ips():
        acc = AppControllerClient(load_balancer, secret)
        acc.add_routing_for_blob_server()

    logger.info('Starting BlobServer on {}'.format(args.port))
    tornado.ioloop.IOLoop.instance().start()
Beispiel #15
0
def main():
    file_io.set_logging_format()
    logging.getLogger().setLevel(logging.INFO)

    zk_ips = appscale_info.get_zk_node_ips()
    zk_client = KazooClient(hosts=','.join(zk_ips))
    zk_client.start()

    deployment_config = DeploymentConfig(zk_client)
    projects_manager = GlobalProjectsManager(zk_client)
    thread_pool = ThreadPoolExecutor(MAX_BACKGROUND_WORKERS)
    source_manager = SourceManager(zk_client, thread_pool)
    source_manager.configure_automatic_fetch(projects_manager)
    monit_operator = MonitOperator()

    options.define('private_ip', appscale_info.get_private_ip())
    options.define('syslog_server', appscale_info.get_headnode_ip())
    options.define('db_proxy', appscale_info.get_db_proxy())
    options.define('load_balancer_ip',
                   appscale_info.get_load_balancer_ips()[0])
    options.define('tq_proxy', appscale_info.get_tq_proxy())
    options.define('secret', appscale_info.get_secret())

    routing_client = RoutingClient(zk_client, options.private_ip,
                                   options.secret)
    instance_manager = InstanceManager(zk_client, monit_operator,
                                       routing_client, projects_manager,
                                       deployment_config, source_manager,
                                       options.syslog_server, thread_pool,
                                       options.private_ip)
    instance_manager.start()

    logger.info('Starting AppManager')

    io_loop = IOLoop.current()
    io_loop.run_sync(instance_manager.populate_api_servers)
    io_loop.start()
Beispiel #16
0
def main():
    """ Main. """
    parser = argparse.ArgumentParser()
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Output debug-level logging')
    parser.add_argument('--port',
                        type=int,
                        default=constants.HERMES_PORT,
                        help='The port to listen on')
    args = parser.parse_args()

    logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)
    if args.verbose:
        logging.getLogger('appscale').setLevel(logging.DEBUG)

    my_ip = appscale_info.get_private_ip()
    is_master = (my_ip == appscale_info.get_headnode_ip())
    is_lb = (my_ip in appscale_info.get_load_balancer_ips())
    is_tq = (my_ip in appscale_info.get_taskqueue_nodes())
    is_db = (my_ip in appscale_info.get_db_ips())

    app = web.Application(middlewares=[verify_secret_middleware])

    route_items = []
    route_items += get_local_stats_api_routes(is_lb, is_tq, is_db)
    route_items += get_cluster_stats_api_routes(is_master)
    for route, handler in route_items:
        app.router.add_get(route, handler)

    logger.info("Starting Hermes on port: {}.".format(args.port))
    web.run_app(app,
                port=args.port,
                access_log=logger,
                access_log_format='%a "%r" %s %bB %Tfs "%{User-Agent}i"')
Beispiel #17
0
def main():
    """ Starts the AdminServer. """
    logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)

    parser = argparse.ArgumentParser()
    parser.add_argument('-p',
                        '--port',
                        type=int,
                        default=constants.DEFAULT_PORT,
                        help='The port to listen on')
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Output debug-level logging')
    args = parser.parse_args()

    if args.verbose:
        logger.setLevel(logging.DEBUG)

    options.define('secret', appscale_info.get_secret())
    options.define('login_ip', appscale_info.get_login_ip())
    options.define('private_ip', appscale_info.get_private_ip())
    options.define('load_balancers', appscale_info.get_load_balancer_ips())

    acc = appscale_info.get_appcontroller_client()
    ua_client = UAClient(appscale_info.get_db_master_ip(), options.secret)
    zk_client = KazooClient(hosts=','.join(appscale_info.get_zk_node_ips()),
                            connection_retry=ZK_PERSISTENT_RECONNECTS)
    zk_client.start()
    version_update_lock = zk_client.Lock(constants.VERSION_UPDATE_LOCK_NODE)
    thread_pool = ThreadPoolExecutor(4)
    monit_operator = MonitOperator()
    all_resources = {
        'acc': acc,
        'ua_client': ua_client,
        'zk_client': zk_client,
        'version_update_lock': version_update_lock,
        'thread_pool': thread_pool
    }

    if options.private_ip in appscale_info.get_taskqueue_nodes():
        logger.info('Starting push worker manager')
        GlobalPushWorkerManager(zk_client, monit_operator)

    app = web.Application([
        ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)/versions',
         VersionsHandler, all_resources),
        ('/v1/projects', ProjectsHandler, all_resources),
        ('/v1/projects/([a-z0-9-]+)', ProjectHandler, all_resources),
        ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)', ServiceHandler,
         all_resources),
        ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)/versions/([a-z0-9-]+)',
         VersionHandler, all_resources),
        ('/v1/apps/([a-z0-9-]+)/operations/([a-z0-9-]+)', OperationsHandler),
        ('/api/queue/update', UpdateQueuesHandler, {
            'zk_client': zk_client
        })
    ])
    logger.info('Starting AdminServer')
    app.listen(args.port)
    io_loop = IOLoop.current()
    io_loop.start()
Beispiel #18
0
def get_random_lb_node():
    return [random.choice(appscale_info.get_load_balancer_ips())]
Beispiel #19
0
def main():
    """ Starts a web service for handing datastore requests. """

    global datastore_access
    global server_node
    global zk_client
    zookeeper_locations = appscale_info.get_zk_locations_string()
    if not zookeeper_locations:
        zookeeper_locations = 'localhost:2181'

    parser = argparse.ArgumentParser()
    parser.add_argument('-t',
                        '--type',
                        choices=dbconstants.VALID_DATASTORES,
                        default=dbconstants.VALID_DATASTORES[0],
                        help='Database type')
    parser.add_argument('--fdb-clusterfile',
                        default=None,
                        help='Location of FoundationDB clusterfile')
    parser.add_argument('-p',
                        '--port',
                        type=int,
                        default=dbconstants.DEFAULT_PORT,
                        help='Datastore server port')
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Output debug-level logging')
    args = parser.parse_args()

    if args.verbose:
        logging.getLogger('appscale').setLevel(logging.DEBUG)

    options.define('private_ip', appscale_info.get_private_ip())
    options.define('port', args.port)
    taskqueue_locations = get_load_balancer_ips()

    server_node = '{}/{}:{}'.format(DATASTORE_SERVERS_NODE, options.private_ip,
                                    options.port)

    retry_policy = KazooRetry(max_tries=5)
    zk_client = kazoo.client.KazooClient(
        hosts=zookeeper_locations,
        connection_retry=ZK_PERSISTENT_RECONNECTS,
        command_retry=retry_policy)
    zk_client.start()

    if args.type == 'cassandra':
        datastore_batch = DatastoreFactory.getDatastore(
            args.type, log_level=logger.getEffectiveLevel())
        zookeeper = zktransaction.ZKTransaction(
            zk_client=zk_client,
            db_access=datastore_batch,
            log_level=logger.getEffectiveLevel())
        transaction_manager = TransactionManager(zk_client)
        datastore_access = DatastoreDistributed(
            datastore_batch,
            transaction_manager,
            zookeeper=zookeeper,
            log_level=logger.getEffectiveLevel(),
            taskqueue_locations=taskqueue_locations)
    else:
        from appscale.datastore.fdb.fdb_datastore import FDBDatastore
        clusterfile_path = args.fdb_clusterfile
        if not clusterfile_path:
            try:
                clusterfile_content = zk_client.get(FDB_CLUSTERFILE_NODE)[0]
                clusterfile_path = '/run/appscale/appscale-datastore-fdb.cluster'
                with open(clusterfile_path, 'w') as clusterfile:
                    clusterfile.write(clusterfile_content)
            except NoNodeError:
                logger.warning(
                    'Neither --fdb-clusterfile was specified nor {} ZK node exists,'
                    'FDB client will try to find clusterfile in one of default locations'
                    .format(FDB_CLUSTERFILE_NODE))
        datastore_access = FDBDatastore()
        datastore_access.start(clusterfile_path)

    zk_client.add_listener(zk_state_listener)
    zk_client.ensure_path(DATASTORE_SERVERS_NODE)
    # Since the client was started before adding the listener, make sure the
    # server node gets created.
    zk_state_listener(zk_client.state)
    zk_client.ChildrenWatch(DATASTORE_SERVERS_NODE, update_servers_watch)

    if args.type == 'cassandra':
        index_manager = IndexManager(zk_client,
                                     datastore_access,
                                     perform_admin=True)
        datastore_access.index_manager = index_manager

    server = tornado.httpserver.HTTPServer(pb_application)
    server.listen(args.port)

    IOLoop.current().start()
Beispiel #20
0
def main():
  """ Starts the AdminServer. """
  logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)

  parser = argparse.ArgumentParser(
    prog='appscale-admin', description='Manages AppScale-related processes')
  subparsers = parser.add_subparsers(dest='command')
  subparsers.required = True

  serve_parser = subparsers.add_parser(
    'serve', description='Starts the server that manages AppScale processes')
  serve_parser.add_argument(
    '-p', '--port', type=int, default=constants.DEFAULT_PORT,
    help='The port to listen on')
  serve_parser.add_argument(
    '-v', '--verbose', action='store_true', help='Output debug-level logging')

  subparsers.add_parser(
    'summary', description='Lists AppScale processes running on this machine')
  restart_parser = subparsers.add_parser(
    'restart',
    description='Restart AppScale processes running on this machine')
  restart_parser.add_argument('service', nargs='+',
                              help='The process or service ID to restart')

  args = parser.parse_args()
  if args.command == 'summary':
    table = sorted(list(get_combined_services().items()))
    print(tabulate(table, headers=['Service', 'State']))
    sys.exit(0)

  if args.command == 'restart':
    socket_path = urlquote(ServiceManagerHandler.SOCKET_PATH, safe='')
    session = requests_unixsocket.Session()
    response = session.post(
      'http+unix://{}/'.format(socket_path),
      data={'command': 'restart', 'arg': [args.service]})
    response.raise_for_status()
    return

  if args.verbose:
    logger.setLevel(logging.DEBUG)

  options.define('secret', appscale_info.get_secret())
  options.define('login_ip', appscale_info.get_login_ip())
  options.define('private_ip', appscale_info.get_private_ip())
  options.define('load_balancers', appscale_info.get_load_balancer_ips())

  acc = appscale_info.get_appcontroller_client()
  ua_client = UAClient(appscale_info.get_db_master_ip(), options.secret)
  zk_client = KazooClient(
    hosts=','.join(appscale_info.get_zk_node_ips()),
    connection_retry=ZK_PERSISTENT_RECONNECTS)
  zk_client.start()
  version_update_lock = zk_client.Lock(constants.VERSION_UPDATE_LOCK_NODE)
  thread_pool = ThreadPoolExecutor(4)
  monit_operator = MonitOperator()
  all_resources = {
    'acc': acc,
    'ua_client': ua_client,
    'zk_client': zk_client,
    'version_update_lock': version_update_lock,
    'thread_pool': thread_pool
  }

  if options.private_ip in appscale_info.get_taskqueue_nodes():
    logger.info('Starting push worker manager')
    GlobalPushWorkerManager(zk_client, monit_operator)

  service_manager = ServiceManager(zk_client)
  service_manager.start()

  app = web.Application([
    ('/oauth/token', OAuthHandler, {'ua_client': ua_client}),
    ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)/versions', VersionsHandler,
     {'ua_client': ua_client, 'zk_client': zk_client,
      'version_update_lock': version_update_lock, 'thread_pool': thread_pool}),
    ('/v1/projects', ProjectsHandler, all_resources),
    ('/v1/projects/([a-z0-9-]+)', ProjectHandler, all_resources),
    ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)', ServiceHandler,
     all_resources),
    ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)/versions/([a-z0-9-]+)',
     VersionHandler, all_resources),
    ('/v1/apps/([a-z0-9-]+)/operations/([a-z0-9-]+)', OperationsHandler,
     {'ua_client': ua_client}),
    ('/api/cron/update', UpdateCronHandler,
     {'acc': acc, 'zk_client': zk_client, 'ua_client': ua_client}),
    ('/api/datastore/index/add', UpdateIndexesHandler,
     {'zk_client': zk_client, 'ua_client': ua_client}),
    ('/api/queue/update', UpdateQueuesHandler,
     {'zk_client': zk_client, 'ua_client': ua_client})
  ])
  logger.info('Starting AdminServer')
  app.listen(args.port)

  management_app = web.Application([
    ('/', ServiceManagerHandler, {'service_manager': service_manager})])
  management_server = HTTPServer(management_app)
  management_socket = bind_unix_socket(ServiceManagerHandler.SOCKET_PATH)
  management_server.add_socket(management_socket)

  io_loop = IOLoop.current()
  io_loop.start()
Beispiel #21
0
def main():
  """ Main. """
  parser = argparse.ArgumentParser()
  parser.add_argument(
    '-v', '--verbose', action='store_true',
    help='Output debug-level logging')
  args = parser.parse_args()

  logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)
  if args.verbose:
    logging.getLogger().setLevel(logging.DEBUG)

  options.define('secret', appscale_info.get_secret())

  signal.signal(signal.SIGTERM, signal_handler)
  signal.signal(signal.SIGINT, signal_handler)

  my_ip = appscale_info.get_private_ip()
  is_master = (my_ip == appscale_info.get_headnode_ip())
  is_lb = (my_ip in appscale_info.get_load_balancer_ips())
  is_tq = (my_ip in appscale_info.get_taskqueue_nodes())

  if is_master:
    # Periodically check with the portal for new tasks.
    # Note: Currently, any active handlers from the tornado app will block
    # polling until they complete.
    PeriodicCallback(poll, constants.POLLING_INTERVAL).start()

    # Only master Hermes node handles /do_task route
    task_route = ('/do_task', TaskHandler)

    global zk_client
    zk_client = KazooClient(
      hosts=','.join(appscale_info.get_zk_node_ips()),
      connection_retry=ZK_PERSISTENT_RECONNECTS)
    zk_client.start()
    # Start watching profiling configs in ZooKeeper
    stats_app.ProfilingManager(zk_client)

    # Periodically checks if the deployment is registered and uploads the
    # appscalesensor app for registered deployments.
    sensor_deployer = SensorDeployer(zk_client)
    PeriodicCallback(sensor_deployer.deploy,
                     constants.UPLOAD_SENSOR_INTERVAL).start()
  else:
    task_route = ('/do_task', Respond404Handler,
                  dict(reason='Hermes slaves do not manage tasks from Portal'))

  app = tornado.web.Application([
      ("/", MainHandler),
      task_route,
    ]
    + stats_app.get_local_stats_api_routes(is_lb, is_tq)
    + stats_app.get_cluster_stats_api_routes(is_master),
    debug=False
  )
  app.listen(constants.HERMES_PORT)

  # Start loop for accepting http requests.
  IOLoop.instance().start()

  logging.info("Hermes is up and listening on port: {}."
               .format(constants.HERMES_PORT))
Beispiel #22
0
def main():
  """ Starts the AdminServer. """
  logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)

  parser = argparse.ArgumentParser(
    prog='appscale-admin', description='Manages AppScale-related processes')
  subparsers = parser.add_subparsers(dest='command')
  subparsers.required = True

  serve_parser = subparsers.add_parser(
    'serve', description='Starts the server that manages AppScale processes')
  serve_parser.add_argument(
    '-p', '--port', type=int, default=constants.DEFAULT_PORT,
    help='The port to listen on')
  serve_parser.add_argument(
    '-v', '--verbose', action='store_true', help='Output debug-level logging')

  subparsers.add_parser(
    'summary', description='Lists AppScale processes running on this machine')

  args = parser.parse_args()
  if args.command == 'summary':
    table = sorted(list(get_combined_services().items()))
    print(tabulate(table, headers=['Service', 'State']))
    sys.exit(0)

  if args.verbose:
    logger.setLevel(logging.DEBUG)

  options.define('secret', appscale_info.get_secret())
  options.define('login_ip', appscale_info.get_login_ip())
  options.define('private_ip', appscale_info.get_private_ip())
  options.define('load_balancers', appscale_info.get_load_balancer_ips())

  acc = appscale_info.get_appcontroller_client()
  ua_client = UAClient(appscale_info.get_db_master_ip(), options.secret)
  zk_client = KazooClient(
    hosts=','.join(appscale_info.get_zk_node_ips()),
    connection_retry=ZK_PERSISTENT_RECONNECTS)
  zk_client.start()
  version_update_lock = zk_client.Lock(constants.VERSION_UPDATE_LOCK_NODE)
  thread_pool = ThreadPoolExecutor(4)
  monit_operator = MonitOperator()
  all_resources = {
    'acc': acc,
    'ua_client': ua_client,
    'zk_client': zk_client,
    'version_update_lock': version_update_lock,
    'thread_pool': thread_pool
  }

  if options.private_ip in appscale_info.get_taskqueue_nodes():
    logger.info('Starting push worker manager')
    GlobalPushWorkerManager(zk_client, monit_operator)

  service_manager = ServiceManager(zk_client)
  service_manager.start()

  app = web.Application([
    ('/oauth/token', OAuthHandler, {'ua_client': ua_client}),
    ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)/versions', VersionsHandler,
     all_resources),
    ('/v1/projects', ProjectsHandler, all_resources),
    ('/v1/projects/([a-z0-9-]+)', ProjectHandler, all_resources),
    ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)', ServiceHandler,
     all_resources),
    ('/v1/apps/([a-z0-9-]+)/services/([a-z0-9-]+)/versions/([a-z0-9-]+)',
     VersionHandler, all_resources),
    ('/v1/apps/([a-z0-9-]+)/operations/([a-z0-9-]+)', OperationsHandler,
     {'ua_client': ua_client}),
    ('/api/cron/update', UpdateCronHandler,
     {'acc': acc, 'zk_client': zk_client, 'ua_client': ua_client}),
    ('/api/queue/update', UpdateQueuesHandler,
     {'zk_client': zk_client, 'ua_client': ua_client})
  ])
  logger.info('Starting AdminServer')
  app.listen(args.port)
  io_loop = IOLoop.current()
  io_loop.start()
Beispiel #23
0
def get_random_lb_node():
  return [random.choice(appscale_info.get_load_balancer_ips())]
Beispiel #24
0
def main():
    """ Main. """
    parser = argparse.ArgumentParser()
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='Output debug-level logging')
    args = parser.parse_args()

    logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)
    if args.verbose:
        logging.getLogger().setLevel(logging.DEBUG)

    options.define('secret', appscale_info.get_secret())

    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGINT, signal_handler)

    my_ip = appscale_info.get_private_ip()
    is_master = (my_ip == appscale_info.get_headnode_ip())
    is_lb = (my_ip in appscale_info.get_load_balancer_ips())
    is_tq = (my_ip in appscale_info.get_taskqueue_nodes())

    if is_master:
        # Periodically check with the portal for new tasks.
        # Note: Currently, any active handlers from the tornado app will block
        # polling until they complete.
        PeriodicCallback(poll, constants.POLLING_INTERVAL).start()

        # Only master Hermes node handles /do_task route
        task_route = ('/do_task', TaskHandler)

        global zk_client
        zk_client = KazooClient(hosts=','.join(
            appscale_info.get_zk_node_ips()),
                                connection_retry=ZK_PERSISTENT_RECONNECTS)
        zk_client.start()
        # Start watching profiling configs in ZooKeeper
        stats_app.ProfilingManager(zk_client)

        # Periodically checks if the deployment is registered and uploads the
        # appscalesensor app for registered deployments.
        sensor_deployer = SensorDeployer(zk_client)
        PeriodicCallback(sensor_deployer.deploy,
                         constants.UPLOAD_SENSOR_INTERVAL).start()
    else:
        task_route = (
            '/do_task', Respond404Handler,
            dict(reason='Hermes slaves do not manage tasks from Portal'))

    app = tornado.web.Application(
        [
            ("/", MainHandler),
            task_route,
        ] + stats_app.get_local_stats_api_routes(is_lb, is_tq) +
        stats_app.get_cluster_stats_api_routes(is_master),
        debug=False)
    app.listen(constants.HERMES_PORT)

    # Start loop for accepting http requests.
    IOLoop.instance().start()

    logging.info("Hermes is up and listening on port: {}.".format(
        constants.HERMES_PORT))