System-files interface doesn't work

Hello everyone,

I’ve been trying to give my snap package access to the system files through the interface. My program is able to read the files but it seems to struggle with modifying it. I install it from a local file (so I have to use --dangerous flag). I also connect the interface using

snap connect shellsnake:config-shellsnake

Is there something I’m missing? Interestingly when I run the program with superuser rights it is able to write into the files without an issue. Please find the snapcraf.yaml file below.

Thank you very much!

name: shellsnake # you probably want to 'snapcraft register <name>'
base: core20 # the base snap is the execution environment for this snap
version: '0.2' # just for humans, typically '1.2+git' or '1.3.2'
summary: a simple game # 79 char long summary
description: |
  A simple terminal based game for Linux.

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

parts:
  shellsnake:
    # See 'snapcraft plugins'
    plugin: cmake
    source: .
    build-packages:
      - libgtest-dev
      - libncurses5-dev
    stage-packages:
      - libncursesw5

layout:
  /var/shellsnake/settings.bin:
    bind-file: $SNAP_DATA/var/lib/shellsnake/settings.bin
  /var/shellsnake/scores.bin:
    bind-file: $SNAP_DATA/var/lib/shellsnake/scores.bin
  /usr/local/share/shellsnake/logo.txt:
    bind-file: $SNAP/usr/local/share/shellsnake/logo.txt

plugs:
  config-shellsnake:
    interface: system-files
    write:
      - /var/shellsnake/settings.bin
      - /var/shellsnake/scores.bin
 

apps:
  shellsnake:
    command: usr/local/bin/snake
    plugs:
      - config-shellsnake

interfaces do not alter filesystem permissions at all, if your normal user has no permission to write to /var, adding an interface will not change that …

Hello,

Thank you for the reply! That is interesting, I thought the point of the permissions (using interfaces) was that it gives the app access to the (system) files without having to run it as a superuser. After all that is how it works with my application when it’s installed using ‘sudo make install’. Using cmake I set the files’ permissions to world read/write. The app then can write into the files even when I run it without superuser rights. So is there any way I could replicate this behavior using snap? Thank you!

Maybe a little clarification: I’m trying to write into files in /var that are created during the installation.

Well, lookign at your snapcraft.yaml again,x first of all you do not really need the interface at all since you are already using a layout to map the files to a subdir in the writable $SNAP_DATA, the system-files interface is just redundant granting you write access for something you already can write …

to make files writable per-user you could use a wrapper script from a command-chain to make sure they end up in $SNAP_USER_DATA

i fear just making a dir in $SNAP_DATA world writable wont help here …

Note also that if you’re using layouts to redirect /var/shellsnake to locations your snap controls, you shouldn’t need to use system-files: you should already have permission to write to those locations.

You might have better luck binding the directory /var/shellsnake rather than files within in though. This could help if the application uses the “write a temporary file and rename it over the original” method of updating a file, which may not work too well with binding individual files.

Thank you both for your suggestions. So I tried both.

Using $SNAP_USER_DATA throws an error during package creation. It seems like it doesn’t recognize the variable which is weird:

error: cannot pack "/root/prime": cannot validate snap "shellsnake": layout "/var/shellsnake/scores.bin" uses invalid bind mount source "$SNAP_USER_DATA/scores.bin": reference to unknown variable "$SNAP_USER_DATA"

When I try biding just the folder

layout:
  /var/shellsnake:
    bind: $SNAP_DATA/var/lib/shellsnake 

the application can’t find the files. What am I doing wrong here?

So I solved the issue by creating an install hook that gives the files global write&read permissions:

#!/bin/sh -e

chmod 666 $SNAP_DATA/var/lib/shellsnake/settings.bin
chmod 666 $SNAP_DATA/var/lib/shellsnake/scores.bin

With this the system-files interface is not needed, indeed. That’s it.

1 Like