123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- import urllib.parse
- from typing import TYPE_CHECKING, TypedDict, NotRequired
- if TYPE_CHECKING:
- from render import Render
- from storage import IxStorage
- try:
- from .error import RenderError
- from .deps_perms import PermsContainer
- from .validations import valid_port_or_raise, valid_redis_password_or_raise
- except ImportError:
- from error import RenderError
- from deps_perms import PermsContainer
- from validations import valid_port_or_raise, valid_redis_password_or_raise
- class RedisConfig(TypedDict):
- password: str
- port: NotRequired[int]
- volume: "IxStorage"
- class RedisContainer:
- def __init__(
- self, render_instance: "Render", name: str, image: str, config: RedisConfig, perms_instance: PermsContainer
- ):
- self._render_instance = render_instance
- self._name = name
- self._config = config
- for key in ("password", "volume"):
- if key not in config:
- raise RenderError(f"Expected [{key}] to be set for redis")
- valid_redis_password_or_raise(config["password"])
- port = valid_port_or_raise(self.get_port())
- self._get_repo(image, ("redis", "valkey/valkey"))
- user, group = 568, 568
- run_as = self._render_instance.values.get("run_as")
- if run_as:
- user = run_as["user"] or user # Avoids running as root
- group = run_as["group"] or group # Avoids running as root
- c = self._render_instance.add_container(name, image)
- c.set_user(user, group)
- c.remove_devices()
- c.healthcheck.set_test("redis", {"password": config["password"]})
- cmd = []
- cmd.extend(["--port", str(port)])
- cmd.extend(["--requirepass", config["password"]])
- c.environment.add_env("REDIS_PASSWORD", config["password"])
- c.set_command(cmd)
- c.add_storage("/data", config["volume"])
- perms_instance.add_or_skip_action(
- f"{self._name}_redis_data", config["volume"], {"uid": user, "gid": group, "mode": "check"}
- )
- # Store container for further configuration
- # For example: c.depends.add_dependency("other_container", "service_started")
- self._container = c
- def _get_repo(self, image, supported_repos):
- images = self._render_instance.values["images"]
- if image not in images:
- raise RenderError(f"Image [{image}] not found in values. Available images: [{', '.join(images.keys())}]")
- repo = images[image].get("repository")
- if not repo:
- raise RenderError("Could not determine repo")
- if repo not in supported_repos:
- raise RenderError(f"Unsupported repo [{repo}] for redis. Supported repos: {', '.join(supported_repos)}")
- return repo
- def get_port(self):
- return self._config.get("port") or 6379
- def get_url(self, variant: str):
- addr = f"{self._name}:{self.get_port()}"
- password = urllib.parse.quote_plus(self._config["password"])
- match variant:
- case "redis":
- return f"redis://default:{password}@{addr}"
- @property
- def container(self):
- return self._container
|