def execute_task(id): session = Session() task = session.query(Task).get(id) logger.debug("Processing task with ID: {}", id) task_uid = task.task_id task_module = importlib.import_module("chronos.tasks.{}".format(task_uid)) task_id_dict = {"task_id": id} logger.debug("Starting task with ID: {}", id) task.time_started = datetime.datetime.now() task.status = "STARTED" session.commit() event.trigger("task_started", task_id_dict) arguments = {**json.loads(task.task_arguments), **task_id_dict} task.output = task_module.run(json.dumps(arguments), event) event.trigger("task_finished", task_id_dict) task.time_finished = datetime.datetime.now() task.status = "FINISHED" session.commit() logger.debug("Finished task with ID: {}", id) session.close() return
def run(arguments, event): arguments = json.loads(arguments) name = arguments["name"] session = Session() """Create a new script by creating a virtualenv, creating .sh scripts and registering metadata.""" if name is "": # Generate random UID if no name is given uid = generate_uid() else: # Convert name to UID by "sluggifying" it (e.g. "Simon's script" -> "simons-script") uid = for_uid(name) # Check that the scripts folder exists (important for first-time users) if not os.path.isdir(CHRONOS + os.path.sep + "scripts"): os.mkdir(CHRONOS + os.path.sep + "scripts") # Find script path given UID path = CHRONOS + os.path.sep + "scripts" + os.path.sep + uid # Create folder, if it doesn't already exist if not os.path.isdir(path): os.mkdir(path) else: os.rmdir(path) os.mkdir(path) # Create virtual environment create_env(uid) # Create database entry script = ScriptModel(name=name, uid=uid, enabled=True, triggers=[]) session.add(script) session.commit() # Create script and requirements.txt file script_path = path + os.path.sep + uid + ".py" requirements_path = path + os.path.sep + "requirements.txt" open(script_path, "a").close() open(requirements_path, "a").close() # Create execute script # TODO: Move this script to a folder so it can be copied instead with open(path + os.path.sep + "execute.sh", "w") as file: file.write('''#!/bin/bash cd "{}" source "{}" python -u "{}"'''.format(path, get_activate(uid), script_path)) # Create pip install # TODO: Move this script to a folder so it can be copied instead with open(path + os.path.sep + "install.sh", "w") as file: file.write('''#!/bin/bash source "{}" pip install -r "{}"'''.format(get_activate(uid), requirements_path)) event.trigger("script_created", Script(uid).to_dict()) return uid
def enable(self): session = Session() script_from_database = session.query(ScriptModel).get(self.uid) script_from_database.enabled = True session.commit() session.close() self.enabled = True event.trigger("script_updated", self.__dict__()) event.trigger("action_complete", {"action": "enable", "uid": self.uid})
def set_setting(key, value): """Update setting or create new.""" session = Session() if get_setting(key) is None: session.add(Setting(key=key, value=value)) logger.debug("Created new 'setting': {} with value: '{}'", key, value) else: session.query(Setting).get(key).value = value logger.debug("Updated 'setting': {} with value: '{}'", key, value) session.commit() session.close()
def prune_logs(self): session = Session() if session.query(Log).count() > 10: logger.debug("Pruning logs for {}".format(self.uid)) too_old = datetime.now() - timedelta(days=3) # logger.debug(too_old) logger.debug("Found {} logs to be pruned".format( session.query(Log).filter(Log.date < too_old).count())) session.query(Log).filter(Log.date < too_old).delete() session.commit() session.close()
def dispatch_task(task_id, task_arguments, task_priority="ROUTINE"): session = Session() task = Task( task_id=task_id, task_arguments=json.dumps(task_arguments), priority=task_priority, status="WAITING", ) session.add(task) session.commit() logger.debug("Dispatched task: {}", task_id) event.trigger("task_dispatched", {"task_id": task_id}) session.close() return True
def put(self, uid): """Update script.""" args = request.get_json(force=True) session = Session() try: script = chronos.script.Script(uid) model = session.query(ScriptModel).get(uid) # Update each field if it exists try: model.name = args["name"] except KeyError: pass try: model.triggers = args["triggers"] except KeyError: pass try: model.enabled = args["enabled"] except KeyError: pass try: script.write_contents(args["contents"]) except KeyError: pass try: script.write_requirements(args["requirements"]) except KeyError: pass session.commit() return "OK", 200 except KeyError: return None, 404
def run(arguments, event): arguments = json.loads(arguments) uid = arguments["uid"] script = Script(uid) session = Session() # Remove script folder shutil.rmtree(script.folder) # Remove all logs from script session.query(Log).filter(Log.script == script.uid).delete() # Delete metadata session.delete(script.db) session.commit() session.close() event.trigger("action_complete", {"action": "delete", "uid": script.uid}) event.trigger("script_deleted", {"uid": script.uid}) return uid
def run(arguments, event): arguments = json.loads(arguments) script_uid = arguments["script_uid"] task_id = arguments["task_id"] event.trigger("action_started", {"uid": script_uid, "action": "execute"}) script = Script(script_uid) process = Popen(["bash", script.execute_path], stdout=PIPE, stderr=PIPE, shell=False) exitcode = 0 process_output = "" while True: output = process.stdout.readline() process_output += output.decode("utf-8") if process.poll() is not None: break if output: event.trigger( "task_output", { "task_id": task_id, "script_uid": script_uid, "output": output.decode("utf-8"), "task": "execute", }, ) exitcode = process.poll() stdout, stderr = process.communicate() if stderr: event.trigger( "task_output", { "task_id": task_id, "script_uid": script_uid, "output": stderr.decode("utf-8"), "task": "execute", }, ) session = Session() log = Log(script=script_uid, text=process_output, error=stderr, exitcode=exitcode) session.add(log) session.commit() session.close() event.trigger( "task_output", { "task_id": task_id, "output": "", "script_uid": script.uid, "task": "execute" }, ) script = script.to_dict() # Decode bytes to string try: stderr = stderr.decode("utf-8") except AttributeError: pass try: process_output = process_output.decode("utf-8") except AttributeError: pass script["logs"].insert( 0, { "date": maya.now().rfc2822(), "stderr": stderr, "stdout": process_output, "exitcode": exitcode, }, ) event.trigger("script_executed", script) event.trigger("script_updated", script) event.trigger("action_complete", { "action": "execute", "uid": script["uid"] }) return stdout
def prune_logs(self): session = Session() session.query(Log).filter(Log.date >= timedelta(days=3)).delete() session.commit() session.close()