Guest User

Untitled

a guest
Dec 19th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.95 KB | None | 0 0
  1. import argparse
  2. import time
  3. import logging
  4. import threading
  5. import signal
  6. import socket
  7. import subprocess
  8.  
  9. FORMAT="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
  10. logging.basicConfig(level = logging.DEBUG, format = FORMAT)
  11.  
  12. def kill_gentally(proc):
  13. proc.terminate()
  14. time.sleep(1)
  15. if proc.poll() is None:
  16. logging.info("SIGTERM not working, try again with SIGKILL")
  17. proc.kill()
  18.  
  19. class Handle:
  20.  
  21. def __init__(self, args):
  22. self.state = "INIT"
  23. self.args = args
  24. self.proc = None
  25. self.killFlag = False
  26. self.exitFlag = False
  27.  
  28. def restart(self):
  29. if self.state == 'STARTED':
  30. self.killFlag = True
  31.  
  32. def exit(self):
  33. self.exitFlag = True
  34.  
  35. def loop(self):
  36. self._start()
  37. while True:
  38. if self.exitFlag:
  39. self._kill()
  40. break
  41. elif self.proc.poll() is not None: # died
  42. self.state = "INITED"
  43. retcode = self.proc.poll()
  44. logging.info("[died] process died with code: %d", retcode)
  45. self._start()
  46. elif self.killFlag:
  47. self._kill()
  48. self._start()
  49. time.sleep(1)
  50. pass
  51.  
  52. def _kill(self):
  53. if self.state != 'STARTED':
  54. logging.warn("_kill is called in state: %s", self.state)
  55. return
  56. self.state = "KILLING"
  57. if self.proc.poll() is None:
  58. kill_gentally(self.proc)
  59. retcode = self.proc.wait()
  60. logging.info("[killed] process died with code: %d", retcode)
  61. self.state = "INIT"
  62.  
  63. def _start(self):
  64. self.killFlag = False
  65. self.state = "STARTING"
  66. logging.info("starting ssh...")
  67. self.proc = subprocess.Popen(['ssh'] + self.args)
  68. self.state = "STARTED"
  69.  
  70. def start_ssh_loop_in_thread(sshargs):
  71. handle = Handle(sshargs)
  72. thread = threading.Thread(target=handle.loop)
  73. #thread.setDaemon(True)
  74. thread.start()
  75. handle.join = thread.join
  76. return handle
  77.  
  78. def check_monitor(port):
  79. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  80. try:
  81. sock.connect(('127.0.0.1', port))
  82. sock.close()
  83. return True
  84. except:
  85. return False
  86.  
  87. def main(opts):
  88. handle = start_ssh_loop_in_thread(opts.sshargs)
  89. flags = {'exit': False}
  90. def exit_gracefully(signum, frame):
  91. handle.exit()
  92. flags['exit'] = True
  93.  
  94. signal.signal(signal.SIGINT, exit_gracefully)
  95. signal.signal(signal.SIGTERM, exit_gracefully)
  96. print opts.sshargs, opts.monitor
  97. while flags['exit'] == False:
  98. if not check_monitor(opts.monitor):
  99. logging.error("check monitor failed")
  100. handle.restart()
  101. time.sleep(10)
  102. handle.join()
  103. logging.info("fully exited!")
  104.  
  105. if __name__ == '__main__':
  106. parser = argparse.ArgumentParser()
  107. parser.add_argument("monitor", type=int)
  108. #parser.add_argument('-', action='store_true')
  109. #parser.add_argument('--daemon', action = 'store_true')
  110. #parser.add_argument('--pidfile', default=os.path.join(_my_dir_, _my_file_ + ".pid"))
  111. #parser.add_argument('--logfile', default = os.path.join(_my_dir_, _my_file_ + ".log"))
  112. parser.add_argument('sshargs', nargs=argparse.REMAINDER)
  113. main(parser.parse_args())
Add Comment
Please, Sign In to add comment