def job(self, *args): LOG.info('Recv:: JOB for session %s', self.session_id) try: remote_user, request = json.loads(args[0]) except ValueError: LOG.error('Malformed request received: %s' % args[0]) return command = request['script'] env = request['env'] proc = Processor(remote_user) lang = parser.parse_lang(command) LOG.info("Node[%s]::: User:::[%s] UUID:::[%s] LANG:::[%s]" % (CONFIG.node_id, remote_user, self.session_id, lang)) if isinstance(command, unicode): command = command.encode('utf8') incl_header = [] libs = request.get('libs', []) if libs: for lib in libs: # Save libs if any script = proc.add_libs(**lib) if script: # inline if isinstance(script, unicode): script = script.encode('utf8') incl_header.append(script) # For long-running jobs # self.socket.send_multipart([self.session_id, # StatusCodes.WORKING, # json.dumps(dict(stdout=value))]) proc_iter = iter(proc.run(command, lang, env, inlines=incl_header)) proc = next(proc_iter) def _encode(data): try: return json.dumps(data) except: return "" if not isinstance(proc, list): proc.set_input_fd(self.queue) running = True while running: to_read = proc.select(.2) if proc.poll() is not None: # We are done with the task LOG.info("Job %s finished" % self.session_id) running = False # Do not break, let consume the streams for fd_type in to_read: if fd_type == proc.TRANSPORT: try: frames = self.queue.recv(0) except: continue if frames and len(frames) == 2: if frames[0] == 'INPUT': try: proc.write(frames[1]) except: continue elif frames[0] == 'TERM': if len(frames) > 1 and frames[1] == 'kill': # kill task proc.kill() LOG.info("Job %s killed" % self.session_id) else: # terminate task proc.terminate() LOG.info("Job %s terminated" % self.session_id) continue if fd_type == proc.STDOUT: data = proc.read_out() if data: enc_data = _encode(dict(stdout=data)) if enc_data: self._yield_reply( StatusCodes.STDOUT, proc.run_as, enc_data) if fd_type == proc.STDERR: data = proc.read_err() if data: enc_data = _encode(dict(stderr=data)) if enc_data: self._yield_reply( StatusCodes.STDERR, proc.run_as, enc_data) run_as, ret_code, stdout, stderr, env = next(proc_iter) else: # Error invoking Popen, get params run_as, ret_code, stdout, stderr, env = proc if stdout: self._yield_reply(StatusCodes.STDOUT, run_as, json.dumps(dict(stdout=stdout))) if stderr: self._yield_reply(StatusCodes.STDERR, run_as, json.dumps(dict(stderr=stderr))) job_result = json.dumps(dict(env=env, ret_code=ret_code, stdout=stdout, stderr=stderr)) LOG.info('Job [%s] DONE' % (self.session_id)) self._yield_reply(StatusCodes.FINISHED, run_as, job_result) self._close() # Invoke clean if os.name == 'nt': import win32api import win32con win32api.GenerateConsoleCtrlEvent(win32con.CTRL_C_EVENT, 0) else: os.kill(os.getpid(), signal.SIGHUP)