Merge branch 'master' into nightly

This commit is contained in:
Régis Behmo 2023-11-23 12:58:04 +01:00
commit 913a1adae4
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

@ -57,6 +57,7 @@ def _prepare_environment() -> None:
# BuildKit used to be optional. Now, it's always enabled. # BuildKit used to be optional. Now, it's always enabled.
# This constant is just for temporary backwards compatibility (REMOVE-AFTER-V16). # This constant is just for temporary backwards compatibility (REMOVE-AFTER-V16).
("is_buildkit_enabled", lambda: True), ("is_buildkit_enabled", lambda: True),
("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

@ -173,6 +173,20 @@ def docker(*command: str) -> int:
return execute("docker", *command) return execute("docker", *command)
@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)