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.
 
 
 
 

168 regels
5.0 KiB

  1. # imports - standard imports
  2. import getpass
  3. import logging
  4. import os
  5. # imports - third party imports
  6. import click
  7. # imports - module imports
  8. import bench
  9. from bench.app import use_rq
  10. from bench.bench import Bench
  11. from bench.config.common_site_config import (
  12. compute_max_requests_jitter,
  13. get_config,
  14. get_default_max_requests,
  15. get_gunicorn_workers,
  16. update_config,
  17. )
  18. from bench.utils import get_bench_name, which
  19. logger = logging.getLogger(bench.PROJECT_NAME)
  20. def generate_supervisor_config(bench_path, user=None, yes=False, skip_redis=False):
  21. """Generate supervisor config for respective bench path"""
  22. if not user:
  23. user = getpass.getuser()
  24. config = Bench(bench_path).conf
  25. template = bench.config.env().get_template("supervisor.conf")
  26. bench_dir = os.path.abspath(bench_path)
  27. web_worker_count = config.get(
  28. "gunicorn_workers", get_gunicorn_workers()["gunicorn_workers"]
  29. )
  30. max_requests = config.get(
  31. "gunicorn_max_requests", get_default_max_requests(web_worker_count)
  32. )
  33. config = template.render(
  34. **{
  35. "bench_dir": bench_dir,
  36. "sites_dir": os.path.join(bench_dir, "sites"),
  37. "user": user,
  38. "use_rq": use_rq(bench_path),
  39. "http_timeout": config.get("http_timeout", 120),
  40. "redis_server": which("redis-server"),
  41. "node": which("node") or which("nodejs"),
  42. "redis_cache_config": os.path.join(bench_dir, "config", "redis_cache.conf"),
  43. "redis_queue_config": os.path.join(bench_dir, "config", "redis_queue.conf"),
  44. "webserver_port": config.get("webserver_port", 8000),
  45. "gunicorn_workers": web_worker_count,
  46. "gunicorn_max_requests": max_requests,
  47. "gunicorn_max_requests_jitter": compute_max_requests_jitter(max_requests),
  48. "bench_name": get_bench_name(bench_path),
  49. "background_workers": config.get("background_workers") or 1,
  50. "bench_cmd": which("bench"),
  51. "skip_redis": skip_redis,
  52. "workers": config.get("workers", {}),
  53. "multi_queue_consumption": can_enable_multi_queue_consumption(bench_path),
  54. "supervisor_startretries": 10,
  55. }
  56. )
  57. conf_path = os.path.join(bench_path, "config", "supervisor.conf")
  58. if not yes and os.path.exists(conf_path):
  59. click.confirm(
  60. "supervisor.conf already exists and this will overwrite it. Do you want to continue?",
  61. abort=True,
  62. )
  63. with open(conf_path, "w") as f:
  64. f.write(config)
  65. update_config({"restart_supervisor_on_update": True}, bench_path=bench_path)
  66. update_config({"restart_systemd_on_update": False}, bench_path=bench_path)
  67. sync_socketio_port(bench_path)
  68. def get_supervisord_conf():
  69. """Returns path of supervisord config from possible paths"""
  70. possibilities = (
  71. "supervisord.conf",
  72. "etc/supervisord.conf",
  73. "/etc/supervisord.conf",
  74. "/etc/supervisor/supervisord.conf",
  75. "/etc/supervisord.conf",
  76. )
  77. for possibility in possibilities:
  78. if os.path.exists(possibility):
  79. return possibility
  80. def sync_socketio_port(bench_path):
  81. # Backward compatbility: always keep redis_cache and redis_socketio port same
  82. common_config = get_config(bench_path=bench_path)
  83. socketio_port = common_config.get("redis_socketio")
  84. cache_port = common_config.get("redis_cache")
  85. if socketio_port and socketio_port != cache_port:
  86. update_config({"redis_socketio": cache_port})
  87. def can_enable_multi_queue_consumption(bench_path: str) -> bool:
  88. try:
  89. from semantic_version import Version
  90. from bench.utils.app import get_current_version
  91. supported_version = Version(major=14, minor=18, patch=0)
  92. xhiveframework_version = Version(get_current_version("xhiveframework", bench_path=bench_path))
  93. return xhiveframework_version > supported_version
  94. except Exception:
  95. return False
  96. def check_supervisord_config(user=None):
  97. """From bench v5.x, we're moving to supervisor running as user"""
  98. # i don't think bench should be responsible for this but we're way past this now...
  99. # removed updating supervisord conf & reload in Aug 2022 - gavin@xhiveframework.io
  100. import configparser
  101. if not user:
  102. user = getpass.getuser()
  103. supervisord_conf = get_supervisord_conf()
  104. section = "unix_http_server"
  105. updated_values = {"chmod": "0760", "chown": f"{user}:{user}"}
  106. supervisord_conf_changes = ""
  107. if not supervisord_conf:
  108. logger.log("supervisord.conf not found")
  109. return
  110. config = configparser.ConfigParser()
  111. config.read(supervisord_conf)
  112. if section not in config.sections():
  113. config.add_section(section)
  114. action = f"Section {section} Added"
  115. logger.log(action)
  116. supervisord_conf_changes += "\n" + action
  117. for key, value in updated_values.items():
  118. try:
  119. current_value = config.get(section, key)
  120. except configparser.NoOptionError:
  121. current_value = ""
  122. if current_value.strip() != value:
  123. config.set(section, key, value)
  124. action = (
  125. f"Updated supervisord.conf: '{key}' changed from '{current_value}' to '{value}'"
  126. )
  127. logger.log(action)
  128. supervisord_conf_changes += "\n" + action
  129. if not supervisord_conf_changes:
  130. logger.error("supervisord.conf not updated")
  131. contents = "\n".join(f"{x}={y}" for x, y in updated_values.items())
  132. print(
  133. f"Update your {supervisord_conf} with the following values:\n[{section}]\n{contents}"
  134. )