deps_elastic.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from typing import TYPE_CHECKING, TypedDict, NotRequired
  2. if TYPE_CHECKING:
  3. from render import Render
  4. from storage import IxStorage
  5. try:
  6. from .error import RenderError
  7. from .deps_perms import PermsContainer
  8. except ImportError:
  9. from error import RenderError
  10. from deps_perms import PermsContainer
  11. class ElasticConfig(TypedDict):
  12. password: str
  13. node_name: str
  14. port: NotRequired[int]
  15. volume: "IxStorage"
  16. class ElasticSearchContainer:
  17. def __init__(
  18. self, render_instance: "Render", name: str, image: str, config: ElasticConfig, perms_instance: PermsContainer
  19. ):
  20. self._render_instance = render_instance
  21. self._name = name
  22. self._config = config
  23. self._data_dir = "/usr/share/elasticsearch/data"
  24. for key in ("password", "node_name", "volume"):
  25. if key not in config:
  26. raise RenderError(f"Expected [{key}] to be set for ElasticSearch")
  27. c = self._render_instance.add_container(name, image)
  28. c.set_user(1000, 1000)
  29. basic_auth_header = self._render_instance.funcs["basic_auth_header"]("elastic", config["password"])
  30. c.healthcheck.set_test(
  31. "curl",
  32. {
  33. "port": self.get_port(),
  34. "path": "/_cluster/health?local=true",
  35. "headers": [("Authorization", basic_auth_header)],
  36. },
  37. )
  38. c.remove_devices()
  39. c.add_storage(self._data_dir, config["volume"])
  40. c.environment.add_env("ELASTIC_PASSWORD", config["password"])
  41. c.environment.add_env("http.port", self.get_port())
  42. c.environment.add_env("path.data", self._data_dir)
  43. c.environment.add_env("path.repo", self.get_snapshots_dir())
  44. c.environment.add_env("node.name", config["node_name"])
  45. c.environment.add_env("discovery.type", "single-node")
  46. c.environment.add_env("xpack.security.enabled", True)
  47. c.environment.add_env("xpack.security.transport.ssl.enabled", False)
  48. perms_instance.add_or_skip_action(
  49. f"{self._name}_elastic_data", config["volume"], {"uid": 1000, "gid": 1000, "mode": "check"}
  50. )
  51. self._get_repo(image, ("docker.elastic.co/elasticsearch/elasticsearch"))
  52. # Store container for further configuration
  53. # For example: c.depends.add_dependency("other_container", "service_started")
  54. self._container = c
  55. @property
  56. def container(self):
  57. return self._container
  58. def _get_repo(self, image, supported_repos):
  59. images = self._render_instance.values["images"]
  60. if image not in images:
  61. raise RenderError(f"Image [{image}] not found in values. Available images: [{', '.join(images.keys())}]")
  62. repo = images[image].get("repository")
  63. if not repo:
  64. raise RenderError("Could not determine repo")
  65. if repo not in supported_repos:
  66. raise RenderError(
  67. f"Unsupported repo [{repo}] for elastic search. Supported repos: {', '.join(supported_repos)}"
  68. )
  69. return repo
  70. def get_port(self):
  71. return self._config.get("port") or 9200
  72. def get_url(self):
  73. return f"http://{self._name}:{self.get_port()}"
  74. def get_snapshots_dir(self):
  75. return f"{self._data_dir}/snapshots"