Пример #1
0
 def _processMessages(self, node, messages):
     # Push the messages into the database, recording them for this node.
     # This should be called in a non-reactor thread with a pre-existing
     # connection (e.g. via deferToDatabase).
     if in_transaction():
         raise TransactionManagementError(
             "_processMessages must be called from "
             "outside of a transaction.")
     else:
         # Here we're in a database thread, with a database connection.
         # We only save the last_ping off the last message in the
         # list of messages. This removes the number of database saves
         # required.
         for idx, message in enumerate(messages):
             try:
                 self._processMessage(node, message)
             except:
                 log.err(
                     None, "Failed to process message "
                     "for node: %s" % node.hostname)
             if idx == len(messages) - 1:
                 try:
                     self._updateLastPing(node, message)
                 except:
                     log.err(
                         None, "Failed to update last ping "
                         "for node: %s" % node.hostname)
Пример #2
0
def populate_tags(tag):
    """Evaluate `tag` for all nodes.

    This returns a `Deferred` that will fire when all tags have been
    evaluated. The return value is intended FOR TESTING ONLY because:

    - You must not use the `Deferred` in the calling thread; it must only be
      manipulated in the reactor thread. Pretending it's not there is safer
      than chaining code onto it because it's easy to get wrong.

    - The call may not finish for 10 minutes or more. It is therefore not a
      good thing to be waiting for in a web request.

    """
    # This function cannot be called inside a transaction. The function manages
    # its own transaction.
    if in_transaction():
        raise TransactionManagementError(
            '`populate_tags` cannot be called inside an existing transaction.')

    logger.debug('Evaluating the "%s" tag for all nodes.', tag.name)

    clients = getAllClients()
    if len(clients) == 0:
        # We have no clients so we need to do the work locally.
        @transactional
        def _populate_tag():
            return populate_tag_for_multiple_nodes(tag, Node.objects.all())

        return _populate_tag()
    else:
        # Split the work between the connected rack controllers.
        @transactional
        def _generate_work():
            node_ids = Node.objects.all().values_list("system_id", flat=True)
            node_ids = [{"system_id": node_id} for node_id in node_ids]
            chunked_node_ids = list(chunk_list(node_ids, len(clients)))
            connected_racks = []
            for idx, client in enumerate(clients):
                rack = RackController.objects.get(system_id=client.ident)
                token = _get_or_create_auth_token(rack.owner)
                creds = convert_tuple_to_string(get_creds_tuple(token))
                if len(chunked_node_ids) > idx:
                    connected_racks.append({
                        "system_id": rack.system_id,
                        "hostname": rack.hostname,
                        "client": client,
                        "tag_name": tag.name,
                        "tag_definition": tag.definition,
                        "tag_nsmap": [
                            {"prefix": prefix, "uri": uri}
                            for prefix, uri in tag_nsmap.items()
                        ],
                        "credentials": creds,
                        "nodes": list(chunked_node_ids[idx]),
                    })
            return connected_racks

        return _do_populate_tags(_generate_work())
Пример #3
0
 def _processMessageNow(self, authorization, message):
     # This should be called in a non-reactor thread with a pre-existing
     # connection (e.g. via deferToDatabase).
     if in_transaction():
         raise TransactionManagementError(
             "_processMessageNow must be called from "
             "outside of a transaction.")
     else:
         try:
             node = transactional(
                 NodeKey.objects.get_node_for_key)(authorization)
         except NodeKey.DoesNotExist:
             # The node that should get this message has already had its
             # owner cleared or changed and this message cannot be saved.
             return None
         else:
             self._processMessage(node, message)
Пример #4
0
 def _processMessages(self, node, messages):
     # Push the messages into the database, recording them for this node.
     # This should be called in a non-reactor thread with a pre-existing
     # connection (e.g. via deferToDatabase).
     if in_transaction():
         raise TransactionManagementError(
             "_processMessages must be called from "
             "outside of a transaction.")
     else:
         # Here we're in a database thread, with a database connection.
         for idx, message in enumerate(messages):
             try:
                 exists = self._processMessage(node, message)
                 if not exists:
                     # Node has been deleted no reason to continue saving
                     # the events for this node.
                     break
             except:
                 log.err(
                     None, "Failed to process message "
                     "for node: %s" % node.hostname)