ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
825 stars 1.53k forks source link

dconf does not work with dbus-broker #495

Open fbruetting opened 4 years ago

fbruetting commented 4 years ago
SUMMARY

On systems which use dbus-broker (like Fedora Silverblue) the dconf module sadly doesn’t work.

ISSUE TYPE
COMPONENT NAME

dconf

ANSIBLE VERSION
ansible 2.9.7
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/frank/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.7.7 (default, Mar 13 2020, 10:23:39) [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)]
CONFIGURATION
OS / ENVIRONMENT

Fedora Silverblue 31 (running from out of a toolbox container, connecting to the host via ssh)

STEPS TO REPRODUCE
---
- hosts: all
  tasks:
    - name: dconf test
      dconf:
        key: '/org/gnome/desktop/wm/preferences/audible-bell'
        value: 'false'
EXPECTED RESULTS

Would be nice if it would work like on regular Fedora systems – and even if not, the check mode should also reflect those errors.

ACTUAL RESULTS

Additionally to the regular error, the check-mode just reports a change, not an error!

Gist

Related

See https://github.com/ansible/ansible/issues/59692

ansibullbot commented 4 years ago

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 4 years ago

cc @MorrisA @azaghal @bcoca @d-little @flynn1973 @gforster @kairoaraujo @marvin-sinister @mator @molekuul @ramooncamacho @wtcross click here for bot help

azaghal commented 4 years ago

Hm... So, the whole thing around the D-Bus commands was added in order to be able to detect the running D-Bus user session (its address), so that the dconf command can be executed using the same instance. Otherwise, you can end-up in situation where the application that uses dconf talks to its own user sessions, and Ansible to its own, and the changes are not synced between the two.

It turned out that the user session address is pretty much free-form (usually just pointing to a unix socket file), so I could not rely on fixed path, and had to do some testing to try to find existing session, and then if that fails run the dconf command within a D-Bus user session of its own.

@fbruetting So, the real question would be (maybe you know this already) how one finds a running D-Bus user session address with the dbus-broker? Is it fixed for each user, is it auto-spawned, can there be multiple ones for the same user etc?

@fbruetting As for the check-mode, could you perhaps split that one up into separate issue?

fbruetting commented 4 years ago

Sorry, I have absolutely no idea about how this works internally. But I can do some testing if you tell me what to do.

I covered the check-mode issue in #501.

azaghal commented 4 years ago

Ok, so I got the Fedora Silverblue running, and poked around a bit to figure out what would I need to implement to make dconf Ansible module work with dbus-broker implementation. I think it might not be possible to have a full equivalent to using the standard D-Bus implementation, unfortunately.

Replacing the dbus-send use with busctl for address verification is pretty straightforward. I think something like busctl --address=address_to_thingie emit / com.example test would work.

However, launching a D-Bus user session might not be easily feasible. And this is needed in order to launch a user session when performing a switch to another user. E.g. connect as user ansible (which will get its own user session launched), then switch via sudo become method to user johndoe (which will not get its own user session launched at this point because it's not a login session).

In case of standard D-Bus implementation, this is done via dbus-run-session command. The dbus-broker has a way to launch a session (dbus-broker-launch), but it's bound to systemd, and depends on systemd setting-up the unix socket beforehand. This has been raised on dbus-broker issue tracker as well - https://github.com/bus1/dbus-broker/issues/145.

I've seen mention of installing the dbus-daemon on Fedora 30 in that thread, but I am unsure if that could cause some kind of conflict. Doing a quick install here seems not to have impacted the system, but I did notice the gdm seems to be using the dbus-daemon binary now.

And thanks for splitting the issue - validating presence of binaries in check mode should be fixable even without the dbus-broker support. :)

russoz commented 3 years ago

hi @fbruetting ,

The module states in its docs that it relies specifically on dconf. it never claimed to work with other D-Bus implementations. This is a feature request, not a bug.

In fact, as I read thruogh, I think this should be a new module.

dvdhrm commented 2 years ago

hi @fbruetting ,

The module states in its docs that it relies specifically on dconf. it never claimed to work with other D-Bus implementations. This is a feature request, not a bug.

dconf is not a D-Bus implementation. It is a service that uses D-Bus. Can you elaborate why you think this is a feature request, not a bug? I cannot follow your reasoning, sorry.

Note that the canonical location of the user-bus socket is /run/user/<uid>/bus. All user-buses created by systemd use this location. I believe the correct solution for this module is to use this socket as primary source, unless it does not exist (why wouldn't it exist, though?).

azaghal commented 2 years ago

For start, /run/user/<uid>/bus is not a canonical location. It really boils down to what init system you might be using, and what paths the distro has decided to use. There is also plenty of ways to override what location is used for creating the socket.

And this is in many ways part of the problem - after delving into D-Bus while implementing this module, I can tell you that inability to somehow fetch information about the path to socket without knowing it beforehand is a big minus. It made implementation of this module needlessly convoluted. It is very easy to launch multiple independent user D-Bus sessions, and thus loose the benefits that D-Bus is supposed to bring. I wish that you could, for example, query the system session to get information on how to connect to user session.

Regarding your question on why the socket might not exist, this normally happens when you try to use sudo to switch to a specific user, and the user you are switching to is not logged-in. From what I could tell, most distros will create the socket and set-up user's D-Bus session only on login sessions. So, the gist of it is that you can't be 100% sure that you will find a socket and a running D-Bus session.

The dconf module tries very hard to find the socket, mind you - it even tries to scan existing processes to see if any one of them has the appropriate environment variable set (just to avoid desyncs with multiple applications using D-Bus to sync settings). But if all else fails, it tries to start its own limited-use D-Bus session. And this is where support for dbus-broker becomes problematic - it is dependent on systemd setting-up the socket, and does not provide means to launch a limited-use D-Bus session unlike the reference implementation.

As for bug vs feature question - the Ansible module was specifically written for use with reference implementation. At that time I was not even aware that there was an alternate implementation out there. Personally, I think that eventual support for dbus-broker still belongs in this module. But it will be incomplete without something like dbus-run-session binary. So you would need both dbus-broker and the reference implementation installed to make sure the dconf Ansible module behaves the same in both cases.

Anyways... The dconf Ansible module could be updated to try to cover dbus-broker implementation via dbus-send if it is present. It's been a while since I've dealt with Ansible development, though, so might take me some time to figure it out if I get back into it. And another question is whether the dbus-send and busctl are interchangeable no matter what the underlying daemon is running?

P.S. Ok, I double-checked the thread on dbus-broker issue tracker, and saw you were involved from the get-go in it, so you might find my post annoying or patronising - but it is not my intention to come off like that, I promise :) I'll still keep this answer here for completeness sake, and maybe it would help clarify some things for eventual future reader (and give some background on how the dconf Ansible module got implemented in the first place).

azaghal commented 2 years ago

Yeesh... I should really not write longs comments this late... I was pondering on removing the above comment, but I'll keep it, don't like history rewriting in discussions :)

And once again - I am interested in adding the support for dbus-broker :)

Ok, so main thing would be to add alternative command for D-Bus session validation (using busctl from dbus-broker) - then the module will hard-fail if it can't find a valid D-Bus session and if dbus-run-session is not available.

dvdhrm commented 2 years ago

Yeesh... I should really not write longs comments this late... I was pondering on removing the above comment, but I'll keep it, don't like history rewriting in discussions :)

And once again - I am interested in adding the support for dbus-broker :)

No worries!

We tried to fix most of the issues you mentioned by settling on /run/user/<uid>/bus as the canonical location. You are correct that this bus does not exist for non-login session. However, I think it would still be beneficial to try that path first, and if it does not exist keep the code you currently have.

ansibullbot commented 1 year ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help