From 746635d196d8b82b8312bb6976ad1b6ece6ceda8 Mon Sep 17 00:00:00 2001 From: Maksim Davydov Date: Mon, 19 Oct 2026 13:19:50 +0300 Subject: [PATCH] IGNITE-29164 [ducktests] Support rootless Docker in the local runner --- 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 4f0ccc3dde11f..c789bc25d98b4 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 ba151879bbfde..9861b33a4813b 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 5c204f02bb881..6be6316887045 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}"