Support for "daemon: dbus"?


#1

Recently, I’ve been working on adding support for bus activated D-Bus services, and noticed that the existing systemd code supported dbus as a daemon type.

This generates a systemd .service file using Type=dbus, where the service is considered to have finished starting when it registers a particular well known name on the message bus. I imagine this is the mode most snapped D-Bus services would want to use.

However, Snapcraft complains that dbus is not a valid value for the daemon attribute on an app. I was able to build a snap using passthrough with something like this:

apps:
  system:
    command: ...
    passthrough:
      daemon: dbus
      bus-name: io.snapcraft.SnapDbusService

This produced a working snap with the right mode in the systemd unit, but it looks like review-tools also trips up on dbus type daemons:

$ review-tools.snap-review test-snapd-dbus-service_1.0_amd64.snap 
Errors
------
...
 - lint-snap-v2:daemon:system
    invalid daemon: 'dbus'
Warnings
--------
 - lint-snap-v2:apps_unknown:system
    unknown fields for app 'system': 'bus-name'

Is this just an oversight, or is there a particular reason to discourage use of this daemon type?


#2

This used to be supported by the review-tools but almost two years ago it was removed because it was not properly supported in snapd. This is bug https://bugs.launchpad.net/snappy/+bug/1649399. If ‘daemon: dbus’ is now properly supported in snapd, happy to add it back to the review-tools.


#3

It certainly seems to be working in current snapd master, but I guess it is worth discussing whether it’s a syntax we want to keep and/or encourage the use of. As I’ve been working on D-Bus service activation, here are a few points to keep in mind:

  1. A daemon must be able to acquire the bus name systemd is using to check that the daemon is active. If we’re only considering strict confinement, then this means the daemon must have a dbus slot matching the bus name. With classic snaps, it is quite possible for a daemon to register a name without a matching slot (although with installation of service activation files tied to the interface, they probably want one anyway).

  2. If a daemon is an activatable dbus service, then the dbus daemon type is the most appropriate method to signal that it is active. If the daemon doesn’t claim the name then it is obviously broken, and once it does claim the name it needs to be able to serve requests from clients.

  3. A daemon can potentially claim multiple bus names. It should be considered active only once it owns both names. In general, this means bus-name should be the last name it tries to claim.

    As an example close to home, snap userd tries to register both io.snapcraft.Launcher and io.snapcraft.Settings. By inspecting the source code I can see that it registers io.snapcraft.Settings last, so that is the name systemd should be watching for.

For simple cases it might be possible to infer the details, but (3) requires knowledge of how the daemon initialises itself. So maybe the existing syntax is good enough and just needs to be supplemented with review-tools checks. The following might be a good start:

  1. If a snap is using strict confinement and has an app with daemon: dbus, then bus-name must match one of the app’s dbus interface slots.
  2. If an app is a system daemon, then it should not have any dbus interface slots that specify bus: session.
  3. Once my user daemons PR is merged, any app that is a user daemon must not have any dbus interface slots that specify bus: system.
  4. If an app has a dbus interface slot with activatable: true, and sets daemon: simple then issue a warning suggesting that they use daemon: dbus.