mirror of
https://github.com/MAGICGrants/truenas-apps.git
synced 2026-01-09 20:47:58 -05:00
library: add meili dep (#2945)
* add meili dep support * small fix * let default
This commit is contained in:
@@ -4,17 +4,19 @@ if TYPE_CHECKING:
|
||||
from render import Render
|
||||
|
||||
try:
|
||||
from .deps_postgres import PostgresContainer, PostgresConfig
|
||||
from .deps_redis import RedisContainer, RedisConfig
|
||||
from .deps_mariadb import MariadbContainer, MariadbConfig
|
||||
from .deps_meilisearch import MeilisearchContainer, MeiliConfig
|
||||
from .deps_mongodb import MongoDBContainer, MongoDBConfig
|
||||
from .deps_perms import PermsContainer
|
||||
from .deps_postgres import PostgresContainer, PostgresConfig
|
||||
from .deps_redis import RedisContainer, RedisConfig
|
||||
except ImportError:
|
||||
from deps_postgres import PostgresContainer, PostgresConfig
|
||||
from deps_redis import RedisContainer, RedisConfig
|
||||
from deps_mariadb import MariadbContainer, MariadbConfig
|
||||
from deps_meilisearch import MeilisearchContainer, MeiliConfig
|
||||
from deps_mongodb import MongoDBContainer, MongoDBConfig
|
||||
from deps_perms import PermsContainer
|
||||
from deps_postgres import PostgresContainer, PostgresConfig
|
||||
from deps_redis import RedisContainer, RedisConfig
|
||||
|
||||
|
||||
class Deps:
|
||||
@@ -35,3 +37,6 @@ class Deps:
|
||||
|
||||
def mongodb(self, name: str, image: str, config: MongoDBConfig, perms_instance: PermsContainer):
|
||||
return MongoDBContainer(self._render_instance, name, image, config, perms_instance)
|
||||
|
||||
def meilisearch(self, name: str, image: str, config: MeiliConfig, perms_instance: PermsContainer):
|
||||
return MeilisearchContainer(self._render_instance, name, image, config, perms_instance)
|
||||
85
library/2.1.46/deps_meilisearch.py
Normal file
85
library/2.1.46/deps_meilisearch.py
Normal file
@@ -0,0 +1,85 @@
|
||||
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
|
||||
except ImportError:
|
||||
from error import RenderError
|
||||
from deps_perms import PermsContainer
|
||||
|
||||
|
||||
class MeiliConfig(TypedDict):
|
||||
master_key: str
|
||||
port: NotRequired[int]
|
||||
volume: "IxStorage"
|
||||
|
||||
|
||||
class MeilisearchContainer:
|
||||
def __init__(
|
||||
self, render_instance: "Render", name: str, image: str, config: MeiliConfig, perms_instance: PermsContainer
|
||||
):
|
||||
self._render_instance = render_instance
|
||||
self._name = name
|
||||
self._config = config
|
||||
self._data_dir = "/meili_data"
|
||||
|
||||
for key in ("master_key", "volume"):
|
||||
if key not in config:
|
||||
raise RenderError(f"Expected [{key}] to be set for meilisearch")
|
||||
|
||||
c = self._render_instance.add_container(name, image)
|
||||
|
||||
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.set_user(user, group)
|
||||
c.healthcheck.set_test("curl", {"port": self._get_port(), "path": "/health"})
|
||||
c.remove_devices()
|
||||
c.add_storage(self._data_dir, config["volume"])
|
||||
|
||||
c.environment.add_env("MEILI_HTTP_ADDR", f"0.0.0.0:{self._get_port()}")
|
||||
c.environment.add_env("MEILI_NO_ANALYTICS", True)
|
||||
c.environment.add_env("MEILI_EXPERIMENTAL_DUMPLESS_UPGRADE", True)
|
||||
c.environment.add_env("MEILI_MASTER_KEY", config["master_key"])
|
||||
|
||||
perms_instance.add_or_skip_action(
|
||||
f"{self._name}_meili_data", config["volume"], {"uid": user, "gid": group, "mode": "check"}
|
||||
)
|
||||
|
||||
self._get_repo(image, ("getmeili/meilisearch",))
|
||||
|
||||
# Store container for further configuration
|
||||
# For example: c.depends.add_dependency("other_container", "service_started")
|
||||
self._container = c
|
||||
|
||||
@property
|
||||
def container(self):
|
||||
return self._container
|
||||
|
||||
def _get_port(self):
|
||||
return self._config.get("port") or 7700
|
||||
|
||||
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 meilisearch. Supported repos: {', '.join(supported_repos)}"
|
||||
)
|
||||
return repo
|
||||
|
||||
def get_url(self):
|
||||
return f"http://{self._name}:{self._get_port()}"
|
||||
@@ -39,7 +39,7 @@ class RedisContainer:
|
||||
self._get_repo(image, ("redis", "valkey/valkey"))
|
||||
|
||||
user, group = 568, 568
|
||||
run_as = render_instance.values.get("run_as")
|
||||
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
|
||||
@@ -615,3 +615,78 @@ def test_add_mongodb_unsupported_repo(mock_values):
|
||||
},
|
||||
perms_container,
|
||||
)
|
||||
|
||||
|
||||
def test_add_meilisearch(mock_values):
|
||||
mock_values["images"]["meili_image"] = {"repository": "getmeili/meilisearch", "tag": "v1.17.0"}
|
||||
render = Render(mock_values)
|
||||
c1 = render.add_container("test_container", "test_image")
|
||||
c1.healthcheck.disable()
|
||||
perms_container = render.deps.perms("perms_container")
|
||||
m = render.deps.meilisearch(
|
||||
"meili_container",
|
||||
"meili_image",
|
||||
{
|
||||
"master_key": "test_master_key",
|
||||
"volume": {"type": "volume", "volume_config": {"volume_name": "test_volume", "auto_permissions": True}},
|
||||
},
|
||||
perms_container,
|
||||
)
|
||||
if perms_container.has_actions():
|
||||
perms_container.activate()
|
||||
m.container.depends.add_dependency("perms_container", "service_completed_successfully")
|
||||
output = render.render()
|
||||
assert "devices" not in output["services"]["meili_container"]
|
||||
assert "reservations" not in output["services"]["meili_container"]["deploy"]["resources"]
|
||||
assert output["services"]["meili_container"]["image"] == "getmeili/meilisearch:v1.17.0"
|
||||
assert output["services"]["meili_container"]["user"] == "568:568"
|
||||
assert output["services"]["meili_container"]["deploy"]["resources"]["limits"]["cpus"] == "2.0"
|
||||
assert output["services"]["meili_container"]["deploy"]["resources"]["limits"]["memory"] == "4096M"
|
||||
assert output["services"]["meili_container"]["healthcheck"] == {
|
||||
"test": "curl --request GET --silent --output /dev/null --show-error --fail http://127.0.0.1:7700/health",
|
||||
"interval": "30s",
|
||||
"timeout": "5s",
|
||||
"retries": 5,
|
||||
"start_period": "15s",
|
||||
"start_interval": "2s",
|
||||
}
|
||||
assert output["services"]["meili_container"]["volumes"] == [
|
||||
{
|
||||
"type": "volume",
|
||||
"source": "test_volume",
|
||||
"target": "/meili_data",
|
||||
"read_only": False,
|
||||
"volume": {"nocopy": False},
|
||||
}
|
||||
]
|
||||
assert output["services"]["meili_container"]["environment"] == {
|
||||
"TZ": "Etc/UTC",
|
||||
"UMASK": "002",
|
||||
"UMASK_SET": "002",
|
||||
"NVIDIA_VISIBLE_DEVICES": "void",
|
||||
"MEILI_MASTER_KEY": "test_master_key",
|
||||
"MEILI_HTTP_ADDR": "0.0.0.0:7700",
|
||||
"MEILI_NO_ANALYTICS": "true",
|
||||
"MEILI_EXPERIMENTAL_DUMPLESS_UPGRADE": "true",
|
||||
}
|
||||
assert output["services"]["meili_container"]["depends_on"] == {
|
||||
"perms_container": {"condition": "service_completed_successfully"}
|
||||
}
|
||||
|
||||
|
||||
def test_add_meilisearch_unsupported_repo(mock_values):
|
||||
mock_values["images"]["meili_image"] = {"repository": "unsupported_repo", "tag": "7"}
|
||||
render = Render(mock_values)
|
||||
c1 = render.add_container("test_container", "test_image")
|
||||
c1.healthcheck.disable()
|
||||
perms_container = render.deps.perms("perms_container")
|
||||
with pytest.raises(Exception):
|
||||
render.deps.meilisearch(
|
||||
"meili_container",
|
||||
"meili_image",
|
||||
{
|
||||
"master_key": "test_master_key",
|
||||
"volume": {"type": "volume", "volume_config": {"volume_name": "test_volume", "auto_permissions": True}},
|
||||
},
|
||||
perms_container,
|
||||
)
|
||||
@@ -1,2 +1,2 @@
|
||||
0.0.1: f074617a82a86d2a6cc78a4c8a4296fc9d168e456f12713e50c696557b302133
|
||||
2.1.45: 2b78b1918738cd8bbb292da9a3f5060f5122e085fa34559c5ae748ead981cff4
|
||||
2.1.46: 464cacce9ffec31b1819cd064a4d1099af6d232cb3d870da847a885e00ed12ce
|
||||
|
||||
Reference in New Issue
Block a user