docker.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import os, io, sys, platform, shutil, time, json, datetime
  2. import re, docker, requests
  3. from api.utils import shell_execute
  4. from dotenv import load_dotenv, find_dotenv
  5. import dotenv
  6. from pathlib import Path
  7. from api.utils.common_log import myLogger
  8. from api.utils import shell_execute, const
  9. from api.exception.command_exception import CommandException
  10. from api.service import manage
  11. # 已经是running的app怎么知道它已经能够访问,如页面能进入,如mysql能被客户端连接
  12. def if_app_access(app_name):
  13. return True
  14. def if_app_exits(app_name):
  15. cmd = "docker compose ls -a"
  16. output = shell_execute.execute_command_output_all(cmd)
  17. if int(output["code"]) == 0:
  18. pattern = app_name + '$'
  19. info_list = output['result'].split()
  20. is_exist = False
  21. for info in info_list:
  22. if re.match(pattern, info) != None:
  23. is_exist = True
  24. break
  25. return is_exist
  26. else:
  27. return True
  28. def if_app_running(app_name):
  29. cmd = "docker compose ls -a"
  30. output = shell_execute.execute_command_output_all(cmd)
  31. if int(output["code"]) == 0:
  32. app_list = output['result'].split("\n")
  33. pattern = app_name + '\s*'
  34. if_running = False
  35. for app in app_list:
  36. if re.match(pattern, app) != None and re.match('running', app) != None:
  37. if_running = True
  38. break
  39. return if_running
  40. else:
  41. return False
  42. def check_appid_exist(app_id):
  43. myLogger.info_logger("Checking check_appid_exist ...")
  44. appList = manage.get_my_app()
  45. find = False
  46. for app in appList:
  47. if app_id == app.app_id:
  48. find = True
  49. break
  50. myLogger.info_logger("Check complete.")
  51. return find
  52. def check_appid_include_rq(app_id):
  53. message = ""
  54. code = None
  55. if app_id == None:
  56. code = const.ERROR_CLIENT_PARAM_BLANK
  57. message = "AppID is null"
  58. elif re.match('^[a-z0-9]+_[a-z0-9]+$', app_id) == None:
  59. code = const.ERROR_CLIENT_PARAM_Format
  60. message = "APP name can only be composed of numbers and lowercase letters"
  61. elif not check_appid_exist(app_id):
  62. code = const.ERROR_CLIENT_PARAM_NOTEXIST
  63. message = "AppID is not exist"
  64. return code, message
  65. def check_app_id(app_id):
  66. message = ""
  67. code = None
  68. if app_id == None:
  69. code = const.ERROR_CLIENT_PARAM_BLANK
  70. message = "AppID is null"
  71. elif re.match('^[a-z0-9]+_[a-z0-9]+$', app_id) == None:
  72. code = const.ERROR_CLIENT_PARAM_Format
  73. message = "APP name can only be composed of numbers and lowercase letters"
  74. myLogger.info_logger(code)
  75. return code, message
  76. def check_vm_resource(app_name):
  77. myLogger.info_logger("Checking virtual memory resource ...")
  78. var_path = "/data/library/apps/" + app_name + "/variables.json"
  79. requirements_var = read_var(var_path, 'requirements')
  80. need_cpu_count = int(requirements_var['cpu'])
  81. cpu_count = int(shell_execute.execute_command_output_all("cat /proc/cpuinfo | grep \'core id\'| wc -l")["result"])
  82. if cpu_count < need_cpu_count:
  83. myLogger.info_logger("Check complete: The number of CPU cores is insufficient!")
  84. return False
  85. need_mem_total = int(requirements_var['memory'])
  86. mem = shell_execute.execute_command_output_all("free -m | grep Mem")["result"].split()
  87. mem_total = float(mem[1]) / 1024
  88. if round(mem_total) < need_mem_total:
  89. myLogger.info_logger("Check complete: The total amount of memory is insufficient!")
  90. return False
  91. mem_free = float(mem[3]) / 1024
  92. if need_mem_total > 4 and round(mem_free) < 4:
  93. myLogger.info_logger("Check complete: There is not enough memory left!")
  94. return False
  95. need_disk = int(requirements_var['disk'])
  96. disk_free = float(
  97. shell_execute.execute_command_output_all("df -m --output=avail /")["result"].split("\n")[1]) / 1024
  98. if round(disk_free) < need_disk - 17:
  99. myLogger.info_logger("Check complete: There are not enough disks left!")
  100. return False
  101. myLogger.info_logger("Check complete.")
  102. return True
  103. def check_app_websoft9(app_name):
  104. # websoft9's support applist
  105. myLogger.info_logger("Checking dir...")
  106. path = "/data/library/apps/" + app_name
  107. is_exists = check_directory(path)
  108. return is_exists
  109. def check_directory(path):
  110. try:
  111. shell_execute.execute_command_output_all("ls " + path)
  112. return True
  113. except CommandException as ce:
  114. return False
  115. def check_app_compose(app_name, customer_name):
  116. myLogger.info_logger("Checking port...")
  117. library_path = "/data/library/apps/" + app_name
  118. install_path = "/data/apps/" + customer_name
  119. port_dic = read_env(library_path + '/.env', "APP_.*_PORT")
  120. # 1.判断/data/apps/app_name/.env中的port是否占用,没有被占用,方法结束(get_start_port方法)
  121. cmd1 = "docker container inspect $(docker ps -aq) | grep HostPort | awk \'{print $2}\' | sort -u"
  122. cmd2 = "netstat -tunlp | grep \"LISTEN\" | awk '{print $4}' | awk -F \":\" '{print $NF}' | sort -u"
  123. cmd3 = "grep -r \"APP_.*_PORT=\" /data/apps/*/.env | awk -F \"=\" '{print $2}' | sort -u"
  124. s1 = shell_execute.execute_command_output_all(cmd1)['result'].replace('\"', '')
  125. s2 = shell_execute.execute_command_output_all(cmd2)['result']
  126. try:
  127. s3 = ''
  128. s3 = shell_execute.execute_command_output_all(cmd3)['result']
  129. except:
  130. pass
  131. s = s1 + '\n' + s2 + '\n' + s3
  132. shell_execute.execute_command_output_all("cp -r " + library_path + " " + install_path)
  133. for port_name in port_dic:
  134. port_value = get_start_port(s, port_dic[port_name])
  135. modify_env(install_path + '/.env', port_name, port_value)
  136. myLogger.info_logger("Port check complete")
  137. return
  138. def check_app_url(customer_app_name):
  139. myLogger.info_logger("Checking app url...")
  140. # 如果app的.env文件中含有HTTP_URL项目,需要如此设置 HTTP_URL=ip:port
  141. env_path = "/data/apps/" + customer_app_name + "/.env"
  142. if read_env(env_path, "HTTP_URL") != {}:
  143. ip = shell_execute.execute_command_output_all("curl ifconfig.me")["result"]
  144. http_port = list(read_env(path, "APP_HTTP_PORT").values())[0]
  145. url = ip + ":" + http_port
  146. modify_env(path, "HTTP_URL", url)
  147. myLogger.info_logger("App url check complete")
  148. return
  149. def read_env(path, key):
  150. myLogger.info_logger("Read " + path)
  151. output = shell_execute.execute_command_output_all("cat " + path)
  152. code = output["code"]
  153. env_dic = {}
  154. if int(code) == 0:
  155. ret = output["result"]
  156. env_list = ret.split("\n")
  157. for env in env_list:
  158. if re.match(key, env) != None:
  159. env_dic[env.split("=")[0]] = env.split("=")[1]
  160. myLogger.info_logger("Read " + path + ": " + str(env_dic))
  161. return env_dic
  162. def modify_env(path, env_name, value):
  163. myLogger.info_logger("Modify " + path + "...")
  164. output = shell_execute.execute_command_output_all("sed -n \'/^" + env_name + "/=\' " + path)
  165. if int(output["code"]) == 0 and output["result"] != "":
  166. line_num = output["result"].split("\n")[0]
  167. s = env_name + "=" + value
  168. output = shell_execute.execute_command_output_all("sed -i \'" + line_num + "c " + s + "\' " + path)
  169. if int(output["code"]) == 0:
  170. myLogger.info_logger("Modify " + path + ": Change " + env_name + " to " + value)
  171. def read_var(var_path, var_name):
  172. value = ""
  173. myLogger.info_logger("Read " + var_path)
  174. output = shell_execute.execute_command_output_all("cat " + var_path)
  175. if int(output["code"]) == 0:
  176. var = json.loads(output["result"])
  177. try:
  178. value = var[var_name]
  179. except KeyError:
  180. myLogger.warning_logger("Read " + var_path + ": No key " + var_name)
  181. else:
  182. myLogger.warning_logger(var_path + " not found")
  183. return value
  184. def get_start_port(s, port):
  185. use_port = port
  186. while True:
  187. if s.find(use_port) == -1:
  188. break
  189. else:
  190. use_port = str(int(use_port) + 1)
  191. return use_port