Interface management


#3

It is important to note that ‘interface’ here is a snapd term, not to be confused with Application Programming Interfaces (APIs), Application Binary Interfaces (ABIs), DBus interfaces, etc. Your snapcraft.yaml/snap.yaml declares the snapd interfaces that your snap needs to use relevant programming interfaces for the resource. In your case, you declare ‘plugs: [x11]’ and then you are allowed to talk to the X server using the raw X protocol or any other higher level abstractions (eg, windowing toolkits like gtk, qt, etc).


#4

Ok interesting, that is a little different than what I had expected. Doesn’t that leave the Snaps in the position of needing knowledge of the systems they’re deploying to? For example if I have a Snap that is requesting :network-setup-control don’t I need to know what network manager is installed?

Also, are there any good resources on writing against Snap interfaces for developers? This is pretty much the only link I can find and it’s hard to understand what exactly is being opened up when an app is connected to an interface.


#5

Interfaces can be thought of as contracts between the slot side (the provider, sometimes its a service) and the plug side (the consumer). On an all-snaps system like Ubuntu Core, the snap executes in a predictable runtime where snapd exposes so-called ‘implicit slots’. Other slots are provided by app snaps (eg, a network-manager snap). In this manner, you only have to know what the slot implementation provides. It would be considered a bug in a providing snap to drop APIs, etc or otherwise break consuming snaps.

For so-called classic distributions where snaps are installed alongside debs/rpms, the above mostly holds true for strict and devmode snaps, though, yes, it is true that Fedora and Ubuntu might ship different network-managers as part of the system. Typically there isn’t a tight coupling between the client libraries and services (indeed, libraries like Qt have abstractions you program to and they figure out which network-manager DBus APIs are available), but where there is a tight coupling, the snap would have to account for that.

For ‘classic snaps’ which have no confinement and can access anything on the system directly, it is up to the snap publisher to account for any difference across distributions (which is made is by using libraries like the aforementioned Qt with network-manager).


/usr/bin/fold got permission denied but /usr/bin/fmt is working fine. What's happened?
#6

I’ll defer to the snap advocacy team here (@evan, @Wimpress and @popey) but can say you can look at the snapd source code for the latest on what is allowed: https://github.com/snapcore/snapd/tree/master/interfaces/builtin


#7

Ah ok actually that source is very helpful. So for the network_setup_control interface, it’s actually operated by files using netplan. And I guess network_bind operates by allowing system calls to accept/bind/listen? That seems doable.

https://netplan.io/

Our current installation script uses authbind though. So much to learn. I’ll save it all for another thread though. It looks like the source is the place to go for good dev details on interfaces now.


#8

Is it possible for a launcher (preferably, a shell script) to detect whether a certain interface is connected to a snap without detecting AppArmor denials?


#9

You could try:

#!/bin/sh

usage() {
    echo "Usage: check-plug <snap name> <interface name>"
    exit
}

if [ -z "$1" -o -z "$2" ]; then
    usage
fi

SNAPNAME="$1"
INTERFACE="$2"

if snap interface "$INTERFACE" | sed -e '1,/plugs:/d' | sed -e '/slots:/,$d' | awk '{print $2}' | grep "^$SNAPNAME\$" >/dev/null; then
    echo connected
else
    echo not connected
fi

Edit: Just spotted that you want this inside the snap. I don’t know if that data is exposed to the application in a snap… I just checked snapctl, which doesn’t appear to expose the info, so you cannot do it through that.


#10

Thanks for the info.


#11

indeed you dont really need to “detect denials” but just check if you have the expected access to a file, device or whatever the interface normally provides.

#! /bin/sh

[ -r "/var/log/syslog" ] || echo "please connect log-observe !!"

#12

I would like to found out how to assert plugs/slots and plugs & slots with attributes in this topic.


#13

This topic used to have all the undocumented and new interfaces which are not yet updated in https://docs.snapcraft.io/reference/interfaces . I see they are no longer available here as well. Could you please add a link where we can find the updated interfaces list ?


#14

We’re currently working on the Interfaces pages and we’ll definitely be adding the interface list back (likely today), along with a reference to each interface. Sorry this isn’t clear - when something like this affects the docs again, I’ll leave a ‘Work in progress’ note with an explanation.


#15

The interface section is still not available. When can we expect it to be back ?


#16

Have you seen Supported interfaces? It should include all the details there were previously in this topic, but let me know if there’s something missing.


#17

Still broken here (18.04 LTS). The above steps do not resolve it.

The snap was ‘postman’ and my home folder is /home/local/SOMETHING/myname


#18

So this page doesn’t seem to teach you how to add interfaces to your snapcraft file, and neither does:
https://docs.snapcraft.io/supported-interfaces/7744

The latter tells you what interfaces are supported, but neither of these docs seem to be linking me towards, as an author, how to do a strict mode snap and have it request interfaces.

The Go examples are both “devmode” snaps, and thus don’t do confinement (AFAICT).

Some of that seems to be described in:
https://docs.snapcraft.io/the-snap-format/698

but if you just start with “Creating a Snap” it seems to direct you immediately to the language-specific details, which at least for the Go ones, doesn’t direct you back.


#19

We’re missing a huge chunk of the snapcraft lifecycle, including installation (in a central place), command syntax, confinement, adding interfaces, using plugins, tracking down dependencies, build override examples, scriptlets, troubleshooting and publishing.

All of the above are high priority (and what I’m currently working on), so we’ll have something published on here soon.


#20

As a snap package creator, I am interested in what precisely a particular interface provides, in technical terms. Some interfaces are pretty intuitive, like ‘home’. Some others are rather obscure: for example, what precisely does plugging into ‘avahi-control’ enable? How exactly does it affect my C program which uses the avahi-client library? And If I want to provide a slot for an interface, what precisely must I do in my snap?

I assume it ultimately all comes down to the basic Linux kernel and IPC interfaces: files, system calls, etc. It would be helpful if the interfaces were described in terms of those primitives. Given that there is just a few of those basic primitives, I also wonder why there are very specific interfaces such as ‘avahi-control’? Why is something related to an application like Avahi part of the basic snap system? Would it make sense for any snap other than ‘avahi’ to provide the avahi-related slots? What happens if multiple snaps provide this slot? As another example, the ‘docker’ interface begs the same questions.

Furthermore, if the interfaces are intended to be so application specific, then it seems essential for a snap application developer or an embedded system developer to also be able to implement their own interfaces, without hacking the snap system itself. Is that possible or is it part of the vision?


#21

This does not seem right. Which is the previous output? Things do not match with the previous output. Perhaps something was moved round?


#22

You’re absolutely right! Thanks for mentioning this. snap connections has a different output, but we didn’t change the text to explain this. I’ll fix it now.