You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by av...@apache.org on 2026/10/20 15:33:52 UTC

(ignite) branch master updated: IGNITE-29164 [ducktests] Support rootless Docker in the local runner (#13703)

This is an automated email from the ASF dual-hosted git repository.

anton-vinogradov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 9784ed7d8e7 IGNITE-29164 [ducktests] Support rootless Docker in the local runner (#13703)
9784ed7d8e7 is described below

commit 9784ed7d8e73dbbcd76e9d18ca1cca0394c9dd5b
Author: Maksim Davydov <70...@users.noreply.github.com>
AuthorDate: Tue Oct 20 18:33:41 2026 +0300

    IGNITE-29164 [ducktests] Support rootless Docker in the local runner (#13703)
---
 modules/ducktests/README.md                  |  2 +-
 modules/ducktests/tests/docker/Dockerfile    |  5 +++--
 modules/ducktests/tests/docker/ducker-ignite | 13 ++++++++++++-
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/modules/ducktests/README.md b/modules/ducktests/README.md
index 4f0ccc3dde1..c789bc25d98 100644
--- a/modules/ducktests/README.md
+++ b/modules/ducktests/README.md
@@ -19,7 +19,7 @@ All paths below are relative to `${IGNITE_HOME}/modules/ducktests/tests`:
 Docker is used to emulate a distributed multi-node cluster environment where each individual container acts as a running cluster node.
 
 ### 1. Prerequisites
-* **Docker** installed and running on your host system.
+* **Docker** installed and running on your host system. A rootless daemon works too: the runner detects it and runs the `ducker` user as container root, which the daemon maps to you. Network fault tests then need the `iptables` and `sch_netem` kernel modules already loaded on the host, since a rootless container cannot load them.
 * **Python >= 3.8** installed on your host system (required only for local environment scripts and development).
 
 ### 2. Prepare the Environment & Code
diff --git a/modules/ducktests/tests/docker/Dockerfile b/modules/ducktests/tests/docker/Dockerfile
index ba151879bbf..9861b33a481 100644
--- a/modules/ducktests/tests/docker/Dockerfile
+++ b/modules/ducktests/tests/docker/Dockerfile
@@ -170,8 +170,9 @@ ARG USER_GID=1000
 RUN getent passwd ubuntu &>/dev/null && userdel -r ubuntu || true
 
 # Provision ducker system environment and security configurations
-RUN groupadd -g $USER_GID ducker \
-    && useradd -u $USER_UID -g $USER_GID -ms /bin/bash ducker \
+# -o lets ducker share uid and gid 0 with root in an image built for a rootless daemon (see ducker-ignite).
+RUN groupadd -o -g $USER_GID ducker \
+    && useradd -o -u $USER_UID -g $USER_GID -ms /bin/bash ducker \
     && mkdir -p /home/ducker/ \
     && rsync -aiq /root/.ssh/ /home/ducker/.ssh \
     && chown -R ducker /home/ducker/ /mnt/ /var/log/ /opt \
diff --git a/modules/ducktests/tests/docker/ducker-ignite b/modules/ducktests/tests/docker/ducker-ignite
index 5c204f02bb8..6be63168870 100755
--- a/modules/ducktests/tests/docker/ducker-ignite
+++ b/modules/ducktests/tests/docker/ducker-ignite
@@ -267,6 +267,17 @@ ducker_build_image() {
         extra_build_args="--no-cache"
     fi
 
+    # The ducker user must be able to write the checkout that ducker_run mounts. A rootless daemon
+    # maps only container root to the caller, so there ducker is built as uid 0.
+    local ducker_uid="$(id -u)"
+    local ducker_gid="$(id -g)"
+
+    if docker info --format '{{.SecurityOptions}}' 2>/dev/null | grep -q rootless; then
+        echo "** Rootless Docker detected: building ducker as uid 0."
+        ducker_uid=0
+        ducker_gid=0
+    fi
+
     # Use SECONDS, a builtin bash variable that gets incremented each second, to measure the docker
     # build duration.
     SECONDS=0
@@ -275,7 +286,7 @@ ducker_build_image() {
     # Tip: if you are scratching your head for some dependency problems that are referring to an old code version
     # (for example java.lang.NoClassDefFoundError), add --no-cache flag to the build shall give you a clean start.
     must_do -v -o docker build ${extra_build_args} --network=host --memory="${docker_build_memory_limit}" \
-        --build-arg USER_UID=$(id -u) --build-arg USER_GID=$(id -g) \
+        --build-arg USER_UID=${ducker_uid} --build-arg USER_GID=${ducker_gid} \
         --build-arg "ducker_creator=${user_name}" --build-arg "jdk_version=${jdk_version}" \
         --build-arg "python_version=${python_version}" -t "${image_name}" \
         -f "${docker_context}/Dockerfile" -- "${docker_context}"