I have been trying to get the content interface working with a trivial example.

consumer:

name: consumer # you probably want to 'snapcraft register <name>'
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

apps:
  consumer:
    command: ls -lR /snap/consumer/current/

parts:
  my-part:
    # See 'snapcraft plugins'
    plugin: nil

plugs:
  shared-files:
    content: shared-files
    interface: content
    target: shared
    default-provider: provider:shared-files

provider:

name: provider # you probably want to 'snapcraft register <name>'
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
description: |

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

parts:
  my-part:
    plugin: dump
    source: .

slots:
  shared-files:
    content: shared-files
    interface: content
    read:
    - /src

/src has some random files placed in it. I can see these in /snap/provider/current but nowhere in the /snap/consumer/current tree - which is where I believe they should appear. snap interfaces shows that the plug and slot are connected.

What am I doing wrong?

share|improve this question

You're so close!

The content sharing interface bind-mounts the slot to the plug's target. To that end, the target parameter must be pointing to an existing directory (bind mounts need to mount on top of something just like any other mount). So in your consumer, instead of using the nil plugin, use the dump plugin and dump an empty shared directory into the root of the snap. Then you'll see provider's $SNAP/src directory show up in consumer's $SNAP/shared directory.

Note that you won't see this from the system perspective. If you ls /snap/consumer/current/shared/ from the system, it'll be the empty directory you packaged into the snap. However, when an application is fired up, the context in which it is run contains that bind mount. Let me prove it:

$ snap run --shell consumer
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

$ ls $SNAP/shared/
file1  file2

snap run --shell runs a shell within the exact environment that would be used for the application in question. So running snap run --shell consumer you're asking for a shell with the same confinement and environment that the consumer app would have. That's why I could use $SNAP there. Note that file1 and file2 are the files contained within my provider's src directory.

One last note: assuming that you want the consumer app to list the contents of the shared directory, you would change it to look like this (no need to use /snap/consumer/current):

apps:
  consumer:
    command: ls -lR $SNAP/shared/
share|improve this answer
    
One issue with that approach is that you won't be able to provide a read-write directory to the consuming snap. It seems that snapd passes MS_RDONLY if the target directory is on a read-only file system which is the case with squashfs. This is not a required option though. paste.ubuntu.com/24336824 – Dmitrii S. Apr 7 '17 at 22:17
    
Hmm, I don't think that should be the case. That strace is coming from snap-confine? Might be worth logging a bug. – Kyle Apr 7 '17 at 22:24
    
Yes, it looks like it is coming from snap-confine/mount-support.c paste.ubuntu.com/24339585 : 7 mount-support.c sc_setup_mount_profiles 228 int flags = MS_BIND | MS_RDONLY | MS_NODEV | MS_NOSUID; – Dmitrii S. Apr 8 '17 at 9:56
    
pad.lv/1681068 - filed a bug. – Dmitrii S. Apr 8 '17 at 11:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.