While fixing some recent issues with duplicate plugs/slots on the core snap we realized the algorithm for auto-connection is naive and can easily be incorrect.
Currently a connection between a plug and a slot, or slot and a plug, is made only if at the time of installation there’s exactly one candidate available to satisfy the connection and the assertion system and the interface itself allows this to happen. We can see why this is incorrect for slots. Typically slots are 1-to-N (e.g. the network slot) so one slot can be paired to many plugs at the same time.
Depending on the nature of the interface we should be more generic. E.g. installing a snap with shared runtime (e.g. java or qt) should connect to all otherwise unconnected snaps that can use such runtime. On the other hand installing an application while having two possible runtimes should not connect both runtimes. I’m sure there are more interesting examples we can make.
I think that we need a way to model this behaviour in the interface code itself, so that it can make useful suggestions to the core, during auto-connection analysis.
We should make the obvious cases work well before worrying about rare ones. In particular:
That’s a pretty obvious bug which needs to be fixed. If there’s an allowed auto-connection which may be established with the core snap, the code should just do it, ignoring any duplicates elsewhere.
If there are duplicates elsewhere in other snaps, we can hold back for now and not connect, waiting for it to be manually established. This gives us room to implement the right behavior in the near future without breaking compatibility. We’ll likely need to support some additional metadata in the interfaces since there’s more than one right answer.
Is there any other case that needs to be fixed right now?
In the screenly-client snap we have two plugs for the one udisks2:service slot and we’re getting
auto connect udisks2:service (slot auto-connection), candidates found: "screenly-client:udisks2, udisks2:client"
In this particular case we want both of them to connect to the slot.
In the other situation - we have three dbus slots and three dbus plugs, and each plug should be connected to its own slot. Currently, the system tries to connect to all of them and we’re getting the error message:
auto connect screenly-client:command-dbus-client (plug auto-connection), candidates found: "screenly-client:command-dbus-server, screenly-client:ping-dbus-server, screenly-client:playlist-dbus-server"
Is would be nice to have a way to select target slots for plugs in the snapcraft.yaml or in the snap’s declaration.
While I agree with this idea, we need to make sure that certain things are not auto-connected to more than one consumer. From the top of my head are the GPIOs and serial ports but I bet more will follow. Those are really 1-to-1 interfaces. Some are only such logically and it might be possible to have multiple connections (but I’d make it so it requires explicit connection) and others are really single use (e.g. a file is open by a process and other processes will not be allowed).
We need to extend the language so we can express these cases. Meanwhile, we may simply not auto-connect. GPIO and serial ports are both examples of things that are too general for them to be auto-connected in a sensible way.
There’s a snap hosted in the branded store which specifies the qualified (ie. named) gpio plugs it uses in its snapcraft.yaml. This snap is the only snap hosted in the branded store that uses the gadget slots involved. The expectation was that when the snap gets installed, all of these connections happen automatically.
I’d been working with @pedronis and @jdstrand on adjustments to the snap-declarations of both the client snap, and the gadget snap to get this to work, but so far to date we’ve been unsuccessful. At this point, the only snap-declaration change that is live, is a Slots stanza for the gadget snap which grants permission to the client snap: