Interface connection from gadget in firstboot

upcoming
pedronis
2_34

#1

During the most recent fact to face meeting the topic of connecting plugs/slots on firstboot came up. The feedback we got was that its an important feature.

As a strawman here is a proposal how to do it. In the gadget.yaml we add a new connect: key:

connect:
 - <snap-id>:<plug> <snap-id>:<slot>
 ...

For the implementations we have some options. The most simple one would be a task that runs as part of firstboot that simply does the connections. The downside of this is that the hooks will not be connected when they run and that subsequent install/remove will not take the connections into account (which may not be bad, depending on what we want).


How to preconfigure custom image?
How to preconfigure custom image?
#2

it’s slightly strange if this uses snap names while defaults uses snap-ids atm


#3

@pedronis yeah, I agree - let me change the proposal


#4

yes, I see two main approaches:

  • add tasks to first boot/seeding change
  • store the info so that can be used close to the auto-connect logic, in that case approach would let specify connections for things that might be installed later OTOH we might not need/want to that

#5

I like option (1) slightly better, however it depends on the exact semantic we want. In my mind this is about firstboot only. If OTOH we want this to also apply to installs that happen after firstboot, then the second approach is the better one of course.


#6

ISTR when the feature was discussed ages ago, the gadget was supposed to have a say in auto-connections at snap install, not just pre-installs. This makes some sense if you consider a model that has several snaps preinstalled, but additional snaps can be installed (perhaps purchasable) later to extend the device. The gadget developer may want to auto-connect some of these.


#7

@mvo has there been any progress on this topic?
Otherwise I agree with @jdstrand this should be more universal, not just at first boot. It should accommodate snap to be installed in the future, and ideally also accommodate gadget snap update for already installed snaps, so rules can be updated as snaps evolve.


#8

having it for pre-installed snaps in firstboot (i.e. for required-snaps from the model assertion) would already be immensely helpful for several customer projects though …


#9

Just wanted to check the status of this? Would be great to have it for our use-case also.

Also a slightly n00b question regarding the suggested approach: If I wanted to add the “connect” key to my gadget snap’s snapcraft.yaml file, in order to connect a plug to a slot provided by the gadget itself, how would I go about finding out the yet-to-be-built gadget’s snap-id? Would this auto-connection approach only work for gadget snaps that were pushed to the store (and have their snap ID listed there), or would there be a way to do it for snaps that were built locally (where they’re for example used in a device image)?


#10

In the meantime, I came up with a workaround for this via systemd that is so inelegant that it will presumably irritate someone else into implementing the proper way of handling this :wink:

(In the image file tree, create a system-data/etc/systemd/system/connector.service that contains any required ExecStart=/usr/bin/snap connect <...> statements in “oneshot” mode. Then enable the service to start on boot by putting a symlink to the file in in system-data/etc/systemd/system/multi-user.target.wants. Probably overkill to run on each boot, but in the absence of other alternatives it seems to do the trick.)


#11

I think whatever we do we should still, in principle, respect the connection rules from the snap-declarations of the involved snaps.


#12

Collecting some discussion input here about use cases:

  • Typically this is interesting for slots provided by the gadget itself, if one goes looking for interfaces that can have slots provided by a gadget we encounters things like serial-port etc., where auto-connection alone is not enough because there might be usually many candidates plugs and slots.
  • The application requiring those slots might come with the device originally or not (it might enable some important functionality but might not have been available when the device first shipped, it might be an add-on).
  • For an interface like camera provided by core and where auto-connection is not allowed by default, auto-connecting via the a declaration is a viable path as long as the application comes from a store controlled by the gadget/device publisher. it is not a viable path if the application is more generic and comes from a store to which they have access but don’t control (like the global store).

It’s important to note that for an appliance kind of device (no user usually present to trigger snapd actions):
snaps either come via seeding, or there is a snap with snapd-control that can install further snaps and so in in principle could do connections too.

With these considerations it seems there are two related areas to address:

  • the gadget should be able to define connections between snaps that comes with the model (naively this means at seeding but see 2nd point)
  • we need to explore ways to update the model assertion of a gadget to a new revision, and carry out any reasonable effect of that, like installing further required snaps (what about removing?)
  • unless we specify the connections in the model assertions, not the gadget (that doesn’t seem appropriate though), such model revision update would need to be potentially in sync with a gadget update; one approach would be to have a trigger for the model revision update from the gadgets

#13

@pedronis pushed a preliminary PR here:

We’ve also just had a quick call to discuss this, and agreed to tweak the syntax slightly to something along those lines:

connections:
  - plug: snapid1:plg1
    slot: snapid2:slot
  - plug: snapid3:process-control
  - plug: snapid4:pctl4
    slot: system:process-control
  - plug: snapid5:pctl5
    slot: system:process-control

Rationale for “connections” is that the other options we have there are also plural nouns (defaults, volumes), and the more verbose syntax is both more symmetric and allows us to extend individual connections with further options if we have to (we might want an option to drop the otherwise established automatic connection, for example).


#14

https://github.com/snapcore/snapd/pull/5221 is now updated


#15

Proposed now:

that actually performs the connections (but ignores missing snaps/slots/plugs while logging them) at first boot.