Есть ли способ надежно проверить, поддерживает ли systemd --user?

Есть ли способ надежно проверить, поддерживает ли systemd --user?

Я пытаюсь настроить некоторые пользовательские службы с помощью Ansible и systemd.

В Ubuntu и RHEL 7 я получаю

# systemctl --user status
Failed to get D-Bus connection: Connection refused

Для Ubuntu я уточнил ошибку, она возникает из-за этого:

https://docs.ansible.com/ansible/latest/modules/systemd_module.html

запустить systemctl в заданной области действия менеджера служб, либо как область действия системы по умолчанию (system), область действия текущего пользователя (user) или область действия всех пользователей (global). Чтобы systemd работал с 'user', у исполняющего пользователя должен быть запущен собственный экземпляр dbus (требование systemd). Процесс dbus пользователя обычно запускается во время обычного входа в систему, но не во время выполнения задач Ansible. В противном случае вы, вероятно, получите ошибку 'Failed to connect to bus: no such file or directory'.

По сути, DBus нужно запустить, прежде чем systemd --userон сможет работать. Я тоже не уверен, как это сделать, но я думаю, что это можно обойти другими способами.

Однако сейчас главный блокировщик: как вообще проверить доступность функционала?

Я пробовал systemctl show, но явной "пользовательской" функции нет. Флаг "+PAM" из строки Features? Я знаю, что systemd использует PAM по крайней мере частично для ее реализации, не знаю, нужна ли она для других функций.

Как мне проверить, что "мой" systemd поддерживает --userнадежным образом? Есть ли файл, который я могу проверить? Команда? Что-то еще? DBus voodoo?

решение1

К сожалению, я больше не могу воспроизвести это поведение с Ansible 2.12 на Debian 11, и у меня сейчас нет других машин, но моим первым грязным решением было бы игнорировать любые ошибки, регистрировать состояние ответа и выяснять, что происходит.

- name: "Check, if user can handle user property"
  ansible.builtin.systemd:
    state: "started"
    name: "crond"
    scope: "user"
  ignore_errors: true
  changed_when: false
  register: systemd_status

- name: "Output status for debugging"
  ansible.builtin.debug:
    msg: "{{ systemd_status }}"
  when:
    - "systemd_status.failed | bool"

Когда вы запустите command: systemd --user status, это даст вам конкретный ответ. Но я не могу это проверить из-за отсутствия состояния отказа в Debian. Также в документации показан пример. Но в конце, я думаю, в реализации модуля systemd отсутствуют некоторые детали реализации и документация здесь.

Также есть открытая проблема на Ansible, см.https://github.com/ansible/ansible/issues/72674Он дает вам несколько возможных обходных путей, принудительно затягивая сеанс.

Я думаю, что коммит выше не соответствует сути. Если пользователь не вошел в систему, XDG_RUNTIME_DIR не указывает на (каталог не существует), поэтому разъяснение того, что он должен быть доступен, не помогает. Как упомянул @ikke-t, затяжной сеанс может быть принудительно включен в systemd (например, loginctl enable-linger ), но ansible должен это обработать, либо автоматически включив его для таких случаев, либо разрешив его в модуле systemd (включить/отключить задержку пользователя).

С помощью ansible-manual перед вызовом systemd:

- name: Ensure lingering enabled
  ansible.builtin.command: "loginctl enable-linger {{ user }}"
    creates: /var/lib/systemd/linger/{{ user }}

Связанный контент