[Supervisor-checkins] r781 - supervisor/branches/foreground/src/supervisor

Siddhant Goel siddhantgoel at gmail.com
Mon Jul 21 15:28:14 EDT 2008


Author: Siddhant Goel <siddhantgoel at gmail.com>
Date: Mon Jul 21 15:28:13 2008
New Revision: 781

Log:
foreground initial code

Modified:
   supervisor/branches/foreground/src/supervisor/supervisorctl.py

Modified: supervisor/branches/foreground/src/supervisor/supervisorctl.py
==============================================================================
--- supervisor/branches/foreground/src/supervisor/supervisorctl.py	(original)
+++ supervisor/branches/foreground/src/supervisor/supervisorctl.py	Mon Jul 21 15:28:13 2008
@@ -42,6 +42,8 @@
 import asyncore
 import errno
 import urlparse
+import curses
+
 
 from supervisor.options import ClientOptions
 from supervisor.options import split_namespec
@@ -720,6 +722,144 @@
             "version\t\t\tShow the version of the remote supervisord "
             "process")
 
+    def _foreground(self,program,supervisor):
+        # initialise curses
+        stdscr=curses.initscr()
+        stdscr.scrollok(True)
+	stdscr.keypad(1)
+	# put a curses.mousemask(curses.ALL_MOUSE_EVENTS)
+        # whenever handling mouse events becomes clearer
+        stdscr.move(0,0)
+        stdscr.addstr('Entered foreground mode for process %s'%program)
+        # print out any initial output/error messages
+        if self.outputs[-1]:
+            stdscr.addstr(self.outputs[-1])
+        if self.errors[-1]:
+            stdscr.addstr(self.errors[-1])
+        stdscr.refresh()
+        try:
+            while True:
+                # check whether the window should be scrolled
+                # scrolling down is perfect, scrolling up needs to be checked
+                # a mouse event should scroll the window up
+                maxy,maxx = stdscr.getmaxyx()
+                y,x = stdscr.getyx()
+                if y == maxy:
+                    stdscr.scroll()
+                curses.noecho()
+                # set a timer on getch, so that
+                # it stops blocking after 0.5 seconds
+                curses.halfdelay(5)
+                a=stdscr.getch()
+                curses.nocbreak() # quit halfdelay mode
+                # a=curses.ERR when user does not press a key within 0.5s
+                if not a == curses.ERR:
+                    # user pressed a key
+                    # take inputs, send it to supervisor
+                    # receive outputs, and display the output (if necessary)
+                    curses.echo()
+		    # add the mouse event handling code (for scrolling) later on
+                    # stdscr.addstr('\n\rEnter the input string\n\r')  (never mind this one)
+                    stdscr.refresh()
+                    inp=stdscr.getstr() 
+                    # inp=r'%s'%inp
+                    supervisor.sendProcessStdin(program,inp)
+                    output=supervisor.tailProcessStdoutLog(program,0,1600)[0]
+                    error=supervisor.tailProcessStderrLog(program,0,1600)[0]
+                    if output:
+                        stdscr.addstr(output)
+                        self.outputs.append(output)
+                    if error:
+                        stdscr.addstr(error)
+                        self.errors.append(error)
+                    stdscr.refresh()
+                    supervisor.clearProcessLogs(program)
+                else:
+                    # user didn't press a key, so check for any
+                    # updates on output/error messages from the process
+                    output=supervisor.tailProcessStdoutLog(program,0,1600)[0]
+                    error=supervisor.tailProcessStderrLog(program,0,1600)[0]
+                    if output:
+                        stdscr.addstr(output)
+                        self.outputs.append(output)
+                    if error:
+                        stdscr.addstr(error)
+                        self.errors.append(error)
+                    stdscr.refresh()
+                    supervisor.clearProcessLogs(program)
+                if supervisor.getProcessInfo(program)['pid'] == 0:
+                    stdscr.addstr('Process got killed\n')
+                    stdscr.addstr('Exiting foreground\n')
+                    stdscr.addstr('Press any key to exit\n')
+                    stdscr.getch()
+                    break
+        except KeyboardInterrupt:
+            stdscr.addstr('Exiting foreground\n')
+            stdscr.addstr('Press any key to exit\n')
+            curses.nocbreak()
+            stdscr.getch()
+            curses.echo()
+	    stdscr.keypad(0)
+            curses.endwin()
+            del stdscr
+            return
+        except:
+            stdscr.addstr('An error occured\n')
+            stdscr.addstr('Exiting foreground\n')
+            stdscr.addstr('Press any key to exit\n')
+            stdscr.getch()
+            curses.echo()
+	    stdscr.keypad(0)
+            curses.endwin()
+            del stdscr
+            return
+        curses.echo()
+        curses.nocbreak()
+	stdscr.keypad(0)
+        curses.endwin()
+        del stdscr
+        return
+
+    def do_fg(self, args=None):
+        if not self.ctl.upcheck():
+            return
+        if not args:
+            self.help_fg()
+            return
+        args=args.strip().split()
+        if len(args)>1:
+            self.ctl.output('ERROR: Multiple process names entered\n')
+            self.help_fg()
+            return
+        # check whether the process name is sane
+        program=args[0]
+        supervisor=self.ctl.get_supervisor()
+        try:
+            info=supervisor.getProcessInfo(program)
+        except xmlrpclib.Fault, msg:
+            if msg.faultString == 'BAD_NAME: %s' % program:
+                self.ctl.output('ERROR -- Bad process name supplied')
+            else:
+                self.ctl.output('ERROR -- %s' % msg)
+            return
+        if info['pid'] == 0:
+            self.ctl.output('ERROR -- Process not running')
+            return
+        # everything good, continue
+        self.outputs=[supervisor.tailProcessStdoutLog(program,0,1600)[0]]
+        self.errors=[supervisor.tailProcessStderrLog(program,0,1600)[0]]
+        supervisor.clearProcessLogs(program)
+        self._foreground(program,supervisor)
+        
+    def help_fg(self,args=None):
+        self.ctl.output('fg <process_name> : Connect to a process in foreground mode')
+        self.ctl.output('While in foreground mode, press any key to start entering')
+        self.ctl.output('the input string for the process.')
+        self.ctl.output('Press any key within 0.5 seconds to enter an input')
+        self.ctl.output('After which, the process would be checked for any')
+        self.ctl.output('output/error messages available')
+        self.ctl.output('Press Ctrl+C to exit foreground')
+
 def main(args=None, options=None):
     if options is None:
         options = ClientOptions()


More information about the Supervisor-checkins mailing list