Exemple #1
0
        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)