6
0
mirror of https://github.com/ChristianLight/tutor.git synced 2024-11-15 17:47:13 +00:00

fix: fix ulimits error for elasticsearch in Docker rootless mode

disable `ulimits` in rootless docker mode by setting them to zero
This commit is contained in:
Omar Al-Ithawi 2023-10-12 11:14:11 +03:00 committed by Régis Behmo
parent 8fdb6f52d9
commit 65ba0d2de2
5 changed files with 46 additions and 0 deletions

View File

@ -0,0 +1,2 @@
- [Improvement] Fix `ulimits` error for elasticsearch in Docker rootless mode (by @OmarIthawi)

View File

@ -3,6 +3,7 @@ import os
import tempfile import tempfile
import unittest import unittest
from io import StringIO from io import StringIO
import subprocess
from typing import List, Tuple from typing import List, Tuple
from unittest.mock import MagicMock, mock_open, patch from unittest.mock import MagicMock, mock_open, patch
@ -241,6 +242,25 @@ class UtilsTests(unittest.TestCase):
self.assertFalse(utils.is_http("home/user/")) self.assertFalse(utils.is_http("home/user/"))
self.assertFalse(utils.is_http("http-home/user/")) self.assertFalse(utils.is_http("http-home/user/"))
@patch("subprocess.run")
def test_is_docker_rootless(self, mock_run: MagicMock) -> None:
# Mock rootless `docker info` output
utils.is_docker_rootless.cache_clear()
mock_run.return_value.stdout = "some prefix\n rootless foo bar".encode("utf-8")
self.assertTrue(utils.is_docker_rootless())
# Mock regular `docker info` output
utils.is_docker_rootless.cache_clear()
mock_run.return_value.stdout = "some prefix, regular docker".encode("utf-8")
self.assertFalse(utils.is_docker_rootless())
@patch("subprocess.run")
def test_is_docker_rootless_podman(self, mock_run: MagicMock) -> None:
"""Test the `is_docker_rootless` when podman is used or any other error with `docker info`"""
utils.is_docker_rootless.cache_clear()
mock_run.side_effect = subprocess.CalledProcessError(1, "docker info")
self.assertFalse(utils.is_docker_rootless())
def test_format_table(self) -> None: def test_format_table(self) -> None:
rows: List[Tuple[str, ...]] = [ rows: List[Tuple[str, ...]] = [
("a", "xyz", "value 1"), ("a", "xyz", "value 1"),

View File

@ -55,6 +55,7 @@ def _prepare_environment() -> None:
("TUTOR_APP", __app__.replace("-", "_")), ("TUTOR_APP", __app__.replace("-", "_")),
("TUTOR_VERSION", __version__), ("TUTOR_VERSION", __version__),
("is_buildkit_enabled", utils.is_buildkit_enabled), ("is_buildkit_enabled", utils.is_buildkit_enabled),
("is_docker_rootless", utils.is_docker_rootless),
], ],
) )

View File

@ -52,4 +52,13 @@ services:
command: openedx-assets watch-themes --env dev command: openedx-assets watch-themes --env dev
restart: unless-stopped restart: unless-stopped
{% if RUN_ELASTICSEARCH and is_docker_rootless() %}
elasticsearch:
ulimits:
memlock:
# Fixes error setting rlimits for ready process in rootless docker
soft: 0 # zero means "unset" in the memlock context
hard: 0
{% endif %}
{{ patch("local-docker-compose-dev-services")|indent(2) }} {{ patch("local-docker-compose-dev-services")|indent(2) }}

View File

@ -192,6 +192,20 @@ def is_buildkit_enabled() -> bool:
return False return False
@lru_cache(maxsize=None)
def is_docker_rootless() -> bool:
"""
A helper function to determine if Docker is running in rootless mode.
- https://docs.docker.com/engine/security/rootless/
"""
try:
results = subprocess.run(["docker", "info"], capture_output=True, check=True)
return "rootless" in results.stdout.decode()
except subprocess.CalledProcessError:
return False
def docker_compose(*command: str) -> int: def docker_compose(*command: str) -> int:
return execute("docker", "compose", *command) return execute("docker", "compose", *command)