[Supervisor-checkins] r782 - supervisor/branches/foreground/src/supervisor
Siddhant Goel
siddhantgoel at gmail.com
Wed Jul 23 12:56:59 EDT 2008
Author: Siddhant Goel <siddhantgoel at gmail.com>
Date: Wed Jul 23 12:56:58 2008
New Revision: 782
Log:
replaced curses with signal
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 Wed Jul 23 12:56:58 2008
@@ -42,13 +42,18 @@
import asyncore
import errno
import urlparse
-import curses
-
+import signal
+import time
+import tty
+import termios
from supervisor.options import ClientOptions
from supervisor.options import split_namespec
from supervisor import xmlrpc
+def alarm_handler(*args):
+ raise Exception
+
class Controller(cmd.Cmd):
def __init__(self, options, completekey='tab', stdin=None,
@@ -722,143 +727,102 @@
"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):
+ def do_fg(self,args=None):
if not self.ctl.upcheck():
return
if not args:
self.help_fg()
return
- args=args.strip().split()
+ args=args.split()
if len(args)>1:
- self.ctl.output('ERROR: Multiple process names entered\n')
- self.help_fg()
+ self.ctl.output('ERROR : too many process names supplied')
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)
+ self.ctl.output('Bad process name supplied')
+ return
+ # for any other fault,
+ self.ctl.output(str(msg))
return
if info['pid'] == 0:
- self.ctl.output('ERROR -- Process not running')
+ self.ctl.output('ERROR : Process not running')
return
# everything good, continue
+ self.ctl.output('Entered foreground mode for %s ' % program)
+ self.ctl.output('Press any key to start entering the input string for the process')
self.outputs=[supervisor.tailProcessStdoutLog(program,0,1600)[0]]
self.errors=[supervisor.tailProcessStderrLog(program,0,1600)[0]]
supervisor.clearProcessLogs(program)
- self._foreground(program,supervisor)
-
+ if self.outputs[-1]:
+ self.ctl.output(self.outputs[-1])
+ if self.errors[-1]:
+ self.ctl.output(self.errors[-1])
+ signal.signal(signal.SIGALRM, alarm_handler)
+ original_settings=termios.tcgetattr(sys.stdin.fileno())
+ while True:
+ try:
+ try:
+ # put the terminal in raw mode
+ tty.setraw(sys.stdin.fileno())
+ signal.alarm(1)
+ ready = sys.stdin.read(1)
+ signal.alarm(0)
+ finally:
+ # restore the terminal to its original state
+ termios.tcsetattr(sys.stdin.fileno(),termios.TCSADRAIN,original_settings)
+ if ready:
+ self.ctl.output('Enter the input string')
+ inp=sys.stdin.readline()
+ supervisor.sendProcessStdin(program,inp)
+ time.sleep(0.5)
+ # check if there is any useful output/error message
+ output=supervisor.tailProcessStdoutLog(program,0,1600)[0]
+ error=supervisor.tailProcessStderrLog(program,0,1600)[0]
+ if output:
+ self.outputs.append(output)
+ self.ctl.output(output)
+ if error:
+ self.errors.append(error)
+ self.ctl.output(error)
+ supervisor.clearProcessLogs(program)
+ if supervisor.getProcessInfo(program)['pid'] == 0:
+ self.ctl.output('Process got killed')
+ self.ctl.output('Exiting foreground')
+ return
+ continue
+ except KeyboardInterrupt:
+ signal.alarm(0)
+ self.ctl.output('Exiting foreground')
+ return
+ except:
+ signal.alarm(0)
+ if supervisor.getProcessInfo(program)['pid'] == 0:
+ self.ctl.output('Process got killed')
+ self.ctl.output('Exiting foreground')
+ return
+ output=supervisor.tailProcessStdoutLog(program,0,1600)[0]
+ error=supervisor.tailProcessStderrLog(program,0,1600)[0]
+ if output:
+ self.outputs.append(output)
+ self.ctl.output(output)
+ if error:
+ self.errors.append(error)
+ self.ctl.output(error)
+ supervisor.clearProcessLogs(program)
+ continue
+
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')
+ self.ctl.output('While in foreground, press any key to start entering the')
+ self.ctl.output('input string for the process.')
+ self.ctl.output('This input string would be sent to the process, and any')
+ self.ctl.output('interesting output/error messages will be displayed.')
+ self.ctl.output('Press Ctrl+C to exit foreground mode')
+
def main(args=None, options=None):
if options is None:
More information about the Supervisor-checkins
mailing list