#!/bin/bash # Run a command as the unprivileged rootless Docker install user. # # This used to ssh to @localhost to get a fully-initialised user session # (so `systemctl --user` and the rootless dockerd would work). That needs an SSH # server, a generated key and authorized_keys — none of which the install set # up, so the whole rootless path silently no-op'd. Instead run via `sudo -u` # with the session env set explicitly: `loginctl enable-linger` (done during # rootless setup) keeps the user's `systemd --user` and /run/user/ alive, # so `systemctl --user` works, and DOCKER_HOST points at the rootless socket. # `sudo -u` to an unprivileged user is not a root escalation, and there's no SSH # attack surface. dockerCommandRunInstallUser() { local silent_flag="" local argv_mode="" while true; do case "$1" in --silent) silent_flag="1"; shift ;; --argv) argv_mode="1"; shift ;; *) break ;; esac done local uid uid=$(id -u "$CFG_DOCKER_INSTALL_USER" 2>/dev/null) if [ -z "$uid" ]; then isError "Cannot run as '$CFG_DOCKER_INSTALL_USER' — user does not exist." return 1 fi # rootless docker installs its binaries to the user's ~/bin, so include it. local run_env=( "HOME=/home/$CFG_DOCKER_INSTALL_USER" "XDG_RUNTIME_DIR=/run/user/$uid" "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus" "DOCKER_HOST=unix:///run/user/$uid/docker.sock" "PATH=/home/$CFG_DOCKER_INSTALL_USER/bin:/usr/bin:/bin:/usr/local/bin" ) # Run from the install user's HOME, not the caller's cwd. At install time the # caller is root in /root, which the unprivileged user can't enter, so # cwd-sensitive tools error (e.g. find: "Failed to change directory: /root"). local run_cwd="/home/$CFG_DOCKER_INSTALL_USER" # --argv: exec the remaining args verbatim (no shell re-parse) so regex/ # quotes/backslashes in arguments (e.g. sed scripts) survive intact. Default: # treat $1 as a shell snippet via bash -c (needed for pipes/redirects/ # systemctl --user/etc.). if [ -n "$argv_mode" ]; then if [ -n "$silent_flag" ]; then sudo -u "$CFG_DOCKER_INSTALL_USER" env --chdir="$run_cwd" "${run_env[@]}" "$@" >/dev/null 2>&1 else sudo -u "$CFG_DOCKER_INSTALL_USER" env --chdir="$run_cwd" "${run_env[@]}" "$@" fi else local remote_command="$1" if [ -n "$silent_flag" ]; then sudo -u "$CFG_DOCKER_INSTALL_USER" env --chdir="$run_cwd" "${run_env[@]}" bash -c "$remote_command" >/dev/null 2>&1 else sudo -u "$CFG_DOCKER_INSTALL_USER" env --chdir="$run_cwd" "${run_env[@]}" bash -c "$remote_command" fi fi }