docker.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import os, io, sys, platform, shutil, time, json, datetime, psutil
  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_free = float(psutil.virtual_memory().available) / 1024 / 1024 / 1024
  87. if mem_free < need_mem_total * 1.2:
  88. myLogger.info_logger("Check complete: The total amount of memory is insufficient!")
  89. return False
  90. need_disk = int(requirements_var['disk'])
  91. disk_free = float(psutil.disk_usage('/').free) / 1024 / 1024 / 1024
  92. if round(disk_free) < need_disk + 2:
  93. myLogger.info_logger("Check complete: There are not enough disks left!")
  94. return False
  95. myLogger.info_logger("Check complete.")
  96. return True
  97. def check_app_websoft9(app_name):
  98. # websoft9's support applist
  99. myLogger.info_logger("Checking dir...")
  100. path = "/data/library/apps/" + app_name
  101. is_exists = check_directory(path)
  102. return is_exists
  103. def check_directory(path):
  104. try:
  105. shell_execute.execute_command_output_all("ls " + path)
  106. return True
  107. except CommandException as ce:
  108. return False
  109. def check_app_compose(app_name, customer_name):
  110. myLogger.info_logger("Checking port...")
  111. library_path = "/data/library/apps/" + app_name
  112. install_path = "/data/apps/" + customer_name
  113. port_dic = read_env(library_path + '/.env', "APP_.*_PORT")
  114. # 1.判断/data/apps/app_name/.env中的port是否占用,没有被占用,方法结束(get_start_port方法)
  115. cmd1 = "docker container inspect $(docker ps -aq) | grep HostPort | awk \'{print $2}\' | sort -u"
  116. cmd2 = "netstat -tunlp | grep \"LISTEN\" | awk '{print $4}' | awk -F \":\" '{print $NF}' | sort -u"
  117. cmd3 = "grep -r \"APP_.*_PORT=\" /data/apps/*/.env | awk -F \"=\" '{print $2}' | sort -u"
  118. s1 = shell_execute.execute_command_output_all(cmd1)['result'].replace('\"', '')
  119. s2 = shell_execute.execute_command_output_all(cmd2)['result']
  120. try:
  121. s3 = ''
  122. s3 = shell_execute.execute_command_output_all(cmd3)['result']
  123. except:
  124. pass
  125. s = s1 + '\n' + s2 + '\n' + s3
  126. shell_execute.execute_command_output_all("cp -r " + library_path + " " + install_path)
  127. for port_name in port_dic:
  128. port_value = get_start_port(s, port_dic[port_name])
  129. modify_env(install_path + '/.env', port_name, port_value)
  130. myLogger.info_logger("Port check complete")
  131. return
  132. def check_app_url(customer_app_name):
  133. myLogger.info_logger("Checking app url...")
  134. # 如果app的.env文件中含有HTTP_URL项目,需要如此设置 HTTP_URL=ip:port
  135. env_path = "/data/apps/" + customer_app_name + "/.env"
  136. if read_env(env_path, "HTTP_URL") != {}:
  137. ip = "localhost"
  138. try:
  139. ip_result = shell_execute.execute_command_output_all("cat /data/apps/stackhub/docker/w9appmanage/public_ip")
  140. ip = ip_result["result"].rstrip('\n')
  141. except Exception:
  142. ip = "127.0.0.1"
  143. http_port = list(read_env(path, "APP_HTTP_PORT").values())[0]
  144. url = ip + ":" + http_port
  145. modify_env(path, "HTTP_URL", url)
  146. myLogger.info_logger("App url check complete")
  147. return
  148. def read_env(path, key):
  149. myLogger.info_logger("Read " + path)
  150. output = shell_execute.execute_command_output_all("cat " + path)
  151. code = output["code"]
  152. env_dic = {}
  153. if int(code) == 0:
  154. ret = output["result"]
  155. env_list = ret.split("\n")
  156. for env in env_list:
  157. if re.match(key, env) != None:
  158. env_dic[env.split("=")[0]] = env.split("=")[1]
  159. myLogger.info_logger("Read " + path + ": " + str(env_dic))
  160. return env_dic
  161. def modify_env(path, env_name, value):
  162. myLogger.info_logger("Modify " + path + "...")
  163. output = shell_execute.execute_command_output_all("sed -n \'/^" + env_name + "/=\' " + path)
  164. if int(output["code"]) == 0 and output["result"] != "":
  165. line_num = output["result"].split("\n")[0]
  166. s = env_name + "=" + value
  167. output = shell_execute.execute_command_output_all("sed -i \'" + line_num + "c " + s + "\' " + path)
  168. if int(output["code"]) == 0:
  169. myLogger.info_logger("Modify " + path + ": Change " + env_name + " to " + value)
  170. def read_var(var_path, var_name):
  171. value = ""
  172. myLogger.info_logger("Read " + var_path)
  173. output = shell_execute.execute_command_output_all("cat " + var_path)
  174. if int(output["code"]) == 0:
  175. var = json.loads(output["result"])
  176. try:
  177. value = var[var_name]
  178. except KeyError:
  179. myLogger.warning_logger("Read " + var_path + ": No key " + var_name)
  180. else:
  181. myLogger.warning_logger(var_path + " not found")
  182. return value
  183. def get_start_port(s, port):
  184. use_port = port
  185. while True:
  186. if s.find(use_port) == -1:
  187. break
  188. else:
  189. use_port = str(int(use_port) + 1)
  190. return use_port