Preparing the interfaces logic for connection hooks

As part of the work on interface connection hooks that is coming for a long while now, we’ve been trying to adapt the existing logic that we have today in our interfaces repository abstraction to something that will support the new logic well. Instead of piling up more and more hacks on it, we’ve agreed it’s time to refactor it and make its API more in line with the work that has happened since it was first conceived.

The fundamental mismatch between its current implementation and the new world is that the current repository was designed to be a stateless representation of the connections in the system, and the new world requires connections to be first-class stateful entities that hold dynamic attributes that can be modified by snap hooks.

So, after a couple of calls in the last few days, we decided to fix the situation as follows. The order is the one suggested for implementation too, hopefully doable in smaller and easier changes:

  1. Move interface sanitization routine to the very early loading of snaps, so that every single PlugInfo and SlotInfo in memory is guaranteed to be clean and ready. This will require a local callback in the snap package to avoid cycles.
  2. Introduce interfaces.plugRef/slotRef helpers that return a PlugRef/SlotRef when given a PlugInfo/SlotInfo; that may go away eventually, but will ease the transition
  3. Drop use of interfaces.Plug and Slot entirely in the interface repository, replacing them by their underlying PlugInfo and SlotInfo
  4. Move any remaining logic that depends on the serialization of Plug and Slot to the daemon package
  5. Introduce interfaces.Connection, ConnectedPlug, and ConnectedSlot types. These reference each other and can only ever be observed together.
  6. Change the repository code and make all established connections use Connection/ConnectedPlug/ConnectedSlot as a unique value with a persistent identity throughout the whole system
  7. Change all interface code to use ConnectedPlug/ConnectedSlot on the dynamic methods, and to use PlugInfo/SlotInfo on permanent methods

There will certainly be some more details to figure, but that’s the high-level idea. If successful, by the end of this process we’ll have in the Connection and Connected* types an obvious place to hold the persistent data that associated with dynamic attributes provided by hooks.

So that’s the idea. Please let me know if this captures the idea we discussed well.

2 Likes

I think this matches the discussion and my understanding.

PR adressing #1: https://github.com/snapcore/snapd/pull/3972

Two more PRs: https://github.com/snapcore/snapd/pull/4007 and https://github.com/snapcore/snapd/pull/4013 (more are ready but I will propose them after the ones above land, otherwise diffs will be too big).