def send_command_to_pilot(self, cmd, arg=None, pilot_manager_id=None, pilot_ids=None): """ Send a command to one or more pilots. """ if self._s is None: raise Exception("No active session.") if pilot_manager_id is None and pilot_ids is None: raise Exception("Either Pilot Manager or Pilot needs to be specified.") if pilot_manager_id is not None and pilot_ids is not None: raise Exception("Pilot Manager and Pilot can not be both specified.") command = {COMMAND_FIELD: {COMMAND_TYPE: cmd, COMMAND_ARG: arg, COMMAND_TIME: timestamp() }} if pilot_ids is None: # send command to all pilots that are known to the # pilot manager. self._p.update( {"pilotmanager": pilot_manager_id}, {"$push": command}, multi=True ) else: if not isinstance(pilot_ids, list): pilot_ids = [pilot_ids] # send command to selected pilots if pilot_ids are # specified convert ids to object ids for pid in pilot_ids: self._p.update( {"_id": pid}, {"$push": command} )
def update_pilot_state(self, pilot_uid, started=None, finished=None, submitted=None, state=None, sagajobid=None, pilot_sandbox=None, global_sandbox=None, logs=None): """Updates the information of a pilot. """ if self._s is None: raise Exception("No active session.") # construct the update query set_query = dict() push_query = dict() if state : set_query["state"] = state push_query["statehistory"] = [{'state': state, 'timestamp': timestamp()}] if logs : push_query["log"] = logs if started : set_query["started"] = started if finished : set_query["finished"] = finished if submitted : set_query["submitted"] = submitted if sagajobid : set_query["sagajobid"] = sagajobid if pilot_sandbox : set_query["sandbox"] = pilot_sandbox if global_sandbox : set_query["global_sandbox"] = global_sandbox # update pilot entry. self._p.update( {"_id": pilot_uid}, {"$set": set_query, "$pushAll": push_query}, multi=True )
def close(self): """ close the session """ if self._s is None: raise RuntimeError("No active session.") self._closed = timestamp()
def insert_compute_units(self, umgr_uid, units, unit_log): """ Adds one or more compute units to the database and sets their state to 'PENDING'. """ if self._s is None: raise RuntimeError("No active session.") # Make sure we work on a list. if not isinstance(units, list): units = [units] unit_docs = list() results = dict() for unit in units: ts = timestamp() unit_json = { "_id": unit.uid, "description": unit.description.as_dict(), "restartable": unit.description.restartable, "unitmanager": umgr_uid, "pilot": None, "pilot_sandbox": None, "state": unit._local_state, "statehistory": [{ "state": unit._local_state, "timestamp": ts }], "submitted": ts, "started": None, "finished": None, "exec_locs": None, "exit_code": None, "sandbox": None, "stdout": None, "stderr": None, "log": unit_log, "FTW_Input_Status": None, "FTW_Input_Directives": None, "Agent_Input_Status": None, "Agent_Input_Directives": None, "FTW_Output_Status": None, "FTW_Output_Directives": None, "Agent_Output_Status": None, "Agent_Output_Directives": None } unit_docs.append(unit_json) results[unit.uid] = unit_json unit_uids = self._w.insert(unit_docs) assert len(unit_docs) == len(unit_uids) assert len(results) == len(unit_uids) return results
def insert_compute_units(self, umgr_uid, units, unit_log): """ Adds one or more compute units to the database and sets their state to 'PENDING'. """ if self._s is None: raise RuntimeError("No active session.") # Make sure we work on a list. if not isinstance(units, list): units = [units] unit_docs = list() results = dict() for unit in units: ts = timestamp() unit_json = { "_id": unit.uid, "description": unit.description.as_dict(), "restartable": unit.description.restartable, "unitmanager": umgr_uid, "pilot": None, "pilot_sandbox": None, "state": unit._local_state, "statehistory": [{"state": unit._local_state, "timestamp": ts}], "submitted": ts, "started": None, "finished": None, "exec_locs": None, "exit_code": None, "sandbox": None, "stdout": None, "stderr": None, "log": unit_log, "FTW_Input_Status": None, "FTW_Input_Directives": None, "Agent_Input_Status": None, "Agent_Input_Directives": None, "FTW_Output_Status": None, "FTW_Output_Directives": None, "Agent_Output_Status": None, "Agent_Output_Directives": None } unit_docs.append(unit_json) results[unit.uid] = unit_json unit_uids = self._w.insert(unit_docs) assert len(unit_docs) == len(unit_uids) assert len(results) == len(unit_uids) return results
def __init__(self, sid, name, dburl): """ Creates a new session A session is a distinct collection with three sub-collections in MongoDB: radical.pilot.<sid> | Base collection. Holds some metadata. | self._s radical.pilot.<sid>.cu | Collection holding all compute units. | self._w radical.pilot.<sid>.um | Collection holding all unit managers. | self._um radical.pilot.<sid>.p | Collection holding all pilots. | self._p radical.pilot.<sid>.pm | Collection holding all pilot managers. | self._pm All collections are created with a new session. Since MongoDB uses lazy-create, they only appear in the database after the first insert. That's ok. """ # mpongodb_connect wants a string at the moment mongo, db, _, _, _ = ru.mongodb_connect(str(dburl)) if not mongo or not db: raise RuntimeError("Could not connect to database at %s" % dburl) self._client = mongo self._db = db self._dburl = ru.Url(dburl) self._session_id = sid self._created = timestamp() self._connected = self._created self._closed = None # make sure session doesn't exist already if self._db[sid].count() != 0: raise RuntimeError("Session '%s' already exists." % sid) # create the db entry self._s = self._db["%s" % sid] self._s.insert({ "_id": sid, "name": name, "created": self._created, "connected": self._created }) # Create the collection shortcut: self._w = self._db["%s.cu" % sid] self._um = self._db["%s.um" % sid] self._p = self._db["%s.p" % sid] self._pm = self._db["%s.pm" % sid]
def __init__(self, sid, name, dburl): """ Creates a new session A session is a distinct collection with three sub-collections in MongoDB: radical.pilot.<sid> | Base collection. Holds some metadata. | self._s radical.pilot.<sid>.cu | Collection holding all compute units. | self._w radical.pilot.<sid>.um | Collection holding all unit managers. | self._um radical.pilot.<sid>.p | Collection holding all pilots. | self._p radical.pilot.<sid>.pm | Collection holding all pilot managers. | self._pm All collections are created with a new session. Since MongoDB uses lazy-create, they only appear in the database after the first insert. That's ok. """ # mpongodb_connect wants a string at the moment mongo, db, _, _, _ = ru.mongodb_connect(str(dburl)) if not mongo or not db: raise RuntimeError("Could not connect to database at %s" % dburl) self._client = mongo self._db = db self._dburl = ru.Url(dburl) self._session_id = sid self._created = timestamp() self._connected = self._created self._closed = None # make sure session doesn't exist already if self._db[sid].count() != 0: raise RuntimeError("Session '%s' already exists." % sid) # create the db entry self._s = self._db["%s" % sid] self._s.insert({"_id" : sid, "name" : name, "created" : self._created, "connected" : self._created}) # Create the collection shortcut: self._w = self._db["%s.cu" % sid] self._um = self._db["%s.um" % sid] self._p = self._db["%s.p" % sid] self._pm = self._db["%s.pm" % sid]
def insert_pilot(self, pilot_uid, pilot_manager_uid, pilot_description, pilot_sandbox, global_sandbox): """Adds a new pilot document to the database. """ if self._s is None: raise Exception("No active session.") ts = timestamp() # the SAGA attribute interface does not expose private attribs in # as_dict(). That semantics may change in the future, for now we copy # private elems directly. pd_dict = dict() for k in pilot_description._attributes_i_list(priv=True): pd_dict[k] = pilot_description[k] pilot_doc = { "_id": pilot_uid, "description": pd_dict, "submitted": ts, "input_transfer_started": None, "input_transfer_finished": None, "started": None, "finished": None, "heartbeat": None, "output_transfer_started": None, "output_transfer_finished": None, "nodes": None, "cores_per_node": None, "sagajobid": None, "sandbox": pilot_sandbox, "global_sandbox": global_sandbox, "state": PENDING_LAUNCH, "statehistory": [{ "state": PENDING_LAUNCH, "timestamp": ts }], "log": [], "pilotmanager": pilot_manager_uid, "unitmanager": None, "commands": [] } self._p.insert(pilot_doc) return str(pilot_uid), pilot_doc
def insert_pilot(self, pilot_uid, pilot_manager_uid, pilot_description, pilot_sandbox, global_sandbox): """Adds a new pilot document to the database. """ if self._s is None: raise Exception("No active session.") ts = timestamp() # the SAGA attribute interface does not expose private attribs in # as_dict(). That semantics may change in the future, for now we copy # private elems directly. pd_dict = dict() for k in pilot_description._attributes_i_list (priv=True): pd_dict[k] = pilot_description[k] pilot_doc = { "_id": pilot_uid, "description": pd_dict, "submitted": ts, "input_transfer_started": None, "input_transfer_finished": None, "started": None, "finished": None, "heartbeat": None, "output_transfer_started": None, "output_transfer_finished": None, "nodes": None, "cores_per_node": None, "sagajobid": None, "sandbox": pilot_sandbox, "global_sandbox": global_sandbox, "state": PENDING_LAUNCH, "statehistory": [{"state": PENDING_LAUNCH, "timestamp": ts}], "log": [], "pilotmanager": pilot_manager_uid, "unitmanager": None, "commands": [] } self._p.insert(pilot_doc) return str(pilot_uid), pilot_doc
def update_pilot_state(self, pilot_uid, started=None, finished=None, submitted=None, state=None, sagajobid=None, pilot_sandbox=None, global_sandbox=None, logs=None): """Updates the information of a pilot. """ if self._s is None: raise Exception("No active session.") # construct the update query set_query = dict() push_query = dict() if state: set_query["state"] = state push_query["statehistory"] = [{ 'state': state, 'timestamp': timestamp() }] if logs: push_query["log"] = logs if started: set_query["started"] = started if finished: set_query["finished"] = finished if submitted: set_query["submitted"] = submitted if sagajobid: set_query["sagajobid"] = sagajobid if pilot_sandbox: set_query["sandbox"] = pilot_sandbox if global_sandbox: set_query["global_sandbox"] = global_sandbox # update pilot entry. self._p.update({"_id": pilot_uid}, { "$set": set_query, "$pushAll": push_query }, multi=True)
def send_command_to_pilot(self, cmd, arg=None, pilot_manager_id=None, pilot_ids=None): """ Send a command to one or more pilots. """ if self._s is None: raise Exception("No active session.") if pilot_manager_id is None and pilot_ids is None: raise Exception( "Either Pilot Manager or Pilot needs to be specified.") if pilot_manager_id is not None and pilot_ids is not None: raise Exception( "Pilot Manager and Pilot can not be both specified.") command = { COMMAND_FIELD: { COMMAND_TYPE: cmd, COMMAND_ARG: arg, COMMAND_TIME: timestamp() } } if pilot_ids is None: # send command to all pilots that are known to the # pilot manager. self._p.update({"pilotmanager": pilot_manager_id}, {"$push": command}, multi=True) else: if not isinstance(pilot_ids, list): pilot_ids = [pilot_ids] # send command to selected pilots if pilot_ids are # specified convert ids to object ids for pid in pilot_ids: self._p.update({"_id": pid}, {"$push": command})
def set_compute_unit_state(self, unit_ids, state, log, src_states=None): """ Update the state and the log of one or more ComputeUnit(s). If src_states is given, this will only update units which are currently in those src states. """ ts = timestamp() if not unit_ids: return if self._s is None: raise Exception("No active session.") # Make sure we work on a list. if not isinstance(unit_ids, list): unit_ids = [unit_ids] if src_states and not isinstance(src_states, list): src_states = [src_states] bulk = self._w.initialize_ordered_bulk_op() for uid in unit_ids: if src_states: bulk.find ({"_id" : uid, "state" : {"$in" : src_states} }) \ .update ({"$set" : {"state": state}, "$push" : {"statehistory": {"state": state, "timestamp": ts}}, "$push" : {"log" : {"message": log, "timestamp": ts}}}) else: bulk.find ({"_id" : uid}) \ .update ({"$set" : {"state": state}, "$push" : {"statehistory": {"state": state, "timestamp": ts}}, "$push" : {"log" : {"message": log, "timestamp": ts}}}) result = bulk.execute()
def set_compute_unit_state(self, unit_ids, state, log, src_states=None): """ Update the state and the log of one or more ComputeUnit(s). If src_states is given, this will only update units which are currently in those src states. """ ts = timestamp() if not unit_ids : return if self._s is None: raise Exception("No active session.") # Make sure we work on a list. if not isinstance(unit_ids, list): unit_ids = [unit_ids] if src_states and not isinstance (src_states, list) : src_states = [src_states] bulk = self._w.initialize_ordered_bulk_op () for uid in unit_ids : if src_states : bulk.find ({"_id" : uid, "state" : {"$in" : src_states} }) \ .update ({"$set" : {"state": state}, "$push" : {"statehistory": {"state": state, "timestamp": ts}}, "$push" : {"log" : {"message": log, "timestamp": ts}}}) else : bulk.find ({"_id" : uid}) \ .update ({"$set" : {"state": state}, "$push" : {"statehistory": {"state": state, "timestamp": ts}}, "$push" : {"log" : {"message": log, "timestamp": ts}}}) result = bulk.execute()