pmanager.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env python3
  2. import json
  3. import os
  4. import signal
  5. import socket
  6. import subprocess
  7. import sys
  8. import time
  9. import websocket
  10. DEBUG = False
  11. DEBUG = True
  12. def log(s):
  13. if not DEBUG:
  14. return
  15. print(s)
  16. def sendmsg(msg):
  17. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  18. ret = None
  19. try:
  20. s.connect(('localhost', 9999))
  21. tosend = msg + "\r\n"
  22. encoded_msg = tosend.encode("ascii")
  23. s.sendall(encoded_msg)
  24. ret = s.recv(4096)
  25. s.close()
  26. except Exception as e:
  27. log(e)
  28. return None
  29. log("[nc output] %s " % ret)
  30. return ret
  31. class PManager:
  32. ws = websocket.WebSocket()
  33. ip = "ws://192.168.1.208:9001"
  34. p_list = {}
  35. ptable = {}
  36. log_list = {}
  37. def __init__(self, ptable):
  38. self.ptable = ptable
  39. self.conn(self.ip)
  40. signal.signal(signal.SIGINT, self.sighandler)
  41. signal.signal(signal.SIGCHLD, signal.SIG_IGN) #To kill zombies
  42. while True:
  43. try:
  44. data = self.ws.recv()
  45. except Exception as e:
  46. log(e)
  47. self.conn(self.ip)
  48. continue
  49. try:
  50. j = json.loads(data)
  51. except Exception as e:
  52. log(e)
  53. log("Invalid json?")
  54. continue
  55. if ("type" not in j or "command" not in j or
  56. "key" not in j or j["type"] != "snowmix"):
  57. log("Dropping: %s" % j)
  58. continue
  59. log(j)
  60. if j["command"] == "launch":
  61. opts = None
  62. if "options" in j:
  63. opts = j["options"]
  64. self.launch(j["key"],opts)
  65. if j["command"] == "kill":
  66. self.stop(j["key"])
  67. if j["command"] == "netcat":
  68. sendmsg(j["key"])
  69. def conn(self, target):
  70. if self.ws is None:
  71. self.ws = websocket.WebSocket()
  72. try:
  73. self.ws.connect(target)
  74. except Exception as e:
  75. log(e)
  76. time.sleep(2)
  77. self.conn(target) #keep trying you basterd
  78. def close(self):
  79. if self.ws is None:
  80. return
  81. self.ws.close()
  82. def sighandler(self, sig, frame):
  83. log("\rExiting!")
  84. self.close()
  85. log("Bye!")
  86. sys.exit(0)
  87. def stop(self, key):
  88. if key not in self.p_list:
  89. log("key %s doesn't exist! not killing!" % (key))
  90. return
  91. try:
  92. os.killpg(os.getpgid(self.p_list[key].pid), signal.SIGTERM)
  93. except Exception as e:
  94. log("This process (%d) can't be killed! Why?" % self.p_list[key].pid)
  95. log(e)
  96. try:
  97. self.log_list[key].close()
  98. except Exception as e:
  99. log("ex file: %s" % e)
  100. if key in self.log_list:
  101. del self.log_list[key]
  102. del self.p_list[key]
  103. def launch(self, key, options=None):
  104. if key in self.p_list:
  105. log("key %s exist! not running!" % (key))
  106. return
  107. if key not in self.ptable:
  108. log("This process (%s) is not on my table!" % key)
  109. return
  110. log("Launching! key: %s, opts: %s" % (key, options))
  111. tolaunch = self.ptable[key]
  112. if options is not None:
  113. tolaunch = tolaunch + options
  114. log(tolaunch)
  115. self.log_list[key] = open("/tmp/%s" % key, "w")
  116. try:
  117. proc = subprocess.Popen(tolaunch, preexec_fn=os.setsid, stdout=self.log_list[key])
  118. #Le doy su propio grupo al subproceso
  119. except Exception as e:
  120. log(e)
  121. sys.exit(1)
  122. self.p_list[key] = proc
  123. return proc.pid
  124. if __name__ == "__main__":
  125. if len(sys.argv) != 2:
  126. print("Usage: ./%s <file.json>" % (sys.argv[0]))
  127. sys.exit(1)
  128. try:
  129. ptable = json.loads(open(sys.argv[1]).read())
  130. except Exception as e:
  131. print(e)
  132. sys.exit(2)
  133. print(ptable)
  134. m = PManager(ptable)