Exemple #1
0
def create_database():
  """
  Creates any missing tables.
  """
  db, cursor = selexorhelper.connect_to_db()
  code = open('database_create.sql', 'r').read()
  for line in code.split(';'):
    if line.strip():
      cursor.execute(line.strip())
Exemple #2
0
  def get_request_status(self, authinfo, remoteip):
    '''
    <Purpose>
      Returns the status of the current request.
    <Arguments>
      None
    <Exceptions>
      None
    <Side Effects>
      None
    <Return>
      A dictionary containing the status of each group.
      'group_id': 'group_status'

    '''
    db, cursor = selexorhelper.connect_to_db()

    cursor = db.cursor()

    data = {'groups':{}}
    try:
      username = authinfo.keys()[0]
      identity = (username, remoteip)
      if identity not in request_datum:
        data['status'] = "unknown"
        return data

      request_data = request_datum[identity]

      data['status'] = request_data['status']
      for group in request_data['groups'].values():
        data['groups'][group['id']] = {}
        group_data = data['groups'][group['id']]
        group_data['status'] = group['status']
        if 'error' in group:
          group_data['error'] = group['error']

        group_data['vessels_acquired'] = []
        for vesseldict in group['acquired']:
          vesselhandle = vesseldict['handle']
          nodeinfo = {}

          nodekey, nodeinfo['vesselname'] = vesselhandle.split(':')
          cursor.execute('SELECT ip_addr, node_port FROM nodes WHERE node_key="'+nodekey+'"')
          nodeinfo['node_ip'], nodeinfo['node_port'] = cursor.fetchone()
          nodeinfo['handle'] = vesselhandle

          group_data['vessels_acquired'].append(nodeinfo)

        group_data['target_num_vessels'] = group['allocate']
    except Exception, e:
      logger.error(str(identity) + ": Error while responding to status query\n" + traceback.format_exc())
      data['error'] = str(e)
Exemple #3
0
  def serve_request(self, identity, request_data, client):
    '''
    <Purpose>
      Serves a host request.

    <Arguments>
      identity:
        A user identity.
      request_data:
        A requestdict.
      client:
        The Seattle Clearinghouse XMLRPC client to use.

    <Side Effects>
      Attempts to obtain vessels described in the request_data. This is not
      guaranteed, depending on the ddata collected in the selexordatabase.

    <Exceptions>
      SeattleClearinghouse.
      InvalidRequestStringError

    <Returns>
      Returns the status of the request, as a string.

      'timeout':
        The request did not finish in the allocated time.
      'complete':
        Selexor successfully finished the request.

    '''
    logger.info(str(identity) + ": Request data:\n" + str(request_data))
    db, cursor = selexorhelper.connect_to_db()

    for groupname, group in request_data['groups'].iteritems():
      pass_no = 0
      while pass_no < 5:
        try:
          logger.info(str(identity) + ": Resolving group: " + str(groupname))
          group = self.resolve_node(identity, client, group, db, cursor)
          # We are done here, no need to proceed with the remaining
          # passes
          if group['status'] != STATUS_INCOMPLETE:
            break

        except seattleclearinghouse_xmlrpc.NotEnoughCreditsError, e:
          group['status'] = 'error'
          group['error'] = str(e)
          logger.info(str(identity) + ": Not enough credits.")
          request_data['status'] = 'error'
          return
        except:
Exemple #4
0
  def release_vessels(self, authdata, vessels_to_release, remoteip):
    '''
    <Purpose>
      Returns the # of vessels released
    <Arguments>
      authdata:
        An authdict. See module documentation for more information.
      vessels:
        A list of dictionaries containing vessel information of the vessels
        to release.  These dictionaries should either contain the vessel handle,
        or node_ip:node_port:vesselname.
      remoteip:
        The remote IP address of the client. This is used for client identification.
    <Exceptions>
      None
    <Side Effects>
      None
    <Return>
      A dictionary containing the status of each group.
      'group_id': 'group_status'

    '''
    try:
      username = authdata.keys()[0]
      identity = (username, remoteip)
      logger.info(str(identity) + "> Release: " + str(vessels_to_release))

      # There's nothing to do if there aren't any vessels to release
      if not vessels_to_release:
        return 0

      handles_of_vessels_to_release = []
      for vesseldict in vessels_to_release:
        if 'node_handle' in vesseldict:
          handles_of_vessels_to_release.append(vesseldict['node_handle'])
        else:
          # Do we have this information in the database?
          db, cursor = selexorhelper.connect_to_db()

          # If it is found, the lookup returns a 1L.
          node_in_db = 1L == cursor.execute("SELECT node_key FROM nodes WHERE ip_addr='"+vesseldict['node_ip']+"' AND node_port="+str(vesseldict['node_port']))
          if node_in_db:
            [node_key] = cursor.fetchone()
            logger.debug('\n'.join([
                str(identity),
                "Found node in database: "+vesseldict['node_ip']+':'+str(int(vesseldict['node_port']))+':'+vesseldict['vesselname']+" with key:",
                node_key]))
            handles_of_vessels_to_release.append(node_key+':'+vesseldict['vesselname'])

          else:
            # Try to connect to that node to get the handle
            vessel_location = vesseldict['node_ip']+':'+str(int(vesseldict['node_port']))+':'+vesseldict['vesselname']
            try:
              handles_of_vessels_to_release.append(get_handle_from_nodehandle(vessel_location))
            except fastnmclient.NMClientException, e:
              logger.info("Failed to look up vessel "+vessel_location+' through nodemanager: '+ str(e))

      client = selexorhelper.connect_to_clearinghouse(authdata)

      # Release the remaining vessels
      for vessel in handles_of_vessels_to_release:
        # Do we need to check if a vessel failed to release?
        # Maybe it means that a vessel has gone offline/is now invalid.
        client.release_resources([vessel])

      # Assume all the vessels were released successfully
      num_released = len(handles_of_vessels_to_release)

      # Remove vessel entries from the groups tables.
      if identity in request_datum:
        for group in request_datum[identity]['groups']:
          for vesselhandle in handles_of_vessels_to_release:
            if vesselhandle in request_datum[identity]['groups'][group]['acquired']:
              request_datum[identity]['groups'][group]['acquired'].remove(vesselhandle)
              request_datum[identity]['groups'][group]['allocate'] -= 1
Exemple #5
0
def contact_vessels_and_update_database(nodes_to_check):
  '''
  Of all nodes that need checking, take one node.
  Obtain its:
    IP address
    name of each vessel on it
    Location
  For each vessel, obtain:
    vessel name
    ports available
  Finally, update the information about these nodes.

  '''
  db, cursor = selexorhelper.connect_to_db()

  while nodes_to_check:
    nodelocation = nodes_to_check.pop()
    nodeinfo = selexorhelper.get_node_ip_port_from_nodelocation(nodelocation)

    # We can't use NAT addresses, nor ipv6
    if not selexorhelper.is_ipv4_address(nodeinfo['id']):
      # if nodeinfo['id'].startswith('NAT'):
        # self._nat_nodes.append(nodeinfo['id'])
      continue

    # Used to communicate with the node
    node_nmhandle = None
    try:
      node_nmhandle = nmclient_createhandle(nodeinfo['id'], nodeinfo['port'])
      node_dict = nmclient_getvesseldict(node_nmhandle)

      ports = {}
      for vesselname in node_dict['vessels']:
        resources_string = nmclient_rawsay(node_nmhandle, "GetVesselResources", vesselname)
        ports[vesselname] = selexorhelper.get_ports_from_resource_string(resources_string)
        node_dict['vessels'][vesselname]['acquirable'] = \
          selexorhelper.is_resource_acquirable(resources_string)

      # Retrieve the geographic information
      try:
        # We need to some initial value so that it is not undefined when we check it later.
        geoinfo = None

        # Only retrieve the geographic information if we don't have it already
        # The geoip server's data doesn't change, so we don't need to constantly update it.
        geoinfo_exists = selexorhelper.autoretry_mysql_command(cursor, "SELECT ip_addr FROM location WHERE ip_addr='"+nodeinfo['id']+"'") == 1L
        if not geoinfo_exists:
          logger.info("Location data not in database, looking up on geoip: "+nodelocation)
          geoinfo = geoip_record_by_addr(nodeinfo['id'])

      except Exception, e:
        if not "Unable to contact the geoip server" in str(e):
          raise
      # The geoip lookup sometimes returns None.
      if geoinfo is None:
        geoinfo = {}
      format_geoinfo(geoinfo)

      commit_data_to_database(db, cursor, nodeinfo['id'], nodeinfo['port'], node_dict, ports, geoinfo)

    except NMClientException, e:
      if not node_nmhandle:
        nmclient_destroyhandle(node_nmhandle)
      # self._bad_node_locations.append(nodelocation)
      errstr = str(e)
      if ("timed out" in errstr or
          'No connection could be made because the target machine actively refused it' in errstr or
          "Connection refused" in errstr or
          "Socket closed" in errstr):
        continue
      logger.error("Unknown error contacting " + nodelocation + traceback.format_exc())