The content interface

Content moved out of the wiki.

The enhancements implemented in Improvements in the content interface are not documented here yet (cc @zyga-snapd).

2 Likes

Thank you for sharing this! One note: on recent builds this does not appear to work unless

interface: content

is also specified alongside the content: xxx directive. Without this attempting to publish a snap throws errors such as

Error: interface '_slot_name_' not found in base declaration
Error: unknown interface '_slot_name_'

(in this case I was building against a core18 base; maybe there’s been a change since 16)

As far as I know that should have never worked, a plug has an interface type of _slot_name_ unless it specifies "interface". So the examples here all need fixes. cc @degville @zyga-snapd

1 Like

I fixed the examples and added the ‘interface’ attribute at the top. @degville, please feel free to adjust as necessary.

The attribute description for default-provider has now been corrected but has been for long:

In practice snapd has always ignored and still does the :<SLOT> part. The connection between the snap and its default provider will depend only and entirely on the general auto connection mechanism. The reason for doing this in the actual implementation is avoiding tight coupling between snaps, as was explained also in this old comment.

1 Like

I have a few questions about socket-directories using the content interface.

I have one snap that provides a socket-directory slot https://paste.ubuntu.com/p/N7wchfdYhM/.

The socket that the munge process creates here https://paste.ubuntu.com/p/FwvQ7JQNZw/ in SNAP_DATA.

I create another snap to test with munger https://paste.ubuntu.com/p/GtxZkyy9Dq/ which provides the plug.

I install both of the snaps and connect the content interface plug of one to the content-interface slot of the other https://paste.ubuntu.com/p/qhrQQGKFq3/.

Once both the snaps are connected, I can see the socket in the munge snap that creates it, but I can’t see the socket in SNAP_DATA of the snap that has the consuming plug https://paste.ubuntu.com/p/6tJPVs7x9s/

My question is, should I be able to ls SNAP_DATA and see the socket in both of the snaps?

Thanks!

EDIT: It seems that even though I can’t see the socket in the consuming snap, the process can see it. Given this, I feel that my socket-directory slot and plug are working as expected, its just seems difficult to verify this from the user perspective.

I’m experiencing an odd glitch when trying to set up a content slot on a newly built snap, according to the above instructions (which have worked for me previously). Issue is described here: Can't connect to content slot, since "content" directive somehow gets dropped from snapcraft.yaml.

Haven’t had any responses to that original post, and this has turned into a bit of a blocking issue, so I figured I’d drop a note here in case there are any ideas.

@jamesbeedy I know you posed your question a while ago and mostly self-answered it, but I figured I’d add my $0.02. Indeed, if you are just browsing your filesystem you will not see the content of mounted content plugs. So for example

$ ls /var/snap/my-snap/current/slot-content

will return nothing, even if there’s something mounted there. To look at the contents, you can drop into the snap’s shell environment by doing

sudo snap run --shell my-snap.my-command

Then you should be able to see the mounted contents

# ls $SNAP_DATA/slot-content
socket

I’m not 100% sure if this applies for all types of content, but it does seem to be the case for socket files at least.

1 Like

should be “provides” right? Just a simple error.

Corrected, thanks! :slight_smile:

I wonder if we should list common content snaps here…

1 Like

I think it could be useful

1 Like

Hi @mapero, I recommend creating a new topic for your question. This discussion is maily for talking about the docs. Also, creating a new topic, your issue will have far more visibility :wink:

1 Like

Edit: Apparently I had edit permissions, so this has now been fixed.

The example under Using source has a slight error in it:

slots:
  _slot_name_:
    interface: content
    content: executables
-     source:
+    source:
       read: 
         - $SNAP/bin
1 Like

Great spot, thanks for the comment and updating the doc!

Should that say “should”, or should it say “must”? What other directories are eligible for sharing with a content interface, apart from those three?

Hi! I’ve tried sharing a socket between to snaps, but couldn’t get it to work the same way that this documentation does. Here’s what I did:

Provider-Snap:

slots:
  tailscale-socket:
    interface: content
    content: tailscale-socket
    write: 
      - $SNAP_DATA

Consumer Snap:

plugs:
  tailscale-socket:
    interface: content
    content: tailscale-socket
    target: $SNAP_DATA

The provider snap creates the socket at $SNAP_DATA, as expected. But I couldn’t get it to show up on the other snap:

root@auth-test:~# snap run --shell derper
root@auth-test:/root# ls $SNAP_DATA
var
root@auth-test:/root# 

It only worked, after moving it into a separate directory on both sides:

slots:
  tailscale-socket:
    interface: content
    content: tailscale-socket
    write: 
      - $SNAP_DATA/socket
plugs:
  tailscale-socket:
    interface: content
    content: tailscale-socket
    target: $SNAP_DATA/socket
root@auth-test:~# snap run --shell derper
root@auth-test:/root# ls $SNAP_DATA/socket/
tailscaled.sock
root@auth-test:/root# 

Is sharing the socket from $SNAP_DATA directly not possible? The example in the docs says so. Or did I miss something else?

There is a bind mount going on between the two snaps, if you would actually allow one snap to mount its whole $SNAP_DATA over the $SNAP_DATA of the other snap, it would lose its whole own writable space and might result in weird, broken or unexpected behavior …

We should surely somehow note this in the doc though…

1 Like

Thanks for the quick reply! One more question about it. If I share just the socket, can I then mount it at $SNAP_DATA? E.g.:

slots:
  tailscale-socket:
    interface: content
    content: tailscale-socket
    write: 
      - $SNAP_DATA/tailscale.sock
plugs:
  tailscale-socket:
    interface: content
    content: tailscale-socket
    target: $SNAP_DATA

Small additional FYI. I ran into this error and thought it could be a bit more clear.

INFO snap "derper" has bad plugs or slots: tailscale-socket (content interface path is not clean: "$SNAP_DATA/socket/")

It wasn’t immediately obvious to me what is considered a “clean” path and that the trailing slash was the problem.