2

I'm trying to set up some user services using Ansible and systemd.

On Ubuntu and RHEL 7 I'm getting

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

For Ubuntu I clarified the error, it's because of this:

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

run systemctl within a given service manager scope, either as the default system scope (system), the current user's scope (user), or the scope of all users (global). For systemd to work with 'user', the executing user must have its own instance of dbus started (systemd requirement). The user dbus process is normally started during normal login, but not during the run of Ansible tasks. Otherwise you will probably get a 'Failed to connect to bus: no such file or directory' error.

Basically DBus needs to be started before systemd --user can work. I'm not sure how to do that either, but I can work around it in other ways, I think.

However, the main blocker right now is: how do I check, generically, for the availability of the functionality?

I tried systemctl show and there's no explicit "user" feature. Is the flag the "+PAM" from the Features line? I know that systemd uses PAM at least partially to implement it, I don't know if it's needed for other features.

How can I check that "my" systemd supports --user in a reliable manner? Is there a file I could check? A command? Something else? DBus voodoo?

oblio
  • 375
  • 3
  • 11

1 Answers1

0

Sadly I cannot reproduce that behaviour anymore with Ansible 2.12 on Debian 11 and I don't have other boxes right now, but my first dirty solution would be to ignore any error and register the response state and find out, what happens.

- 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"

When you run command: systemd --user status, this would give you a concrete response. But I cannot test that because of a missing failure state on Debian. Also the documentation shows an example. But at the end, I think, the systemd module implementation misses some implementation details and documentation here.

Also there is an open issue on Ansible, see https://github.com/ansible/ansible/issues/72674 It gives you some possible workarounds by forcing a lingering session.

I think that the commit above misses the point. If the user is not logged in, there is no XDG_RUNTIME_DIR to point to (the directory doesn't exist), so clarifying that it should be accessible doesn't help. As mentioned by @ikke-t, a lingering session can be forced in systemd (e.g. loginctl enable-linger ), but ansible should handle that, either automatically enabling it for these cases, or allowing for it in the systemd module (enable/disable user linger).

With ansible-manual work before calling systemd:

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