Advertisement
codemonkey

daemonManager.py

Nov 4th, 2011
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.42 KB | None | 0 0
  1. # =======
  2. # Imports
  3. # =======
  4.  
  5. import sys, os
  6. import jtvStreamsUpdater
  7. import pprint
  8. import subprocess
  9.  
  10. # =======
  11. # Globals
  12. # =======
  13.  
  14. PIDPATH = '/var/run'
  15. PYPATH = sys.executable
  16.  
  17. RUNNING = 1
  18. STARTED = 2
  19. ALREADY_RUNNING = 3
  20. NOT_RUNNING = 4
  21. KILLED = 5
  22.  
  23. # ==========
  24. # Exceptions
  25. # ==========
  26.  
  27. class AlreadyStartedError(Exception):
  28.     def __init__(self, pid):
  29.         self.pid = pid
  30.  
  31. class NotRunningError(Exception):
  32.     pass
  33.  
  34. # ===============
  35. # Configure paths
  36. # ===============
  37.  
  38. # Get the absolute path of this folder
  39. FILEROOT = os.path.abspath(os.path.dirname(__file__))
  40.  
  41. # Set working directory to this
  42. os.chdir(FILEROOT)
  43.  
  44. # ==========================
  45. # Process handling functions
  46. # ==========================
  47.  
  48. def startProcess(name, path):
  49.     """
  50.    Starts a process in the background and writes a PID file
  51.    
  52.    returns integer: pid
  53.    """
  54.    
  55.     # Check if the process is already running
  56.     status, pid = processStatus(name)
  57.    
  58.     if status == RUNNING:
  59.         raise AlreadyStartedError(pid)
  60.    
  61.     # Start process
  62.     command = (path).split(' ')
  63.     process = subprocess.Popen(command, stdout='/dev/null', stderr='/dev/null')
  64.    
  65.     # Write PID file
  66.     pidfilename = os.path.join(PIDPATH, name + '.pid')
  67.     pidfile = open(pidfilename, 'w')
  68.     pidfile.write(str(process.pid))
  69.     pidfile.close()
  70.    
  71.     return process.pid
  72.  
  73. def stopProcess(name):
  74.     """
  75.    Stops a process started by startProcess
  76.    
  77.    returns integer: RESULT
  78.    """
  79.    
  80.     # Get the status of the input process
  81.     status, pid = processStatus(name)
  82.  
  83.     # If it's not running, return    
  84.     if status == NOT_RUNNING:
  85.         return NOT_RUNNING
  86.    
  87.     # If it's running, kill it and remove the PID file
  88.     os.system('kill %s > /dev/null 2> /dev/null' % pid)
  89.     os.system('rm ' + os.path.join(PIDPATH, name + '.pid'))
  90.     return KILLED
  91.    
  92. def processStatus(name):
  93.     """
  94.    Gets the status of a process started by startProcess
  95.    
  96.    returns tuple: ([RUNNING | NOT_RUNNING], pid)
  97.    """
  98.    
  99.     pidfilename = os.path.join(PIDPATH, name + '.pid')
  100.    
  101.     # Try to open the PID file. If successfull, the process is running
  102.     try:
  103.         pidfile = open(pidfilename, 'r')
  104.         pid = pidfile.read()
  105.     except IOError as e:
  106.         return (NOT_RUNNING, None)
  107.    
  108.     return (RUNNING, pid)
  109.  
  110. # ===================
  111. # jtvDaemon functions
  112. # ===================
  113.  
  114. def startjtv():
  115.     """
  116.    Starts the jtvStreamsUpdater loop in a background process
  117.    
  118.    returns tuple: (RESULT, pid)
  119.    """
  120.    
  121.     # Check if process is already started
  122.     status, pid = processStatus('jtvStreamUpdater')
  123.    
  124.     if status == RUNNING:
  125.         return (ALREADY_RUNNING, pid)
  126.    
  127.     # Fork here
  128.     pid = os.fork()
  129.    
  130.     # Write and return the child pid
  131.     if pid:
  132.         # Write PID to pid file
  133.         pidfilepath = os.path.join(PIDPATH, 'jtvStreamsUpdater.pid')
  134.         pidfile = open(pidfilepath, 'w')
  135.         pidfile.write(str(pid))
  136.         pidfile.close()
  137.        
  138.         return (STARTED, pid)
  139.    
  140.     # The child process should start the update loop
  141.     else:
  142.         # Don't output anything
  143.         sys.stdout = open('/dev/null', 'w')
  144.        
  145.         from honsapp.jtvStreamsUpdater import mainUpdateLoop
  146.         mainUpdateLoop()
  147.  
  148. def stopjtv():
  149.     """
  150.    Stops the jtvStreamsUpdater loop
  151.    
  152.    returns int: RESULT
  153.    """
  154.    
  155.     # Try to kill the process
  156.     return stopProcess('jtvStreamsUpdater')
  157.  
  158. # ================
  159. # Script execution
  160. # ================
  161.  
  162. if __name__ == '__main__':
  163.     import argparse
  164.    
  165.     commands = ['startall', 'stopall',
  166.                 'startjtv', 'stopjtv', 'jtvstatus']
  167.    
  168.     help = """commands:
  169.  startall    Starts all refreshing daemons
  170.  stopall     Stops them
  171.  
  172.  startjtv    Starts the justin.tv streams refresher
  173.  stopjtv     Stops it
  174.  jtvstatus   Shows it's current status"""
  175.    
  176.     parser = argparse.ArgumentParser(epilog=help,
  177.                            formatter_class=argparse.RawDescriptionHelpFormatter)
  178.    
  179.     # Add the main positional argument; command
  180.     parser.add_argument('command', metavar='command', type=str,
  181.                         choices=commands, help='The command to give the script')
  182.    
  183.     # Get the parser arguments
  184.     args = parser.parse_args()
  185.    
  186.     # Abide the input command
  187.     if args.command == 'startall':
  188.         startallDaemons()
  189.    
  190.     elif args.command == 'stopall':
  191.         stopallDaemons()
  192.    
  193.     elif args.command == 'startjtv':
  194.         # Try to start the daemon
  195.         result, pid = startjtv()
  196.        
  197.         if result == STARTED:
  198.             print 'jtvStreamsUpdater started at ' + str(pid)
  199.         elif result == ALREADY_RUNNING:
  200.             print 'jtvStreamsUpdater already running at ' + str(pid)
  201.    
  202.     elif args.command == 'stopjtv':
  203.         # Try to stop the daemon
  204.         result = stopjtv()
  205.        
  206.         if result == KILLED:
  207.             print 'jtvStreamsUpdater has been stopped'
  208.         elif result == NOT_RUNNING:
  209.             print 'jtvStreamsUpdater isn\'t running'
  210.    
  211.     elif args.command == 'jtvstatus':
  212.         # Fetch the daemon status
  213.         result, pid = processStatus('jtvStreamsUpdater')
  214.        
  215.         if result == RUNNING:
  216.             print 'jtvStreamsUpdater is running at %s' % pid
  217.         elif result == NOT_RUNNING:
  218.             print 'jtvStreamsUpdater isn\'t running'
  219.  
  220.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement