Creating a tmpfs in a snap that is user writable

Hello,

TL;DR Is there any supported way to mount a tmpfs filesystem within a snap in a manner that supports read/write access to applications of the same snap without sudo?

Some Background …

I have a snap with applications that require the use of an in-memory (i.e. RAM only) read/write filesystem. To address this, I am attempting to mount a tmpfs that will be user-writable to applications in the snap. I can do this with a classically confined snap, but the goal is to be able to package our applications as a strictly confined snap.

So far, I have found that I can mount a tmpfs without any problems using the mount-control interface, however, the mount-control interface only permits $SNAP_DATA, $SNAP_COMMON, and “/” as the start of the where parameter. The ability to start with “/” does not seem to provide a workaround because, if I provide a path like, /home/user/snap/snap_name/common/mymount, it fails to mount. That is true even with the home plug connected.

The fact that the $SNAP_DATA and $SNAP_COMMON directories are owned by root and the lack of support for the uid/gid parameters for tmpfs, necessitates using sudo for write access. Providing a mode=0777 during the mount also seems to get overridden by the mode mode=0x775. I don’t understand the need for this limitation when the interaction is between an application provided by the snap and its snap directories. It seems a bit unnecessary to have to run an application with elevated privileges to be able to interact with a tmpfs filesystem that the snap mounted itself.

So I am left wondering…

Is there any supported way to mount a tmpfs filesystem within a snap in a manner that supports read/write access to applications of the same snap without sudo?

Thank you.

I have concocted a workaround solution. A user-writable tmpfs mount can be used IF the snap is not responsible for mounting the tmpfs filesystem on install. The way to do this is:

  1. Mount a tmpfs somewhere in the user $HOME directory
mkdir -p $HOME/.local/mymnt 
sudo mount -t tmpfs -o rw,uid=`id -u`,gid=`id -g`,mode=0775,size=10M none $HOME/.local/mymnt
  1. In the snap/snapcraft.yaml file, create a plug based on the personal-files interface. The plug must specify the specific mount point.
plugs:
  mymnt:
    interface: personal-files
    write:
      - $HOME/.local/mymnt
  1. Make sure the applications that will be reading/writing to that directory specify the plug.
apps:
  write:
    command: usr/local/bin/write
    plugs: [mymnt,home]
  1. Install the snap
  2. Connect the snap’s plug to the :person-files slot
sudo snap connect mysnap:mymnt :personal-files

At that point, the applications that carry the mymnt plug will have the ability to read/write files in the tmpfs filesystem.

This is not ideal because installing the snap presumes the tmpfs filesystem has been mounted at a hard-coded location. It gets the job done though for my purposes because I this code will be installed by hand.

If anyone knows a clean/self-contained way to accomplish this during the snap’s installation, please share.

Have you considered FUSE yet ?

My understanding of FUSE is that it is a means to provide a custom implementation of the Linux VFS. In the past, I have used fuse.sshfs to mount a remote directory over ssh. It worked fine for that purpose.

I did search for a FUSE driver that would provide the same kind of functionality as tmpfs or ramfs. I did not come across any written in C or C++ that looked promising.

It was discussed in a stackoverflow post at: https://stackoverflow.com/questions/9003351/in-memory-fuse-filesystem.

I also found this blog post: https://web.archive.org/web/20170219015022/https://bbengfort.github.io/snippets/2017/01/30/fuse-inmem-fs.html

I have also read that there have been some issues in the past with inotify(), which I need to make use of, from working correctly in FUSE. That issue may not be relevant anymore, but it gives me pause.

In the end, the effort and trouble that come with providing my own in-memory implementation of FUSE seem like an unnecessary headache when tmpfs and ramfs are there to be used with no effort.