Should /v2/interfaces?select=connected return unconnected plugs/slots?

For a feature I’m working on, I needed to check whether a particular named snap was plugged into a particular interface type, which means hitting the /v2/interfaces REST API.

Looking at the code, this endpoint can produce two forms of data:

  1. the getLegacyConnections mode where it produces information about every connected interface on the system. This is what snap interfaces uses.
  2. the getInterfaces mode, which produces information in a slightly different format and supports filtering the data. This is what snap interface uses.

Minimising the data I need to parse and filter seemed like a good idea, and looking at the Go client’s InterfaceOptions struct, it looked like I’d want to pass the following query parameters:

  • names=$type to restrict the output to the particular interface type I’m interested in.
  • plugs=true to return plugs associated with the selected interface type(s).
  • select=connected to restrict the output to connected interfaces.

However, this last option didn’t quite do what I expected. I had hoped that it would limit the output to connected plugs/slots. But it seems that if an interface type has at least one connected plug/slot, then all associated plugs/slots are returned with no way to distinguish the state.

For example, using the current stable release (2.33.1):

$ curl --unix-socket /run/snapd.socket 'http://foo/v2/interfaces?names=removable-media&plugs=true&select=connected' | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   329  100   329    0     0   321k      0 --:--:-- --:--:-- --:--:--  321k
{
  "type": "sync",
  "status-code": 200,
  "status": "OK",
  "result": [
    {
      "name": "removable-media",
      "summary": "allows access to mounted removable storage",
      "plugs": [
        {
          "snap": "firefox",
          "plug": "removable-media"
        },
        {
          "snap": "hugo",
          "plug": "removable-media"
        },
        {
          "snap": "keepassxc",
          "plug": "removable-media"
        },
        {
          "snap": "libreoffice",
          "plug": "removable-media"
        }
      ]
    }
  ]
}

… only keepassxc and libreoffice are connected with the other two disconnected.

Is this intended behaviour? I can’t think of a case where this behaviour would be particularly useful, but maybe I’m not imaginative enough :slight_smile:

Also, if one output mode is referred to as getLegacyConnections, should it be considered a bug that you can’t get the equivalent information from the non-legacy interface?

We discussed this briefly on IRC and the summary is:

  • we have a legacy connection-oriented API
  • we have a non-legacy interface (not plug or slot) oriented API with server-side filtering
  • we don’t have a non-legacy connection-oriented API with server-side filtering but want one

As a quick workaround for the lack of that we could use the legacy API and filter client side.

Here are a few ideas for the types of filtering that would be useful:

  1. (my current use case) a trusted helper wants to find out if snap A has a connected plug of interface type X. This is for cases where parts of the confinement policy can not be expressed through AppArmor or seccomp rules but needs some other trusted service to make a decision.

    Examples include Pulse Audio restricting microphone access to some confined apps, and xdg-desktop-portal restricting network connectivity information to snaps with network access.

  2. Information about all plugs/slots of a particular snap, along with their connection state. This seems like what gnome-software’s interface connection UI would need.

  1. feels like the connection-oriented API we don’t have one, we can then limit the scope to snap name and interface type to get a yes-or-no (not empty or empty) answer

  2. feels like something that ought to grow out of the snap specific Queries (extended form of snap info) CC @chipaca for his opinion.

Expanding on use case (2), it might be useful to be able to request the following:

  1. a list of all plugs for a particular snap.
  2. for each of those plugs, a list of all candidate slots it can connect to.
  3. the “connected” state for each of those slots.

While simply listing all slots of the matching interface type is enough for many interfaces, ones like content and dbus are more complicated. Rather than building special knowledge of them into API clients, it seems sensible for snapd to export its view of the connectability.

1 Like