Управление юнитами systemd другого пользователя

Вопрос или проблема

Может ли один пользователь, или, возможно, root, управлять пользовательскими уровнями systemd услуг другого пользователя?

Я попробовал sudo -u <какой-то пользователь> systemctl --user restart <какая-то услуга>, но он жалуется на dbus: Failed to get D-Bus connection: Connection refused.

Уведомление о снятии поддержки: этот ответ устарел начиная с systemd 248 (выпуск март 2021 г.). Пожалуйста, используйте systemctl -M, как объяснил Эрик Шёлюнд в своем ответе.

У меня была такая же проблема, когда я подключился к своему gentoo ящику удаленно через ssh. В моем случае это произошло потому, что переменные окружения XDG_RUNTIME_DIR и DBUS_SESSION_BUS_ADDRESS отсутствовали. Выполните следующие команды и попробуйте снова:

export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"

Если это помогает, вы можете поместить эти команды в ваш .bashrc. Думаю, должно быть более элегантное решение, чем .bashrc, но это зависит от вашей дистрибуции.

Вот где я нашел это решение.

Редактировать:

войдя как root, я смог успешно запустить systemctl --user как другой пользователь, используя su следующим образом:

su -c 'XDG_RUNTIME_DIR="/run/user/$UID" DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus" systemctl --user status' username

или используя sudo (заметьте, мне пришлось явно добавить соответствующий UID пользователя (1000) в путь ‘/run/user/’, но если вы запускаете это из bash скрипта, вы можете использовать $SUDO_UID вместо этого):

sudo -u username XDG_RUNTIME_DIR="/run/user/1000" DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus" systemctl --user status

systemd 248 (выпущен в марте 2021 г.) ввел поддержку синтаксиса -M username@ для указания другого пользователя.

Предполагая, что другой пользователь называется testuser, а услуга – foobar.service, вы можете теперь выполнить

sudo systemctl -M testuser@ --user restart foobar.service

Предполагая, что someuser использует bash как свою оболочку входа, добавьте следующие exports в ~someuser/.bashrc:

export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"

Затем, пользователь с root/sudo правами может взаимодействовать с systemd someuser, обернув команду runuser:

sudo runuser -l someuser -c "systemctl --user restart some-template@$some-service.service"

У меня была такая же ошибка (Failed to connect to bus: No such file or directory) при выполнении следующей команды на Ubuntu 20.04:

systemctl --user mask tracker-store.service tracker-miner-fs.service tracker-miner-rss.service tracker-extract.service tracker-miner-apps.service tracker-writeback.service

Проблема была из-за алиаса:

alias systemctl="sudo systemctl"

Он заменял systemctl на sudo systemctl, и sudo вызывал ошибку.

Переменные окружения:

export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"

не использовались из-за sudo.

mkaito написал в комментарии выше:

Думаю, sudo нужно их в белом списке, потому что он по умолчанию очищает окружение.

.

Ответ или решение

Управление пользовательскими юнитами systemd другого пользователя

Перенимая роль IT-эксперта, давайте детально рассмотрим, как один пользователь, или root, может управлять пользовательскими сервисами systemd другого пользователя.

Проблема: Ошибка соединения с D-Bus

Часто при попытке выполнить команду systemctl --user от имени другого пользователя возникает ошибка: Failed to get D-Bus connection: Connection refused. Это связано с тем, что при переключении контекста через sudo или su, соединения с D-Bus теряются из-за отсутствия соответствующих переменных среды.

Предварительные шаги: Настройка переменных окружения

Для корректного управления юнитами systemd в контексте другого пользователя, необходимо выставить важные переменные окружения:

export XDG_RUNTIME_DIR="/run/user/$UID"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"

Эти переменные определяют директорию для сеансовых данных и адресацию D-Bus. Включите эту настройку в файл .bashrc соответствующего пользователя для автоматического применения при каждом сеансе.

Решение: Использование runuser и sudo

При использовании su или sudo, важно правильно установить контекст и передать требуемые переменные:

Для su:

su -c 'XDG_RUNTIME_DIR="/run/user/$UID" DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus" systemctl --user restart имя_сервиса' имя_пользователя

Для sudo:

sudo -u имя_пользователя XDG_RUNTIME_DIR="/run/user/1000" DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus" systemctl --user restart имя_сервиса

В скриптах удобно использовать переменную $SUDO_UID для динамического определения UID пользователя.

Решение начиная с systemd 248: Новая функция -M username@

С выходом новой версии systemd (248), требуется использовать обновленный синтаксис для управления сервисами:

sudo systemctl -M имя_пользователя@ --user restart имя_сервиса

Эта команда позволяет корректно управлять сервисами другого пользователя без необходимости ручного вмешательства в переменные окружения.

Заключение

Теперь у вас есть несколько способов контролировать системные службы systemd другого пользователя. Каждый из них подходит для различных сценариев использования и степени контроля. Если вы регулярно сталкиваетесь с необходимостью таких операций, рекомендуется создать скрипт, который сократит время на настройки и упростит процесс. Убедитесь, что используете актуальные версии systemd, чтобы использовать все доступные обновления и улучшения.

Для наиболее оптимального SEO этот контент следует адаптировать под конкретные запросы и ключевые слова, связанные с управлением systemd и его настройками.

Оцените материал
Добавить комментарий

Капча загружается...