Я пытаюсь настроить некоторые пользовательские службы с помощью 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 }}