Are there restrictions on system-files interface?

I would like to expose a license file of a third party library to the snap package and think I have to use the system-files interface. Here are the relevant parts of my snapcraft.yml:

apps:
  annotate:
    command: desktop-launch $SNAP/bin/annotate.bin
    plugs:
      ...
      - cm-license

plugs:
  ...
  cm-license:
    interface: system-files
    read:
    - /opt/cm/etc/Licenses

I did connect the plug:

snap connect my-package:cm-license

But it does not seem to work. The file cannot be opened from within the application. I also tried to “–shell” into the application (snap run --shell my-package.annotate) and cannot see the file there (is this supposed to work?).

Sorry, my knowledge of debugging this is quite limited. I have seen people with similar questions e.g. seen post apparmor policies generated, bu t I have no idea how they did that.

Note my package is build and installed in devmode.

Thanks!
Julius

Are you trying to have your snap read the file /opt/cm/etc/Licenses from the host system? Or is your snap trying to provide this file to another snap?

The former, so the file is already in place on the host system.

So /opt is not something from the host that is mounted inside the snap’s mount namespace, so to access it, you need to go through the hostfs mount and adjust your system-files interface to:

plugs:
  ...
  cm-license:
    interface: system-files
    read:
    - /var/lib/snapd/hostfs/opt/cm/etc/Licenses

Ok, I will give it a shot, thanks a ton! Since I was assuming that /opt is maybe “special” I had been doing a test with a file in /etc. But that didn’t work either. Isn’t that unexpected?

/etc should be available through system-files directly without going through the hostfs mount. If you are seeing issues with /etc make sure that the interface is connected, plugged by all applicable apps in your snap in the snapcraft.yaml and finally that there are no warnings generated when you install the snap as sometimes it’s tricky to get the syntax for system-files correct.

If I use the hostfs mount - will the file actually be mapped to /opt/…? Because I really have no possibility to make the third party library look elsewhere for that file.

I have tried your suggestion and it does not show up in the location I need. It does show up in the hostfs location, but then again I think because of devmode, I have full access to that anyway (the same seems to hold for /etc).

Could I “layout” the file from the hostfs to the location I need?

I had such a good idea:

layout:      
  /opt/ipg/etc/Licenses:
    bind-file: $SNAP_COMMON/Licenses

…but still no cigar :frowning:

It just does not show up in that location.

You should be able to use layouts in combination with the system-files interface, which should work also in devmode if system-files isn’t working for you with something like this:

layout:      
  /opt/ipg/etc/Licenses:
    symlink: /var/lib/snapd/hostfs/opt/ipg/etc/Licenses

So I just made a stupid typo and the layout approach does work when done right :slight_smile:

Regarding your suggestion: I tried that (albeit with bind-file not with symlink), but it complained that the mapped filename must begin with either $SNAP, $SNAP_COMMON or $SNAP_DATA.

So you can do something like you have originally with

layout:      
  /opt/ipg/etc/Licenses:
    bind-file: $SNAP_COMMON/Licenses

and then have an configure hook like:

#!/bin/sh

# resize the file to 0
truncate -s 0 $SNAP_COMMON/Licenses
# append the real content
cat /var/lib/snapd/hostfs/opt/ipg/etc/Licenses >> $SNAP_COMMON/Licenses

This won’t handle updates to that file automatically but it will get automatically updated whenever you do snap set <your-snap> something=something-else (you will also need to stage-packages coreutils to get truncate because while it exists in the base snaps, it is not allowed for use by app snaps for some reason. Perhaps we can get that changed

1 Like

Nice, configure hooks are something I have not used so far, thanks for the practical example. For now, I will go with manually copying the file to the the common folder.