首页 > 解决方案 > 有没有办法可靠地检查 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,可以作为默认系统范围(系统)、当前用户的范围(用户)或所有用户的范围(全局)。为了使 systemd 与“用户”一起工作,执行用户必须启动自己的 dbus 实例(systemd 要求)。用户 dbus 进程通常在正常登录期间启动,但不会在 Ansible 任务运行期间启动。否则,您可能会收到“无法连接到总线:没有这样的文件或目录”错误。

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

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

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

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

标签: linuxansiblesystemddbus

解决方案


这与 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:
    user: yes
    daemon_reload: yes
    name: the_service.service
    enabled: yes
    state: started

推荐阅读