def _cleanup_single_vessel(vessel):
  """
  This function is passed by cleanup_vessels() as the function argument to
  run_parallelized().
  """
  
  # This does seem wasteful of lockserver communication to require four
  # round-trips with the lockserver (get handle, lock, unlock, release handle),
  # but if we really want to fix that then I think the best thing to do would
  # be to allow obtaining a lockhandle and releasing a lockhandle to be done
  # in the same calls as lock acquisition and release. 
  
  node_id = maindb.get_node_identifier_from_vessel(vessel)
  lockserver_handle = lockserver.create_lockserver_handle()
  
  # Lock the node that the vessels is on.
  lockserver.lock_node(lockserver_handle, node_id)
  try:
    # Get a new vessel object from the db in case it was modified in the db
    # before the lock was obtained.
    vessel = maindb.get_vessel(node_id, vessel.name)
    
    # Now that we have a lock on the node that this vessel is on, find out
    # if we should still clean up this vessel (e.g. maybe a node state
    # transition script moved the node to a new state and this vessel was
    # removed).
    needscleanup, reasonwhynot = maindb.does_vessel_need_cleanup(vessel)
    if not needscleanup:
      log.info("[_cleanup_single_vessel] Vessel " + str(vessel) + 
               " no longer needs cleanup: " + reasonwhynot)
      return
    
    nodeid = maindb.get_node_identifier_from_vessel(vessel)
    nodehandle = _get_node_handle_from_nodeid(nodeid)
    
    try:
      log.info("[_cleanup_single_vessel] About to ChangeUsers on vessel " + str(vessel))
      nodemanager.change_users(nodehandle, vessel.name, [''])
      log.info("[_cleanup_single_vessel] About to ResetVessel on vessel " + str(vessel))
      nodemanager.reset_vessel(nodehandle, vessel.name)
    except NodemanagerCommunicationError:
      # We don't pass this exception up. Maybe the node is offline now. At some
      # point, it will be marked in the database as offline (should we be doing
      # that here?). At that time, the dirty vessels on that node will not be
      # in the cleanup list anymore.
      log.info("[_cleanup_single_vessel] Failed to cleanup vessel " + 
               str(vessel) + ". " + traceback.format_exc())
      return
      
    # We only mark it as clean if no exception was raised when trying to
    # perform the above nodemanager operations.
    maindb.mark_vessel_as_clean(vessel)
  
    log.info("[_cleanup_single_vessel] Successfully cleaned up vessel " + str(vessel))

  finally:
    # Unlock the node.
    lockserver.unlock_node(lockserver_handle, node_id)
    lockserver.destroy_lockserver_handle(lockserver_handle)
  def SetVesselUsers(*args):
    """
    This is a public function of the XMLRPC server. See the module comments at
    the top of the file for a description of how it is used.
    """
    _assert_number_of_arguments('SetVesselUsers', args, 3)
    (nodeid, vesselname, userkeylist) = args
    
    assert_str(nodeid)
    assert_str(vesselname)
    assert_list(userkeylist)
    
    for userkey in userkeylist:
      assert_str(userkey)

    # Note: The nodemanager checks whether each key is a valid key and will
    #       raise an exception if it is not.
      
    # Raises a DoesNotExistError if there is no node with this nodeid.
    nodehandle = _get_node_handle_from_nodeid(nodeid)
    
    # Raises NodemanagerCommunicationError if it fails.
    nodemanager.change_users(nodehandle, vesselname, userkeylist)
Exemplo n.º 3
0
    def SetVesselUsers(*args):
        """
    This is a public function of the XMLRPC server. See the module comments at
    the top of the file for a description of how it is used.
    """
        _assert_number_of_arguments('SetVesselUsers', args, 3)
        (nodeid, vesselname, userkeylist) = args

        assert_str(nodeid)
        assert_str(vesselname)
        assert_list(userkeylist)

        for userkey in userkeylist:
            assert_str(userkey)

        # Note: The nodemanager checks whether each key is a valid key and will
        #       raise an exception if it is not.

        # Raises a DoesNotExistError if there is no node with this nodeid.
        nodehandle = _get_node_handle_from_nodeid(nodeid)

        # Raises NodemanagerCommunicationError if it fails.
        nodemanager.change_users(nodehandle, vesselname, userkeylist)
def _sync_user_keys_of_single_vessel(vessel):
  """
  This function is passed by sync_user_keys_of_vessels() as the function
  argument to run_parallelized().
  """
  
  # This does seem wasteful of lockserver communication to require four
  # round-trips with the lockserver (get handle, lock, unlock, release handle),
  # but if we really want to fix that then I think the best thing to do would
  # be to allow obtaining a lockhandle and releasing a lockhandle to be done
  # in the same calls as lock acquisition and release. 
  
  node_id = maindb.get_node_identifier_from_vessel(vessel)
  lockserver_handle = lockserver.create_lockserver_handle()
  
  # Lock the node that the vessels is on.
  lockserver.lock_node(lockserver_handle, node_id)
  try:
    # Get a new vessel object from the db in case it was modified in the db
    # before the lock was obtained.
    vessel = maindb.get_vessel(node_id, vessel.name)
  
    # Now that we have a lock on the node that this vessel is on, find out
    # if we should still sync user keys on this vessel (e.g. maybe a node state
    # transition script moved the node to a new state and this vessel was
    # removed).
    needssync, reasonwhynot = maindb.does_vessel_need_user_key_sync(vessel)
    if not needssync:
      log.info("[_sync_user_keys_of_single_vessel] Vessel " + str(vessel) + 
               " no longer needs user key sync: " + reasonwhynot)
      return
    
    nodeid = maindb.get_node_identifier_from_vessel(vessel)
    nodehandle = _get_node_handle_from_nodeid(nodeid)
    
    # The list returned from get_users_with_access_to_vessel includes the key of
    # the user who has acquired the vessel along with any other users they have
    # given access to.
    user_list = maindb.get_users_with_access_to_vessel(vessel)
    
    key_list = []
    for user in user_list:
      key_list.append(user.user_pubkey)
      
    if len(key_list) == 0:
      raise InternalError("InternalError: Empty user key list for vessel " + str(vessel))
    
    try:
      log.info("[_sync_user_keys_of_single_vessel] About to ChangeUsers on vessel " + str(vessel))
      nodemanager.change_users(nodehandle, vessel.name, key_list)
    except NodemanagerCommunicationError:
      # We don't pass this exception up. Maybe the node is offline now. At some
      # point, it will be marked in the database as offline and won't show up in
      # our list of vessels to sync user keys of anymore.
      log.info("[_sync_user_keys_of_single_vessel] Failed to sync user keys of vessel " + 
               str(vessel) + ". " + traceback.format_exc())
      return
      
    # We only mark it as sync'd if no exception was raised when trying to perform
    # the above nodemanager operations.
    maindb.mark_vessel_as_not_needing_user_key_sync(vessel)
  
    log.info("[_sync_user_keys_of_single_vessel] Successfully sync'd user keys of vessel " + str(vessel))

  finally:
    # Unlock the node.
    lockserver.unlock_node(lockserver_handle, node_id)
    lockserver.destroy_lockserver_handle(lockserver_handle)
Exemplo n.º 5
0
def _sync_user_keys_of_single_vessel(vessel):
    """
  This function is passed by sync_user_keys_of_vessels() as the function
  argument to run_parallelized().
  """

    # This does seem wasteful of lockserver communication to require four
    # round-trips with the lockserver (get handle, lock, unlock, release handle),
    # but if we really want to fix that then I think the best thing to do would
    # be to allow obtaining a lockhandle and releasing a lockhandle to be done
    # in the same calls as lock acquisition and release.

    node_id = maindb.get_node_identifier_from_vessel(vessel)
    lockserver_handle = lockserver.create_lockserver_handle()

    # Lock the node that the vessels is on.
    lockserver.lock_node(lockserver_handle, node_id)
    try:
        # Get a new vessel object from the db in case it was modified in the db
        # before the lock was obtained.
        vessel = maindb.get_vessel(node_id, vessel.name)

        # Now that we have a lock on the node that this vessel is on, find out
        # if we should still sync user keys on this vessel (e.g. maybe a node state
        # transition script moved the node to a new state and this vessel was
        # removed).
        needssync, reasonwhynot = maindb.does_vessel_need_user_key_sync(vessel)
        if not needssync:
            log.info("[_sync_user_keys_of_single_vessel] Vessel " +
                     str(vessel) + " no longer needs user key sync: " +
                     reasonwhynot)
            return

        nodeid = maindb.get_node_identifier_from_vessel(vessel)
        nodehandle = _get_node_handle_from_nodeid(nodeid)

        # The list returned from get_users_with_access_to_vessel includes the key of
        # the user who has acquired the vessel along with any other users they have
        # given access to.
        user_list = maindb.get_users_with_access_to_vessel(vessel)

        key_list = []
        for user in user_list:
            key_list.append(user.user_pubkey)

        if len(key_list) == 0:
            raise InternalError(
                "InternalError: Empty user key list for vessel " + str(vessel))

        try:
            log.info(
                "[_sync_user_keys_of_single_vessel] About to ChangeUsers on vessel "
                + str(vessel))
            nodemanager.change_users(nodehandle, vessel.name, key_list)
        except NodemanagerCommunicationError:
            # We don't pass this exception up. Maybe the node is offline now. At some
            # point, it will be marked in the database as offline and won't show up in
            # our list of vessels to sync user keys of anymore.
            log.info(
                "[_sync_user_keys_of_single_vessel] Failed to sync user keys of vessel "
                + str(vessel) + ". " + traceback.format_exc())
            return

        # We only mark it as sync'd if no exception was raised when trying to perform
        # the above nodemanager operations.
        maindb.mark_vessel_as_not_needing_user_key_sync(vessel)

        log.info(
            "[_sync_user_keys_of_single_vessel] Successfully sync'd user keys of vessel "
            + str(vessel))

    finally:
        # Unlock the node.
        lockserver.unlock_node(lockserver_handle, node_id)
        lockserver.destroy_lockserver_handle(lockserver_handle)
Exemplo n.º 6
0
def _cleanup_single_vessel(vessel):
    """
  This function is passed by cleanup_vessels() as the function argument to
  run_parallelized().
  """

    # This does seem wasteful of lockserver communication to require four
    # round-trips with the lockserver (get handle, lock, unlock, release handle),
    # but if we really want to fix that then I think the best thing to do would
    # be to allow obtaining a lockhandle and releasing a lockhandle to be done
    # in the same calls as lock acquisition and release.

    node_id = maindb.get_node_identifier_from_vessel(vessel)
    lockserver_handle = lockserver.create_lockserver_handle()

    # Lock the node that the vessels is on.
    lockserver.lock_node(lockserver_handle, node_id)
    try:
        # Get a new vessel object from the db in case it was modified in the db
        # before the lock was obtained.
        vessel = maindb.get_vessel(node_id, vessel.name)

        # Now that we have a lock on the node that this vessel is on, find out
        # if we should still clean up this vessel (e.g. maybe a node state
        # transition script moved the node to a new state and this vessel was
        # removed).
        needscleanup, reasonwhynot = maindb.does_vessel_need_cleanup(vessel)
        if not needscleanup:
            log.info("[_cleanup_single_vessel] Vessel " + str(vessel) +
                     " no longer needs cleanup: " + reasonwhynot)
            return

        nodeid = maindb.get_node_identifier_from_vessel(vessel)
        nodehandle = _get_node_handle_from_nodeid(nodeid)

        try:
            log.info(
                "[_cleanup_single_vessel] About to ChangeUsers on vessel " +
                str(vessel))
            nodemanager.change_users(nodehandle, vessel.name, [''])
            log.info(
                "[_cleanup_single_vessel] About to ResetVessel on vessel " +
                str(vessel))
            nodemanager.reset_vessel(nodehandle, vessel.name)
        except NodemanagerCommunicationError:
            # We don't pass this exception up. Maybe the node is offline now. At some
            # point, it will be marked in the database as offline (should we be doing
            # that here?). At that time, the dirty vessels on that node will not be
            # in the cleanup list anymore.
            log.info("[_cleanup_single_vessel] Failed to cleanup vessel " +
                     str(vessel) + ". " + traceback.format_exc())
            return

        # We only mark it as clean if no exception was raised when trying to
        # perform the above nodemanager operations.
        maindb.mark_vessel_as_clean(vessel)

        log.info("[_cleanup_single_vessel] Successfully cleaned up vessel " +
                 str(vessel))

    finally:
        # Unlock the node.
        lockserver.unlock_node(lockserver_handle, node_id)
        lockserver.destroy_lockserver_handle(lockserver_handle)