Content interface and SNAP_USER_DATA

Hi,

I have two snaps that like to share data. The snaps in question runs as a normal user. I tried to use the content interface to mount $SNAP_USER_DATA together. No warnings or errors, but the folders are not in sync. $SNAP_DATA works like .

I find no documentation specifying if it’s even possible to do this with $SNAP_USER_DATA? Does the content interface only work for non-user related folders?

What is your recommendation? To use :home for this and just share the data under ~/shared? I’m not really happy with that solution because it will pollute the home folder, and dotfiles will not work. I also do not like to grant snaps access to home if there is no other option.

I’m doing something wrong? Is there a 3rd option for me to share data?

I guess this answers my question about SNAP_USER_DATA: https://github.com/snapcore/snapd/blob/master/interfaces/builtin/content.go#L167

// resolveSpecialVariable resolves one of the three $SNAP* variables at the // beginning of a given path. The variables are $SNAP, $SNAP_DATA and // $SNAP_COMMON. If there are no variables then $SNAP is implicitly assumed // (this is the behavior that was used before the variables were supporter).

It looks like a simple string replace operation, so only there 3 environment variables are supported. So my $SNAP_USER_DATA is actually trying to mount the string /snap/mysnap/current/$SNAP_USER_DATA :slight_smile:

Edit

Not sure what this was not displayed earlier, but I did a reinstall and reconnect and now I got this from the plug-snap when I did a snap run --shell ...

2018/07/19 11:50:32.112883 main.go:192: cannot change mount namespace of snap "sharing-test-b" according to change mount (/snap/sharing-test-a/x1/$SNAP_USER_DATA /snap/sharing-test-b/x1/$SNAP_USER_DATA none bind 0 0): cannot create path "/snap/sharing-test-a/x1/$SNAP_USER_DATA": cannot operate on read-only filesystem at /snap/sharing-test-a/x1

So the question that remains are, is there another way to share data that do not involve :home?

There is no support for this currently, but could probably be implemented fairly easily on top of the user mounts feature I worked on for portal support.

Here’s a quick sketch of the solution:

  1. in the content interface, if a plug or slot is relative to $SNAP_USER_DATA or $SNAP_USER_COMMON, add a user mount instead of a regular mount, expanding the path to be $HOME relative.

  2. teach snap-update-ns to expand $HOME when processing user mounts (similar to how it handles $XDG_RUNTIME_DIR), using the home directory value from a getpwuid() style API rather than trusting the environment.

That still leaves the question of whether this kind of thing is desirable. Perhaps @zyga-snapd has some thoughts?

This would have to happen at runtime, no ? else you’d have to permanently bind the interface to all users all the time from the moment you install the snap (what happens if a user gets added/removed while such a snap is installed ?)

(given how slow connecting interfaces can be in certain scenarios, that might have a massive impact on app startup times)

At the moment, user mounts are processed at the time the application is run (and once for each invocation) into a private mount namespace. The user mounts are only performed for the user invoking the application, so there is no enumeration of all users.

The plan is to switch it over to using persistent mount namespaces like for regular mounts, but that hasn’t happened yet. The creation of this namespace would likely be triggered the first time a user runs the application, and torn down when logind says the user has no more active sessions (i.e. so it won’t refer to a stale $XDG_RUNTIME_DIR or hold an NFS mount open).

Instead of trying to use SNAP_USER_DATA, use SNAP_COMMON and export a sticky dir (1777) under it.

1 Like

This is on the roadmap already so it will happen before 18.10 for sure. I will do it as a part of the work on persistent per-user mount namespaces and snap-update-ns support. User mounts will then be able to reference $SNAP_USER_DATA and $SNAP_COMMON.

Of course, that will work, thank you.