Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # coding:utf-8
- import sys
- import os
- import re
- import time
- import socket
- import subprocess
- import threading
- import logging
- import xmlrpclib
- import SimpleXMLRPCServer
- import ConfigParser
- USE_PYTHONW = 'C:\\Python27\\pythonw.exe'
- SUPERVISORD_CONF = './supervisord.conf'
- DEFAULT_PORT = 9001
- CURRENT_WATCHDOGS = []
- logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(asctime)s %(message)s')
- class WatchDog(threading.Thread):
- """a windows process watch dog"""
- TICK_SECONDS = 1
- START_SECONDS = 5
- def __init__(self, name, commandline):
- threading.Thread.__init__(self)
- self.setName(name)
- self._commanline = commandline
- self._birthtime = None
- self._stoped = False
- self._pipe = None
- def run(self):
- close_fds = False if sys.platform == 'win32' else True
- self._pipe = subprocess.Popen(self._commanline, shell=False, close_fds=close_fds)
- self._birthtime = time.time()
- while True:
- try:
- time.sleep(self.TICK_SECONDS)
- if self._stoped:
- self._pipe.terminate()
- self._pipe = None
- return True
- else:
- if self._pipe.poll() is not None:
- if time.time() - self._birthtime < self.START_SECONDS:
- logging.error('WatchDog(%r) start failed', self.getName())
- self._stoped = True
- self._pipe = None
- return False
- else:
- logging.error('WatchDog(%r) aborted, try restart', self.getName())
- self._pipe = subprocess.Popen(self._commanline, shell=False, close_fds=close_fds)
- self._birthtime = time.time()
- else:
- logging.debug('WatchDog(%r) is alive', self.getName())
- except Exception as e:
- logging.exception('WatchDog.run error: %r', e)
- def start(self):
- threading.Thread.start(self)
- return True
- def stop(self):
- self._stoped = True
- timeout = self.START_SECONDS
- while timeout > 0:
- if self._pipe is None:
- return True
- else:
- time.sleep(self.TICK_SECONDS)
- timeout -= self.TICK_SECONDS
- return False
- def check_daemon(timeout=1):
- try:
- socket.create_connection(('127.0.0.1', DEFAULT_PORT), timeout=timeout).close()
- return True
- except socket.error:
- return False
- def read_service(filename):
- assert os.path.isfile(filename)
- config = ConfigParser.ConfigParser()
- config.read(filename)
- services = {}
- for section in config.sections():
- if section.startswith('program:') and config.has_option(section, 'command'):
- name = section[8:].strip()
- command = config.get(section, 'command').strip()
- if USE_PYTHONW and command.startswith('python'):
- command = ' '.join([USE_PYTHONW] + command.split()[1:])
- services[name] = command
- return services
- def clear_stoped_watchdog():
- global CURRENT_WATCHDOGS
- CURRENT_WATCHDOGS = [x for x in CURRENT_WATCHDOGS if not x._stoped and x._pipe]
- def do_start(name, commandline):
- clear_stoped_watchdog()
- for watchdog in CURRENT_WATCHDOGS:
- if watchdog.getName() == name:
- msg = 'WatchDog(%r) already started' % name
- logging.error(msg)
- return msg
- watchdog = WatchDog(name, commandline)
- watchdog.start()
- CURRENT_WATCHDOGS.append(watchdog)
- msg = 'WatchDog(%r) started' % watchdog.getName()
- logging.info(msg)
- return msg
- def do_stop(name, commandline):
- assert name and commandline
- clear_stoped_watchdog()
- for watchdog in CURRENT_WATCHDOGS:
- if watchdog.getName() == name:
- logging.info('try stoping WatchDog(%r)', name)
- result = watchdog.stop()
- clear_stoped_watchdog()
- if result:
- return 'Stop WatchDog(%r) OK' % watchdog.getName()
- else:
- return 'Stop WatchDog(%r) Error' % watchdog.getName()
- return 'Stop WatchDog(%r) existed, Stop OK' % name
- def do_restart(name, commandline):
- msg = do_stop(name, commandline)
- if 'ok' in msg.lower():
- return do_start(name, commandline)
- else:
- return msg
- def do_list(name, commandline):
- assert name and commandline
- clear_stoped_watchdog()
- return os.linesep.join('%s PID:%s' % (x.getName(), x._pipe.pid) for x in CURRENT_WATCHDOGS)
- def supervisord():
- server = SimpleXMLRPCServer.SimpleXMLRPCServer(('', DEFAULT_PORT), logRequests=True)
- server.register_function(do_start)
- server.register_function(do_stop)
- server.register_function(do_restart)
- server.register_function(do_list)
- server.serve_forever()
- def supervisorctl():
- argstr = ' '.join(sys.argv[1:])
- m = re.search('--service=(\w+)', argstr)
- service = m.group(1) if m else 'node_agent'
- m = re.search('-c\s+(\w+)', argstr)
- action = m.group(1) if m else ''
- filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), SUPERVISORD_CONF)
- conf_services = read_service(filename)
- services = conf_services.keys() if service == 'all' else [service]
- for service in services:
- if service not in conf_services:
- logging.error('cannot found service=%r in %r', service, filename)
- proxy = xmlrpclib.ServerProxy('http://localhost:%d' % DEFAULT_PORT)
- if action == 'start':
- print(proxy.do_start(service, conf_services[service]))
- elif action == 'stop':
- print(proxy.do_stop(service, conf_services[service]))
- elif action == 'restart':
- print(proxy.do_restart(service, conf_services[service]))
- else:
- print(proxy.do_list(service, conf_services[service]))
- def main():
- if '--daemon' in sys.argv[1:]:
- supervisord()
- sys.exit(0)
- if not check_daemon():
- if USE_PYTHONW:
- close_fds = False if sys.platform == 'win32' else True
- cmd = '%s "%s" --daemon' % (USE_PYTHONW, os.path.abspath(__file__))
- subprocess.Popen(cmd, close_fds=close_fds)
- else:
- cmd = 'start "%s" "%s" --daemon' % (sys.executable, os.path.abspath(__file__))
- os.system(cmd)
- supervisorctl()
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement