You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

systemd.py 9.9 KiB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. # imports - standard imports
  2. import getpass
  3. import os
  4. # imports - third partyimports
  5. import click
  6. # imports - module imports
  7. import bench
  8. from bench.app import use_rq
  9. from bench.bench import Bench
  10. from bench.config.common_site_config import (
  11. get_gunicorn_workers,
  12. update_config,
  13. get_default_max_requests,
  14. compute_max_requests_jitter,
  15. )
  16. from bench.utils import exec_cmd, which, get_bench_name
  17. def generate_systemd_config(
  18. bench_path,
  19. user=None,
  20. yes=False,
  21. stop=False,
  22. create_symlinks=False,
  23. delete_symlinks=False,
  24. ):
  25. if not user:
  26. user = getpass.getuser()
  27. config = Bench(bench_path).conf
  28. bench_dir = os.path.abspath(bench_path)
  29. bench_name = get_bench_name(bench_path)
  30. if stop:
  31. exec_cmd(
  32. f"sudo systemctl stop -- $(systemctl show -p Requires {bench_name}.target | cut -d= -f2)"
  33. )
  34. return
  35. if create_symlinks:
  36. _create_symlinks(bench_path)
  37. return
  38. if delete_symlinks:
  39. _delete_symlinks(bench_path)
  40. return
  41. number_of_workers = config.get("background_workers") or 1
  42. background_workers = []
  43. for i in range(number_of_workers):
  44. background_workers.append(
  45. get_bench_name(bench_path) + "-xhiveframework-default-worker@" + str(i + 1) + ".service"
  46. )
  47. for i in range(number_of_workers):
  48. background_workers.append(
  49. get_bench_name(bench_path) + "-xhiveframework-short-worker@" + str(i + 1) + ".service"
  50. )
  51. for i in range(number_of_workers):
  52. background_workers.append(
  53. get_bench_name(bench_path) + "-xhiveframework-long-worker@" + str(i + 1) + ".service"
  54. )
  55. web_worker_count = config.get(
  56. "gunicorn_workers", get_gunicorn_workers()["gunicorn_workers"]
  57. )
  58. max_requests = config.get(
  59. "gunicorn_max_requests", get_default_max_requests(web_worker_count)
  60. )
  61. bench_info = {
  62. "bench_dir": bench_dir,
  63. "sites_dir": os.path.join(bench_dir, "sites"),
  64. "user": user,
  65. "use_rq": use_rq(bench_path),
  66. "http_timeout": config.get("http_timeout", 120),
  67. "redis_server": which("redis-server"),
  68. "node": which("node") or which("nodejs"),
  69. "redis_cache_config": os.path.join(bench_dir, "config", "redis_cache.conf"),
  70. "redis_queue_config": os.path.join(bench_dir, "config", "redis_queue.conf"),
  71. "webserver_port": config.get("webserver_port", 8000),
  72. "gunicorn_workers": web_worker_count,
  73. "gunicorn_max_requests": max_requests,
  74. "gunicorn_max_requests_jitter": compute_max_requests_jitter(max_requests),
  75. "bench_name": get_bench_name(bench_path),
  76. "worker_target_wants": " ".join(background_workers),
  77. "bench_cmd": which("bench"),
  78. }
  79. if not yes:
  80. click.confirm(
  81. "current systemd configuration will be overwritten. Do you want to continue?",
  82. abort=True,
  83. )
  84. setup_systemd_directory(bench_path)
  85. setup_main_config(bench_info, bench_path)
  86. setup_workers_config(bench_info, bench_path)
  87. setup_web_config(bench_info, bench_path)
  88. setup_redis_config(bench_info, bench_path)
  89. update_config({"restart_systemd_on_update": False}, bench_path=bench_path)
  90. update_config({"restart_supervisor_on_update": False}, bench_path=bench_path)
  91. def setup_systemd_directory(bench_path):
  92. if not os.path.exists(os.path.join(bench_path, "config", "systemd")):
  93. os.makedirs(os.path.join(bench_path, "config", "systemd"))
  94. def setup_main_config(bench_info, bench_path):
  95. # Main config
  96. bench_template = bench.config.env().get_template("systemd/xhiveframework-bench.target")
  97. bench_config = bench_template.render(**bench_info)
  98. bench_config_path = os.path.join(
  99. bench_path, "config", "systemd", bench_info.get("bench_name") + ".target"
  100. )
  101. with open(bench_config_path, "w") as f:
  102. f.write(bench_config)
  103. def setup_workers_config(bench_info, bench_path):
  104. # Worker Group
  105. bench_workers_target_template = bench.config.env().get_template(
  106. "systemd/xhiveframework-bench-workers.target"
  107. )
  108. bench_default_worker_template = bench.config.env().get_template(
  109. "systemd/xhiveframework-bench-xhiveframework-default-worker.service"
  110. )
  111. bench_short_worker_template = bench.config.env().get_template(
  112. "systemd/xhiveframework-bench-xhiveframework-short-worker.service"
  113. )
  114. bench_long_worker_template = bench.config.env().get_template(
  115. "systemd/xhiveframework-bench-xhiveframework-long-worker.service"
  116. )
  117. bench_schedule_worker_template = bench.config.env().get_template(
  118. "systemd/xhiveframework-bench-xhiveframework-schedule.service"
  119. )
  120. bench_workers_target_config = bench_workers_target_template.render(**bench_info)
  121. bench_default_worker_config = bench_default_worker_template.render(**bench_info)
  122. bench_short_worker_config = bench_short_worker_template.render(**bench_info)
  123. bench_long_worker_config = bench_long_worker_template.render(**bench_info)
  124. bench_schedule_worker_config = bench_schedule_worker_template.render(**bench_info)
  125. bench_workers_target_config_path = os.path.join(
  126. bench_path, "config", "systemd", bench_info.get("bench_name") + "-workers.target"
  127. )
  128. bench_default_worker_config_path = os.path.join(
  129. bench_path,
  130. "config",
  131. "systemd",
  132. bench_info.get("bench_name") + "-xhiveframework-default-worker@.service",
  133. )
  134. bench_short_worker_config_path = os.path.join(
  135. bench_path,
  136. "config",
  137. "systemd",
  138. bench_info.get("bench_name") + "-xhiveframework-short-worker@.service",
  139. )
  140. bench_long_worker_config_path = os.path.join(
  141. bench_path,
  142. "config",
  143. "systemd",
  144. bench_info.get("bench_name") + "-xhiveframework-long-worker@.service",
  145. )
  146. bench_schedule_worker_config_path = os.path.join(
  147. bench_path,
  148. "config",
  149. "systemd",
  150. bench_info.get("bench_name") + "-xhiveframework-schedule.service",
  151. )
  152. with open(bench_workers_target_config_path, "w") as f:
  153. f.write(bench_workers_target_config)
  154. with open(bench_default_worker_config_path, "w") as f:
  155. f.write(bench_default_worker_config)
  156. with open(bench_short_worker_config_path, "w") as f:
  157. f.write(bench_short_worker_config)
  158. with open(bench_long_worker_config_path, "w") as f:
  159. f.write(bench_long_worker_config)
  160. with open(bench_schedule_worker_config_path, "w") as f:
  161. f.write(bench_schedule_worker_config)
  162. def setup_web_config(bench_info, bench_path):
  163. # Web Group
  164. bench_web_target_template = bench.config.env().get_template(
  165. "systemd/xhiveframework-bench-web.target"
  166. )
  167. bench_web_service_template = bench.config.env().get_template(
  168. "systemd/xhiveframework-bench-xhiveframework-web.service"
  169. )
  170. bench_node_socketio_template = bench.config.env().get_template(
  171. "systemd/xhiveframework-bench-node-socketio.service"
  172. )
  173. bench_web_target_config = bench_web_target_template.render(**bench_info)
  174. bench_web_service_config = bench_web_service_template.render(**bench_info)
  175. bench_node_socketio_config = bench_node_socketio_template.render(**bench_info)
  176. bench_web_target_config_path = os.path.join(
  177. bench_path, "config", "systemd", bench_info.get("bench_name") + "-web.target"
  178. )
  179. bench_web_service_config_path = os.path.join(
  180. bench_path, "config", "systemd", bench_info.get("bench_name") + "-xhiveframework-web.service"
  181. )
  182. bench_node_socketio_config_path = os.path.join(
  183. bench_path,
  184. "config",
  185. "systemd",
  186. bench_info.get("bench_name") + "-node-socketio.service",
  187. )
  188. with open(bench_web_target_config_path, "w") as f:
  189. f.write(bench_web_target_config)
  190. with open(bench_web_service_config_path, "w") as f:
  191. f.write(bench_web_service_config)
  192. with open(bench_node_socketio_config_path, "w") as f:
  193. f.write(bench_node_socketio_config)
  194. def setup_redis_config(bench_info, bench_path):
  195. # Redis Group
  196. bench_redis_target_template = bench.config.env().get_template(
  197. "systemd/xhiveframework-bench-redis.target"
  198. )
  199. bench_redis_cache_template = bench.config.env().get_template(
  200. "systemd/xhiveframework-bench-redis-cache.service"
  201. )
  202. bench_redis_queue_template = bench.config.env().get_template(
  203. "systemd/xhiveframework-bench-redis-queue.service"
  204. )
  205. bench_redis_target_config = bench_redis_target_template.render(**bench_info)
  206. bench_redis_cache_config = bench_redis_cache_template.render(**bench_info)
  207. bench_redis_queue_config = bench_redis_queue_template.render(**bench_info)
  208. bench_redis_target_config_path = os.path.join(
  209. bench_path, "config", "systemd", bench_info.get("bench_name") + "-redis.target"
  210. )
  211. bench_redis_cache_config_path = os.path.join(
  212. bench_path, "config", "systemd", bench_info.get("bench_name") + "-redis-cache.service"
  213. )
  214. bench_redis_queue_config_path = os.path.join(
  215. bench_path, "config", "systemd", bench_info.get("bench_name") + "-redis-queue.service"
  216. )
  217. with open(bench_redis_target_config_path, "w") as f:
  218. f.write(bench_redis_target_config)
  219. with open(bench_redis_cache_config_path, "w") as f:
  220. f.write(bench_redis_cache_config)
  221. with open(bench_redis_queue_config_path, "w") as f:
  222. f.write(bench_redis_queue_config)
  223. def _create_symlinks(bench_path):
  224. bench_dir = os.path.abspath(bench_path)
  225. etc_systemd_system = os.path.join("/", "etc", "systemd", "system")
  226. config_path = os.path.join(bench_dir, "config", "systemd")
  227. unit_files = get_unit_files(bench_dir)
  228. for unit_file in unit_files:
  229. filename = "".join(unit_file)
  230. exec_cmd(
  231. f'sudo ln -s {config_path}/{filename} {etc_systemd_system}/{"".join(unit_file)}'
  232. )
  233. exec_cmd("sudo systemctl daemon-reload")
  234. def _delete_symlinks(bench_path):
  235. bench_dir = os.path.abspath(bench_path)
  236. etc_systemd_system = os.path.join("/", "etc", "systemd", "system")
  237. unit_files = get_unit_files(bench_dir)
  238. for unit_file in unit_files:
  239. exec_cmd(f'sudo rm {etc_systemd_system}/{"".join(unit_file)}')
  240. exec_cmd("sudo systemctl daemon-reload")
  241. def get_unit_files(bench_path):
  242. bench_name = get_bench_name(bench_path)
  243. unit_files = [
  244. [bench_name, ".target"],
  245. [bench_name + "-workers", ".target"],
  246. [bench_name + "-web", ".target"],
  247. [bench_name + "-redis", ".target"],
  248. [bench_name + "-xhiveframework-default-worker@", ".service"],
  249. [bench_name + "-xhiveframework-short-worker@", ".service"],
  250. [bench_name + "-xhiveframework-long-worker@", ".service"],
  251. [bench_name + "-xhiveframework-schedule", ".service"],
  252. [bench_name + "-xhiveframework-web", ".service"],
  253. [bench_name + "-node-socketio", ".service"],
  254. [bench_name + "-redis-cache", ".service"],
  255. [bench_name + "-redis-queue", ".service"],
  256. ]
  257. return unit_files