deps_mongodb.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import urllib.parse
  2. from typing import TYPE_CHECKING, TypedDict
  3. if TYPE_CHECKING:
  4. from render import Render
  5. from storage import IxStorage
  6. try:
  7. from .error import RenderError
  8. from .deps_perms import PermsContainer
  9. except ImportError:
  10. from error import RenderError
  11. from deps_perms import PermsContainer
  12. class MongoDBConfig(TypedDict):
  13. user: str
  14. password: str
  15. database: str
  16. volume: "IxStorage"
  17. class MongoDBContainer:
  18. def __init__(
  19. self, render_instance: "Render", name: str, image: str, config: MongoDBConfig, perms_instance: PermsContainer
  20. ):
  21. self._render_instance = render_instance
  22. self._name = name
  23. self._config = config
  24. self._data_dir = "/data/db"
  25. for key in ("user", "password", "database", "volume"):
  26. if key not in config:
  27. raise RenderError(f"Expected [{key}] to be set for mongodb")
  28. c = self._render_instance.add_container(name, image)
  29. c.set_user(999, 999)
  30. c.healthcheck.set_test("mongodb", {"db": config["database"]})
  31. c.remove_devices()
  32. c.add_storage(self._data_dir, config["volume"])
  33. c.environment.add_env("MONGO_INITDB_ROOT_USERNAME", config["user"])
  34. c.environment.add_env("MONGO_INITDB_ROOT_PASSWORD", config["password"])
  35. c.environment.add_env("MONGO_INITDB_DATABASE", config["database"])
  36. perms_instance.add_or_skip_action(
  37. f"{self._name}_mongodb_data", config["volume"], {"uid": 999, "gid": 999, "mode": "check"}
  38. )
  39. self._get_repo(image, ("mongodb"))
  40. # Store container for further configuration
  41. # For example: c.depends.add_dependency("other_container", "service_started")
  42. self._container = c
  43. @property
  44. def container(self):
  45. return self._container
  46. def _get_repo(self, image, supported_repos):
  47. images = self._render_instance.values["images"]
  48. if image not in images:
  49. raise RenderError(f"Image [{image}] not found in values. Available images: [{', '.join(images.keys())}]")
  50. repo = images[image].get("repository")
  51. if not repo:
  52. raise RenderError("Could not determine repo")
  53. if repo not in supported_repos:
  54. raise RenderError(f"Unsupported repo [{repo}] for mongodb. Supported repos: {', '.join(supported_repos)}")
  55. return repo
  56. def get_port(self):
  57. return self._config.get("port") or 27017
  58. def get_url(self, variant: str):
  59. user = urllib.parse.quote_plus(self._config["user"])
  60. password = urllib.parse.quote_plus(self._config["password"])
  61. creds = f"{user}:{password}"
  62. addr = f"{self._name}:{self.get_port()}"
  63. db = self._config["database"]
  64. urls = {
  65. "mongodb": f"mongodb://{creds}@{addr}/{db}",
  66. "host_port": addr,
  67. }
  68. if variant not in urls:
  69. raise RenderError(f"Expected [variant] to be one of [{', '.join(urls.keys())}], got [{variant}]")
  70. return urls[variant]