hack: run rootless daemon in a systemd user session when systemd is present

Previously, the rootless-systemd CI mode failed with:

    open /sys/fs/cgroup/user.slice/user-1000.slice/cgroup.controllers: no such file or directory

on every container start. The daemon auto-selects the systemd cgroup
driver (cgroup v2 + systemd detected), but the test harness launched
dockerd-rootless.sh via plain "sudo" with a fabricated XDG_RUNTIME_DIR,
so there was no systemd user session at all: no user-${uid}.slice, no
user@${uid}.service, and no user D-Bus socket for runc to talk to.
withRootless() (daemon/oci_linux.go) then failed reading the controllers
file at every container start.

Set up the environment the way it is documented for production rootless
installations instead:

- hack/make/.integration-daemon-start: when systemd is running, enable
  lingering for unprivilegeduser (which starts user@${uid}.service),
  use /run/user/${uid} as XDG_RUNTIME_DIR, and export
  DBUS_SESSION_BUS_ADDRESS so that runc can find the systemd user
  manager. The variable also propagates to the daemons spawned by the
  test suite (sudo --preserve-env in internal/testutil/daemon), whose
  XDG_RUNTIME_DIR points to a non-standard location.

- hack/dind-systemd: delegate the cpu/cpuset/io/memory/pids cgroup
  controllers to unprivileged users, matching
  https://docs.docker.com/engine/security/rootless/#limiting-resources

Fixes the "test (amd64, *, rootless-systemd)" CI failures tracked in
issue 44084.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
This commit is contained in:
Akihiro Suda
2026-07-09 02:04:27 +09:00
parent 3c8d133837
commit 438b5bea26
2 changed files with 41 additions and 4 deletions

View File

@@ -104,6 +104,16 @@ EOF
systemctl enable collect-firewalld-logs.service
fi
# Delegate cgroup v2 controllers to unprivileged users, so that the rootless
# daemon can use the systemd cgroup driver and set resource limits. This is
# the setup documented for production rootless installations:
# https://docs.docker.com/engine/security/rootless/#limiting-resources
mkdir -p /etc/systemd/system/user@.service.d
cat > /etc/systemd/system/user@.service.d/delegate.conf << EOF
[Service]
Delegate=cpu cpuset io memory pids
EOF
env > /etc/docker-entrypoint-env
cat > /etc/systemd/system/docker-entrypoint.target << EOF

View File

@@ -84,14 +84,41 @@ if [ -n "$DOCKER_ROOTLESS" ]; then
fi
user="unprivilegeduser"
uid=$(id -u $user)
# shellcheck disable=SC2174
mkdir -p -m 700 "/tmp/docker-${uid}"
chown "$user" "/tmp/docker-${uid}"
if [ -d "/run/systemd/system" ]; then
# Set up a systemd user session for the user, with cgroup delegation
# (see hack/dind-systemd), so that the daemon and the tests can use
# the systemd cgroup driver. This mimics the setup documented for
# production ("loginctl enable-linger"), where dockerd-rootless.sh
# runs inside user@${uid}.service.
# https://github.com/moby/moby/issues/44084
xdg_runtime_dir="/run/user/${uid}"
tries=0
# Retried in a loop: this may race with systemd-logind/dbus startup,
# as docker-entrypoint.service has no ordering dependency on them.
until loginctl enable-linger "$user" && [ -S "${xdg_runtime_dir}/bus" ]; do
tries=$((tries + 1))
if [ $tries -gt 30 ]; then
echo >&2 "# failed to set up a systemd user session for $user (no ${xdg_runtime_dir}/bus)"
exit 1
fi
sleep 1
done
# Propagated to the daemon started below, and to the test suite, which
# passes it on to the daemons it spawns (sudo --preserve-env in
# internal/testutil/daemon). runc needs it to find the systemd user
# manager when $XDG_RUNTIME_DIR points to a non-standard location.
export DBUS_SESSION_BUS_ADDRESS="unix:path=${xdg_runtime_dir}/bus"
else
xdg_runtime_dir="/tmp/docker-${uid}"
# shellcheck disable=SC2174
mkdir -p -m 700 "${xdg_runtime_dir}"
chown "$user" "${xdg_runtime_dir}"
fi
chmod -R o+w "$DEST"
# The rootless daemon won't be able to load modules for tests that need them, so do it here.
# There's no modprobe in the dev container, so https://x.com/lucabruno/status/902934379835662336
ip link show br_netfilter || true
dockerd="sudo -u $user -E -E XDG_RUNTIME_DIR=/tmp/docker-${uid} -E HOME=/home/${user} -E PATH=$PATH -- dockerd-rootless.sh"
dockerd="sudo -u $user -E -E XDG_RUNTIME_DIR=${xdg_runtime_dir} -E HOME=/home/${user} -E PATH=$PATH -- dockerd-rootless.sh"
fi
if [ -z "$DOCKER_TEST_HOST" ]; then