def run(self): env.config.update(self.config) # start a socket? context = zmq.Context() stdout_socket = context.socket(zmq.PUSH) stdout_socket.connect(self.config["sockets"]["tapping_logging"]) informer_socket = context.socket(zmq.PUSH) informer_socket.connect(self.config["sockets"]["tapping_listener"]) try: filename = tempfile.NamedTemporaryFile(prefix='.tmp_script_', dir=os.getcwd(), suffix='.sos', delete=False).name with open(filename, 'w') as script_file: script_file.write(self.code) cmd = ['sos', 'run', filename] + shlex.split(self.args) + [ '-m', 'tapping', 'slave', self.config["slave_id"], self.config["sockets"]["tapping_logging"], self.config["sockets"]["tapping_listener"], self.config["sockets"]["tapping_controller"] ] ret_code = pexpect_run(subprocess.list2cmdline(cmd), shell=True, stdout_socket=stdout_socket) # status will not trigger frontend update if it was not # started with a pending status informer_socket.send_pyobj({ 'msg_type': 'workflow_status', 'data': { 'cell_id': env.config['slave_id'], 'status': 'completed' if ret_code == 0 else 'failed' } }) sys.exit(ret_code) except Exception as e: stdout_socket.send_multipart([b'ERROR', str(e).encode()]) informer_socket.send_pyobj({ 'msg_type': 'workflow_status', 'data': { 'cell_id': env.config['slave_id'], 'status': 'failed', 'exception': str(e) } }) sys.exit(1) finally: try: os.remove(filename) except Exception as e: env.logger.warning( f'Failed to remove temp script {filename}: {e}') stdout_socket.LINGER = 0 stdout_socket.close() informer_socket.LINGER = 0 informer_socket.close() context.term()
def run(self): env.config.update(self.config) # start a socket? context = zmq.Context() stdout_socket = context.socket(zmq.PUSH) stdout_socket.connect( (f'tcp://127.0.0.1:{self.config["sockets"]["tapping_logging"]}')) informer_socket = context.socket(zmq.PUSH) informer_socket.connect( (f'tcp://127.0.0.1:{self.config["sockets"]["tapping_listener"]}')) try: filename = os.path.join(tempfile.gettempdir(), f'interactive_{os.getpid()}.sos') with open(filename, 'w') as script_file: script_file.write(self.code) cmd = f'sos run {filename} {self.args} -m tapping slave {self.config["slave_id"]} {self.config["sockets"]["tapping_logging"]} {self.config["sockets"]["tapping_listener"]} {self.config["sockets"]["tapping_controller"]}' ret_code = pexpect_run(cmd, shell=True, stdout_socket=stdout_socket) # status will not trigger frontend update if it was not # started with a pending status informer_socket.send_pyobj({ 'msg_type': 'workflow_status', 'data': { 'cell_id': env.config['slave_id'], 'status': 'completed' if ret_code == 0 else 'failed' } }) except Exception as e: stdout_socket.send_multipart([b'ERROR', str(e).encode()]) informer_socket.send_pyobj({ 'msg_type': 'workflow_status', 'data': { 'cell_id': env.config['slave_id'], 'status': 'failed', 'exception': str(e) } }) finally: stdout_socket.LINGER = 0 stdout_socket.close() informer_socket.LINGER = 0 informer_socket.close() context.term()
def _run_cmd(self, cmd, **kwargs): if env.config['run_mode'] == 'interactive': if 'stdout' in kwargs or 'stderr' in kwargs: child = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0) out, err = child.communicate() if 'stdout' in kwargs: if kwargs['stdout'] is not False: with open(kwargs['stdout'], 'ab') as so: so.write(out) else: sys.stdout.write(out.decode()) if 'stderr' in kwargs: if kwargs['stderr'] is not False: with open(kwargs['stderr'], 'ab') as se: se.write(err) else: sys.stderr.write(err.decode()) ret = child.returncode else: # need to catch output and send to python output, which will in trun be hijacked by SoS notebook ret = pexpect_run(cmd) elif '__std_out__' in env.sos_dict and '__std_err__' in env.sos_dict: if 'stdout' in kwargs or 'stderr' in kwargs: if 'stdout' in kwargs: if kwargs['stdout'] is False: so = subprocess.DEVNULL else: so = open(kwargs['stdout'], 'ab') elif env.verbosity > 0: so = open(env.sos_dict['__std_out__'], 'ab') else: so = subprocess.DEVNULL if 'stderr' in kwargs: if kwargs['stderr'] is False: se = subprocess.DEVNULL else: se = open(kwargs['stderr'], 'ab') elif env.verbosity > 1: se = open(env.sos_dict['__std_err__'], 'ab') else: se = subprocess.DEVNULL p = subprocess.Popen(cmd, shell=True, stderr=se, stdout=so) ret = p.wait() if so != subprocess.DEVNULL: so.close() if se != subprocess.DEVNULL: se.close() elif env.verbosity >= 1: with open(env.sos_dict['__std_out__'], 'ab') as so, open(env.sos_dict['__std_err__'], 'ab') as se: p = subprocess.Popen(cmd, shell=True, stderr=se, stdout=so) ret = p.wait() else: p = subprocess.Popen( cmd, shell=True, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) ret = p.wait() else: if 'stdout' in kwargs: if kwargs['stdout'] is False: so = subprocess.DEVNULL else: so = open(kwargs['stdout'], 'ab') elif env.verbosity > 0: so = None else: so = subprocess.DEVNULL if 'stderr' in kwargs: if kwargs['stderr'] is False: se = subprocess.DEVNULL else: se = open(kwargs['stderr'], 'ab') elif env.verbosity > 1: se = None else: se = subprocess.DEVNULL p = subprocess.Popen(cmd, shell=True, stderr=se, stdout=so) ret = p.wait() if so is not None and so != subprocess.DEVNULL: so.close() if se is not None and se != subprocess.DEVNULL: se.close() return ret