How do you configure multiple slots to auto-connect to a single plug?

Hello :wave:

I work at EFF and am trying to understand something about the Certbot snaps we recently created.

In the base Certbot snap, we define a content interface plug like:

    interface: content
    content: certbot-1
    target: $SNAP/certbot-plugin

We then created many additional snaps for features one can add to Certbot (such as certbot-dns-cloudflare) which defines the slot for this interface like:

    interface: content
    content: certbot-1
      - $SNAP/lib/python3.8/site-packages

In case it is useful, the full snapcraft.yml files for these snaps are here and here respectively.

Once publishing these snaps to the snap store, we were surprised to find that when you install multiple snaps that have slots for the plug in the base Certbot snap, only the first auto-connects. For instance:

$ sudo snap install --edge --classic certbot
certbot (edge) 1.6.0-21-g086c8b1b3 from Certbot Project (certbot-eff✓) installed
$ sudo snap set certbot trust-plugin-with-root=ok
$ sudo snap install --edge certbot-dns-luadns
certbot-dns-luadns (edge) 1.7.0.dev0 from Certbot Project (certbot-eff✓) installed
$ sudo snap set certbot trust-plugin-with-root=ok
$ sudo snap install --edge certbot-dns-digitalocean
certbot-dns-digitalocean (edge) 1.7.0.dev0 from Certbot Project (certbot-eff✓) installed
$ sudo snap connections
Interface            Plug                                       Slot                        Notes
content[certbot-1]   certbot:plugin                             certbot-dns-luadns:certbot  -

(The command sudo snap set certbot trust-plugin-with-root=ok is needed for the prepare-plug-plugin hook in base Certbot snap to allow the slot to connect which is an implementation detail discussed at Certbot: request for classic snap approval - #19 by jdstrand if you’re curious.)

My question is is it expected behavior for only the first slot to auto-connect? The best documentation I could find about this is Plug/slot declaration rules: greedy plugs, but I didn’t fully understand the post.

Is it possible to change this behavior and how do we go about doing so? Is it something we’d need to open a store-requests post about? Is the only implication of that change in our case that all slots for this interface also published by us will auto-connect like we initially anticipated?

Thanks for any help clarifying my understanding here!

certbot is a classic snap … unless something drastically changed recently, classic snaps can neither use nor provide interfaces by design … you’d have to make certbot a strict snap first to have it provide any interface slots …

At least in our case, that seems incorrect because the slot in the first strictly confined snap auto-connects to the Certbot plug as shown in the terminal output above and we have other content interfaces on these same snaps which auto-connect.

so perhaps “something drastically changed recently” then :slight_smile: (and i missed it) …

someone from the snapd team should chime in if that is true …

EDIT: on a sidenote, independent of that classic issue, the default-provider line in a content snap declaration should make the consumer snaps auto-connect as long as the snaps all come from the same publisher

You might need to request a greedy plug declaration for this. Greedy plugs auto-connect to all matching candidates. Regular auto-connections only connect to the first one.

Is there official documentation on this anywhere? Part of the problem we had was just understanding if this was expected behavior or if there was something misconfigured in our snaps.

Discourse edited my post making this less clear, but my question was in response to what galgalesh said about plugs only auto-connecting to the first matching candidate by default.

The best documentation about this is Greedy Plugs. As you said yourself, this is not the most clear documentation because it includes some information for the people creating declarations (snap store staff) and some info for developers creating snaps.

I’m wondering what the best place is to put this information. The only place I can find information about auto-connections is the interface management page, but that page is aimed towards users, not developers/publishers. Maybe we should just create a page about auto-connections specifically tailored towards publishers? Which contains info about the regular behavior + greedy plugs.

Edit: Another possibility is to include an “auto-connections” section to the Adding interfaces page meant for developers. What do you think would work best, @bmw?

well, how many snaps do you expect to provide the certbot slot ?

while this is indeed useful info, as i understood you will only have one snap providing the slot (certbot) and a few app snaps consuming it via plugs…

It is indeed tricky where to put this information.

For what it’s worth, I think we probably had the expectation that everything would auto-connect based on which says snaps from the same publisher will auto-connect without mentioning any caveats and later talks about how having multiple slots connected to the same plug is supported. Clarifying this across all interface docs is a lot of work though and may not even be desired to have all docs get bogged down in the details of that.

I think the biggest thing though is just having some some documentation somewhere aimed at developers/publishers of snaps that this is the expected, default behavior and ideally what your options for changing it are. I had to do a fair bit of searching before I came across Plug/slot declaration rules: greedy plugs and like I said, I struggled to understand it at least partially because I wasn’t the target audience.

You have that backwards. If you read my initial post again, you’ll see that the Certbot snap has the plug and is consuming the extra features added by many different slots.

I’ll look into making a store-requests post to change the behavior of the Certbot snap.