コード例 #1
0
ファイル: master.py プロジェクト: wprelic/grr
 def SyncMapping(self, skip=None):
   """Syncs mapping with other servers."""
   pools = []
   try:
     # Update my state.
     self._PeriodicThread()
     for serv in self.servers[1:]:
       if skip and serv in skip:
         continue
       pool = connectionpool.HTTPConnectionPool(serv.Address(),
                                                port=serv.Port())
       pools.append((serv, pool))
     body = self.mapping.SerializeToString()
     headers = {"Content-Length": len(body)}
     for serv, pool in pools:
       res = pool.urlopen("POST", "/servers/sync", headers=headers,
                          body=body)
       if res.status != constants.RESPONSE_OK:
         logging.warning("Could not sync with server %s:%d", serv.Address(),
                         serv.Port())
         return False
       state = rdf_data_server.DataServerState()
       state.ParseFromString(res.data)
       serv.UpdateState(state)
   except urllib3.exceptions.MaxRetryError:
     return False
   finally:
     for _, pool in pools:
       pool.close()
   return True
コード例 #2
0
ファイル: manager.py プロジェクト: stevensfwang-via/grr
  def _Sync(self):
    """Forces the master to sync with the other data servers."""
    pool = None
    try:
      pool = connectionpool.HTTPConnectionPool(self.addr, port=self.port)
      body = ""
      headers = {"Content-Length": len(body)}
      res = pool.urlopen(
          "POST", "/servers/sync-all", headers=headers, body=body)

      if res.status == constants.RESPONSE_INCOMPLETE_SYNC:
        print "Master has tried to contact all the data servers, but failed."
        return False

      if res.status == constants.RESPONSE_DATA_SERVERS_UNREACHABLE:
        print "Master server says that some data servers are not running."
        print "Giving up..."
        return False

      if res.status != constants.RESPONSE_OK:
        print "Unable to sync servers."
        return False
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact master..."
      return False
    print "Sync done."
    # Update mapping.
    self.mapping = rdf_data_server.DataServerMapping(res.data)
    return True
コード例 #3
0
ファイル: manager.py プロジェクト: wprelic/grr
    def _Recover(self, transid):
        """Completes a rebalancing transaction that was unsuccessful."""
        print "Contacting master about transaction %s..." % transid,
        pool = None
        try:
            pool = connectionpool.HTTPConnectionPool(self.addr, port=self.port)
        except urllib3.exceptions.MaxRetryError:
            print "Unable to contact master..."
            return

        print "OK."

        try:
            body = transid
            headers = {"Content-Length": len(body)}
            res = pool.urlopen("POST",
                               "/rebalance/recover",
                               headers=headers,
                               body=body)
        except urllib3.exceptions.MaxRetryError:
            print "Unable to contact master..."
            return

        if res.status == constants.RESPONSE_TRANSACTION_NOT_FOUND:
            print "Transaction %s was not found" % transid
            return
        if res.status != constants.RESPONSE_OK:
            print "Potential data master error. Giving up..."
            return
        rebalance = rdf_data_server.DataServerRebalance(res.data)
        print "Got transaction object %s" % rebalance.id
        answer = raw_input("Proceed with the recover process? (y/n) ")
        if answer != "y":
            return

        body = rebalance.SerializeToString()
        headers = {"Content-Length": len(body)}

        try:
            res = pool.urlopen("POST",
                               "/rebalance/commit",
                               headers=headers,
                               body=body)
        except urllib3.exceptions.MaxRetryError:
            print "Could not commit re-sharding transaction with id %s" % rebalance.id
            print "Make sure the data servers are up and then run:"
            print "'recover %s' in order to re-run transaction" % rebalance.id
            return

        if res.status != constants.RESPONSE_OK:
            print "Could not commit transaction %s" % rebalance.id
            print "Make sure the data servers are up and then run:"
            print "'recover %s' in order to re-run transaction" % rebalance.id
            return

        self.mapping = rdf_data_server.DataServerMapping(res.data)
        print "Rebalance with id %s fully performed." % rebalance.id
コード例 #4
0
ファイル: master.py プロジェクト: wprelic/grr
 def SetRebalancing(self, reb):
   """Sets a new rebalance operation and starts communication with servers."""
   self.rebalance = reb
   self.rebalance_pool = []
   try:
     for serv in self.servers:
       pool = connectionpool.HTTPConnectionPool(serv.Address(),
                                                port=serv.Port())
       self.rebalance_pool.append(pool)
   except urllib3.exceptions.MaxRetryError:
     self.CancelRebalancing()
     return False
   return True
コード例 #5
0
ファイル: manager.py プロジェクト: stevensfwang-via/grr
 def __init__(self):
   servers = config_lib.CONFIG["Dataserver.server_list"]
   if not servers:
     raise errors.DataServerError("List of data servers not available.")
   master_location = servers[0]
   loc = urlparse.urlparse(master_location, scheme="http")
   self.addr = loc.hostname
   self.port = int(loc.port)
   self.pool = connectionpool.HTTPConnectionPool(self.addr, port=self.port)
   self.history_path = os.path.expanduser("~/.grr-data-store-manager")
   if os.path.exists(self.history_path):
     readline.read_history_file(self.history_path)
   self.periodic_thread = None
   self.mapping = None
   self.mapping_time = 0
コード例 #6
0
ファイル: data_server.py プロジェクト: wprelic/grr
 def __init__(self, my_port):
     servers = config_lib.CONFIG["Dataserver.server_list"]
     if not servers:
         raise errors.DataServerError("List of data servers not available.")
     master_location = servers[0]
     loc = urlparse.urlparse(master_location, scheme="http")
     self.index = None
     self.master_addr = loc.hostname
     self.master_port = loc.port
     self.my_port = my_port
     self.pool = connectionpool.HTTPConnectionPool(self.master_addr,
                                                   port=int(
                                                       self.master_port),
                                                   maxsize=1)
     self.registered = False
     self.periodic_fail = 0
コード例 #7
0
ファイル: rebalance.py プロジェクト: stevensfwang-via/grr
def _RecCopyFiles(rebalance, server_id, dspath, subpath, pool_cache,
                  removed_list):
  """Recursively send files for moving to the required data server."""
  fulldir = utils.JoinPath(dspath, subpath)
  mapping = rebalance.mapping
  for comp in os.listdir(fulldir):
    if comp == constants.REBALANCE_DIRECTORY:
      continue
    path = utils.JoinPath(fulldir, comp)
    name, unused_extension = os.path.splitext(comp)
    if name in COPY_EXCEPTIONS:
      continue
    if os.path.isdir(path):
      result = _RecCopyFiles(rebalance, server_id, dspath,
                             utils.JoinPath(subpath, comp), pool_cache,
                             removed_list)
      if not result:
        return False
      continue
    if not os.path.isfile(path):
      continue
    key = common.MakeDestinationKey(subpath, name)
    where = sutils.MapKeyToServer(mapping, key)
    if where != server_id:
      server = mapping.servers[where]
      addr = server.address
      port = server.port
      key = (addr, port)
      try:
        pool = pool_cache[key]
      except KeyError:
        pool = connectionpool.HTTPConnectionPool(addr, port=port)
        pool_cache[key] = pool
      logging.info("Need to move %s from %d to %d", key, server_id, where)
      if not _SendFileToServer(pool, path, subpath, comp, rebalance):
        return False
      removed_list.append(path)
    else:
      logging.info("File %s stays here", path)
  return True
コード例 #8
0
ファイル: manager.py プロジェクト: stevensfwang-via/grr
  def _RemServer(self, addr, port):
    """Remove server from group."""
    # Find server.
    server, _ = self._FindServer(addr, port)
    if not server:
      print "Server not found."
      return
    if server.interval.start != server.interval.end:
      print "Server has some data in it!"
      print "Giving up..."
      return

    pool = None
    try:
      pool = connectionpool.HTTPConnectionPool(self.addr, port=self.port)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact master..."
      return

    body = self._PackNewServer(addr, port)
    headers = {"Content-Length": len(body)}
    try:
      res = pool.urlopen(
          "POST", "/servers/rem/check", headers=headers, body=body)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact master..."
      return

    if res.status == constants.RESPONSE_DATA_SERVER_NOT_FOUND:
      print "Master server says the data server does not exist."
      return

    if res.status == constants.RESPONSE_RANGE_NOT_EMPTY:
      print "Master server says the data server has still some data."
      print "Giving up..."
      return

    if res.status == constants.RESPONSE_DATA_SERVERS_UNREACHABLE:
      print "Master server says some data servers are not running."
      print "Giving up..."
      return

    if res.status != constants.RESPONSE_OK:
      print "Master server error. Is the server running?"
      return

    print "Master server allows us to remove server %s:%d" % (addr, port)

    answer = raw_input("Do you really want to remove server //%s:%d? (y/n) " %
                       (addr, port))
    if answer != "y":
      return

    try:
      res = pool.urlopen("POST", "/servers/rem", headers=headers, body=body)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact master..."
      return

    if res.status == constants.RESPONSE_DATA_SERVERS_UNREACHABLE:
      print "Master server says that some data servers are not running."
      print "Giving up..."
      return

    if res.status == constants.RESPONSE_OK:
      # Update mapping.
      self.mapping = rdf_data_server.DataServerMapping(res.data)
      self._CompleteRemServerHelpComplete(addr, port)
      return

    if res.status == constants.RESPONSE_INCOMPLETE_SYNC:
      # We were unable to sync, so we try again:
      if self._Sync():
        self._CompleteRemServerHelpComplete(addr, port)
        return
      else:
        # If we cannot sync in the second attempt, we give up.
        print("The master server has removed the new server, but the other "
              "servers may not know about it.")

        print "Please run 'sync' to fix the problem, followed by:"
        self._CompleteRemServerHelp(addr, port)
        return

    if res.status != constants.RESPONSE_OK:
      print "Master has returned an unknown error..."
      return
コード例 #9
0
ファイル: manager.py プロジェクト: stevensfwang-via/grr
  def _AddServer(self, addr, port):
    """Starts the process of adding a new server."""
    if port <= 0:
      print "Wrong port: %d" % port
      return
    pool = None
    try:
      pool = connectionpool.HTTPConnectionPool(self.addr, port=self.port)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact master..."
      return

    body = self._PackNewServer(addr, port)
    headers = {"Content-Length": len(body)}
    try:
      res = pool.urlopen(
          "POST", "/servers/add/check", headers=headers, body=body)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact master..."
      return

    if res.status == constants.RESPONSE_EQUAL_DATA_SERVER:
      print "Master server says there is already a similar server."
      print "Giving up..."
      return

    if res.status == constants.RESPONSE_DATA_SERVERS_UNREACHABLE:
      print "Master server says that some data servers are not running."
      print "Giving up..."
      return

    if res.status != constants.RESPONSE_OK:
      print "Master server error. Is the server running?"
      return

    print "Master server allows us to add server %s:%d" % (addr, port)

    answer = raw_input("Do you really want to add server //%s:%d? (y/n) " %
                       (addr, port))
    if answer != "y":
      return

    try:
      res = pool.urlopen("POST", "/servers/add", headers=headers, body=body)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact master..."
      return

    if res.status == constants.RESPONSE_DATA_SERVERS_UNREACHABLE:
      print "Master server says that some data servers are not running."
      print "Giving up..."
      return

    if res.status == constants.RESPONSE_INCOMPLETE_SYNC:
      print("The master server has set up the new server, but the other "
            "servers may not know about it.")
      print "Please run 'sync' to fix the problem."
      print "Afterwards, you have to rebalance server data with the following:"
      self._CompleteAddServerHelp(addr, port)
      return

    if res.status != constants.RESPONSE_OK:
      print "Failed to contact master server."
      return

    print "============================================="
    print "Operation completed."
    print "To rebalance server data you have to do the following:"
    self._CompleteAddServerHelp(addr, port)

    # Update mapping.
    self.mapping = rdf_data_server.DataServerMapping(res.data)
コード例 #10
0
ファイル: manager.py プロジェクト: stevensfwang-via/grr
  def _DoRebalance(self, new_mapping):
    """Performs a new rebalancing operation with the master server."""
    print "Contacting master server to start re-sharding...",
    # Send mapping information to master.
    pool = None
    try:
      pool = connectionpool.HTTPConnectionPool(self.addr, port=self.port)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact master..."
      return
    body = new_mapping.SerializeToString()
    headers = {"Content-Length": len(body)}
    res = None
    try:
      res = pool.urlopen(
          "POST", "/rebalance/phase1", headers=headers, body=body)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to talk with master..."
      pool.close()
      return
    if res.status != constants.RESPONSE_OK:
      print "Re-sharding cannot be done!"
      return
    rebalance = rdf_data_server.DataServerRebalance(res.data)
    print "OK"
    print
    print "The following servers will need to move data:"
    for i, move in enumerate(list(rebalance.moving)):
      print "Server %d moves %dKB" % (i, move / 1024)
    answer = raw_input("Proceed with re-sharding? (y/n) ")
    if answer != "y":
      return
    body = rebalance.SerializeToString()
    headers = {"Content-Length": len(body)}
    try:
      res = pool.urlopen(
          "POST", "/rebalance/phase2", headers=headers, body=body)
    except urllib3.exceptions.MaxRetryError:
      print "Unable to contact server for re-sharding."
      print "Make sure the data servers are up and try again."
      return
    if res.status != constants.RESPONSE_OK:
      print "Could not start copying files for re-sharding"
      print "Make sure the data servers are up and try again."
      return

    try:
      res = pool.urlopen(
          "POST", "/rebalance/commit", headers=headers, body=body)
    except urllib3.exceptions.MaxRetryError:
      print("Could not commit the re-sharding transaction with id "
            "%s") % rebalance.id
      print "Make sure the data servers are up and then run:"
      print "'recover %s' in order to re-run transaction" % rebalance.id
      return

    if res.status != constants.RESPONSE_OK:
      print "Could not commit the transaction %s" % rebalance.id
      print "Make sure the data servers are up and then run:"
      print "'recover %s' in order to re-run transaction" % rebalance.id
      return

    self.mapping = rdf_data_server.DataServerMapping(res.data)

    print "Rebalance with id %s fully performed." % rebalance.id