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 test_get_queryset_vessel_acquired_by_user_changes(self): """ This is ultimately testing maindb._get_queryset_of_all_available_vessels_for_a_port_include_nat_nodes() """ # Create a user who will be doing the acquiring. user = maindb.create_user("testuser", "password", "*****@*****.**", "affiliation", "1 2", "2 2 2", "3 4") userport = user.usable_vessel_port # Create two nodes that have three vessels but only one vessel on the user's port. portlist = [userport - 1, userport, userport + 1] ip = "127.0.0.1" create_node_and_vessels_with_one_port_each(ip, portlist) ip = "127.0.0.2" create_node_and_vessels_with_one_port_each(ip, portlist) # We expect two available vessels. queryset = _get_queryset_include_nat(userport) self.assertEqual(2, queryset.count()) # Mark one of the vessels as acquired. vessel = queryset[0] maindb.record_acquired_vessel(user, vessel) # We expect one available vessel, and it shouldn't be the acquired one. queryset = _get_queryset_include_nat(userport) self.assertEqual(1, queryset.count()) self.assertNotEqual(vessel, queryset[0]) # Release the vessel. It should still be dirty. maindb.record_released_vessel(vessel) # We expect one available vessel, and it shouldn't be the acquired one. queryset = _get_queryset_include_nat(userport) self.assertEqual(1, queryset.count()) self.assertNotEqual(vessel, queryset[0]) # Mark the vessel as clean (as if the backend cleaned it up). maindb.mark_vessel_as_clean(vessel) # We expect two available vessels. queryset = _get_queryset_include_nat(userport) self.assertEqual(2, queryset.count())
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)