有没有办法可靠地检查 systemd 是否支持 --user?

obl*_*lio 1 linux dbus systemd ansible

我正在尝试使用 Ansible 和 systemd 设置一些用户服务。

在 Ubuntu 和 RHEL 7 上我得到

# systemctl --user status
Failed to get D-Bus connection: Connection refused
Run Code Online (Sandbox Code Playgroud)

对于Ubuntu我澄清了这个错误,这是因为:

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

在给定的服务管理器作用域内运行 systemctl,可以是默认系统作用域 (system)、当前用户作用域 (user) 或所有用户作用域 (global)。为了使 systemd 能够与“用户”一起工作,执行用户必须启动自己的 dbus 实例(systemd 要求)。用户 dbus 进程通常在正常登录期间启动,但在 Ansible 任务运行期间不会启动。否则,您可能会收到“无法连接到总线:没有此类文件或目录”错误。

基本上DBus需要启动才能systemd --user工作。我也不知道该怎么做,但我想我可以通过其他方式解决这个问题。

然而,现在的主要障碍是:一般来说,我如何检查功能的可用性?

我尝试过systemctl show,没有明确的“用户”功能。标志是Features行中的“+PAM”吗?我知道 systemd 至少部分使用 PAM 来实现它,我不知道其他功能是否需要它。

如何检查“我的”systemd 是否--user以可靠的方式支持?有我可以检查的文件吗?命令?还有别的事吗?DBus巫毒?

Tho*_*mas 5

这不是 systemd 是否支持 (所有相当新的版本都支持)的问题--user,而是 (a) 用户会话当前是否正在运行,以及 (b) 您的 Ansible 进程是否可以连接到它的问题。

这两个问题的解决方案是become_method: machinectl(请参阅Ansible 文档),但它在某些 systemd 版本上存在问题。


如果该方法不适合您,还有一些解决方法。通常,Ansible 会话不会创建用户 systemd 实例;您需要在本地登录才能发生这种情况。但是,您可以启用延迟以始终为该用户提供 systemd。

第二个问题是连接到该实例。这需要XDG_RUNTIME_DIR设置环境变量;通常到/run/user/<UID>. 它不是由通常设置的become_method: sudo,但您可以使用以下内容来计算它并将其传递给任务systemd

- name: "Find uid of user"
  command: "id -u {{ the_user }}"
  register: the_user_uid
  check_mode: no # Run even in check mode, otherwise the playbook fails with --check.
  changed_when: false

- name: "Determine XDG_RUNTIME_DIR"
  set_fact:
    xdg_runtime_dir: "/run/user/{{ the_user_uid.stdout }}"
  changed_when: false

- name: "Enable some service"
  become: true
  become_user: "{{ the_user }}"
  environment:
    XDG_RUNTIME_DIR: "{{ xdg_runtime_dir }}"
  systemd:
    scope: user
    daemon_reload: yes
    name: the_service.service
    enabled: yes
    state: started
Run Code Online (Sandbox Code Playgroud)