docker.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import os, io, sys, platform, shutil, time, json, datetime
  2. import re,docker,requests
  3. from api.utils import shell_execute
  4. import psutil as p
  5. from dotenv import load_dotenv, find_dotenv
  6. import dotenv
  7. from pathlib import Path
  8. from api.utils.common_log import myLogger
  9. def pull_images(app_name):
  10. # 备用方法
  11. # 为了防止安装前,用户服务器已经有了镜像。导致安装时镜像不重新拉取,镜像是老的(根据docker-compose.yml 和 .env 获取)
  12. myLogger.info_logger("Pull images complete ...")
  13. def delete_images(app_id):
  14. # 备用方法
  15. # 卸载APP时同时删除dockercompose里面对应的镜像(根据docker-compose.yml 和 .env 获取)
  16. myLogger.info_logger("Delete images complete ...")
  17. def get_process_perc(app_name, real_name):
  18. process_now = "step1"
  19. if if_app_exits(app_name):
  20. process_now = "step2"
  21. process_now = "step3"
  22. return process_now
  23. def if_app_exits(app_name):
  24. cmd = "docker compose ls -a | grep \'"+app_name+"\\b\'"
  25. output = shell_execute.execute_command_output_all(cmd)
  26. if int(output["code"]) == -1:
  27. return False
  28. else:
  29. return True
  30. def check_vm_resource(app_name):
  31. myLogger.info_logger("Checking virtual memory resource ...")
  32. cpu_count = p.cpu_count()
  33. mem = p.virtual_memory()
  34. mem_total = float(mem.total) / 1024 / 1024 / 1024
  35. requirements_var = read_var(app_name, 'requirements')
  36. need_cpu_count = int(requirements_var['cpu'])
  37. need_mem = int(requirements_var['memory'])
  38. if cpu_count<need_cpu_count or mem_total<need_mem:
  39. return False
  40. mem_free = float(mem.available) / 1024 / 1024 / 1024
  41. if mem_total>=8 and mem_free<=4:
  42. return False
  43. need_disk = int(requirements_var['disk'])
  44. disk = p.disk_usage('/')
  45. disk_total = float(disk.total) / 1024 / 1024 / 1024
  46. disk_free = float(disk.free) / 1024 / 1024 / 1024
  47. if disk_total<need_disk or disk_free<2:
  48. return False
  49. return True
  50. def check_app_directory(app_name):
  51. # websoft9's support applist
  52. myLogger.info_logger("Checking dir...")
  53. path = "/data/library/apps/"+app_name
  54. is_exists = check_directory(path)
  55. return is_exists
  56. def check_directory(path):
  57. output = shell_execute.execute_command_output_all("ls " + path)
  58. if int(output["code"]) == 0:
  59. return True
  60. else:
  61. return False
  62. def check_app_compose(app_name):
  63. myLogger.info_logger("Checking port...")
  64. path = "/data/apps/" + app_name + "/.env"
  65. port_dic = read_env(path, "APP_.*_PORT")
  66. #1.判断/data/apps/app_name/.env中的port是否占用,没有被占用,方法结束(get_start_port方法)
  67. for port_name in port_dic:
  68. port_value = get_start_port(port_dic[port_name])
  69. modify_env(path, port_name, port_value)
  70. myLogger.info_logger("Port check complete")
  71. return
  72. def check_app_url(customer_app_name):
  73. myLogger.info_logger("Checking app url...")
  74. # 如果app的.env文件中含有HTTP_URL项目,需要如此设置 HTTP_URL=ip:port
  75. env_path = "/data/apps/" + customer_app_name + "/.env"
  76. if read_env(env_path, "HTTP_URL") != {}:
  77. ip = shell_execute.execute_command_output_all("curl ifconfig.me")["result"]
  78. http_port = list(read_env(path, "APP_HTTP_PORT").values())[0]
  79. url = ip + ":" + http_port
  80. modify_env(path, "HTTP_URL", url)
  81. myLogger.info_logger("App url check complete")
  82. return
  83. def read_env(path, key):
  84. myLogger.info_logger("Read " + path)
  85. output = shell_execute.execute_command_output_all("cat " + path + "|grep "+ key)
  86. code = output["code"]
  87. env_dic = {}
  88. if int(code) == 0 and output["result"] != "":
  89. ret = output["result"]
  90. env_list = ret.split()
  91. for env in env_list:
  92. env_dic[env.split("=")[0]] = env.split("=")[1]
  93. myLogger.info_logger("Read " + path + ": " + str(env_dic))
  94. return env_dic
  95. def modify_env(path, env_name, value):
  96. myLogger.info_logger("Modify " + path + "...")
  97. file_data = ""
  98. with open(path, "r", encoding="utf-8") as f:
  99. for line in f:
  100. if re.match(env_name, line) != None:
  101. env_name = line.split("=")[0]
  102. line = line.replace(line, env_name + "=" + value+"\n")
  103. file_data += line
  104. with open(path, "w", encoding="utf-8") as f:
  105. myLogger.info_logger("Modify " + path + ": Change " + env_name + " to " + value)
  106. f.write(file_data)
  107. def read_var(app_name, var_name):
  108. value = "-"
  109. var_path = "/data/apps/" + app_name + "/variables.json"
  110. myLogger.info_logger("Read " + var_path)
  111. try:
  112. f = open(var_path, 'r', encoding='utf-8')
  113. var = json.load(f)
  114. try:
  115. value = var[var_name]
  116. except KeyError:
  117. myLogger.warning_logger("Read " + var_path + ": No key " + var_name)
  118. except FileNotFoundError:
  119. myLogger.warning_logger(var_path + " not found")
  120. return value
  121. def get_start_port(port):
  122. use_port = port
  123. while True:
  124. cmd = "netstat -ntlp | grep -v only"
  125. output = shell_execute.execute_command_output_all(cmd)
  126. if output["result"].find(use_port)==-1:
  127. break
  128. else:
  129. use_port = str(int(use_port)+1)
  130. return use_port