I spent some time figuring out this behavior and I thought it might be useful to others:
On an Ubuntu Linux machine, I installed Racket 8.10 as a snap, and everything was working fine, except racket-mode in Emacs. The Racket files for racket-mode would fail to load in racket or raco with a "permission denied" error.
It turns out that snaps don't have access to configuration files in the user's home directory, and this means that they don't have access to files inside the .emacs.d folder, where racket-mode was installed.
Moving racket mode to a non-"dot folder" solved the problem. I moved mine in ~/site-lisp/racket-mode.
Hopefully this info is useful to others. Also, if you have this setup working without the above workaround, I would like to know the details.
In my experience with VMs and containers, there's usually an option to make outside dirs accessible. (IIUC even just read-only would suffice, here).
But it seems like Snap sandboxes don't make that possible, or at least easy (e.g. --classic might help if you use command-line instead of GUI Snap store)?
I've been hoping someone who knows more about Snaps might discover an easy recipe (EDIT: that allows people to keep using things like MELPA to install Emacs packages in the default place under ~/.emacs.d/).
The issue you linked does look similar to the problem I experienced.
I forgot to mention it in my original post, but I installed Racket Snap with the --classic flag and it still didn't have permissions to read from the dot-folders.
I also have Emacs installed as a Snap, but it has no permission errors when it tries to access files.
@alexh I wonder if changing the Emacs packages directory from the default ~/.emacs.d/elpa to (say) ~/emacs-packages would help? (That way racket wouldn't be trying to read .rkt files out of a dot dir.)
So I guess:
mv any existing ~/.emacs.d/elpa files there
early in your init.el (before any package-xxx stuff) set package-user-dir to there
restart Emacs
(If this works, it would have some bonus justification: it's always felt weird to me that Emacs package files go under ~/.emacs.d by default -- they feel like "cache" not "config", e.g. when excluding subdirs for backup and stuff like that.)
I installed racket-mode directly from the Github repository (I do that with some other packages), so moving elpa would not help me directly, however, it might be good advice for those who use it.
I'm not an expert on Snaps, but I noticed that Emacs installed as a Snap is able to access, and defaults to reading, the ~/.emacs.d/init.el file, but Racket installed as a Snap (even with --classic flag), can only access files in the user's home directory but not in dot-directories. It also creates its own separate mounting point, so its own config files are in a separate location under the users ~/snap folder.
@samth the description for https://snapcraft.io/racket doesn't list its source (maybe good to add that?) and I can't seem to find a repo for it either under you or Racket on GitHub. Where is it?
What do you think about confinement:classic?
EDIT: p.s. Oh, I guess the --classic command line flag might be equivalent(ish?) to running as if the config were confinement:classic?
Note: IIUC the --classic command line flag does not make a strict snap more permissive. Instead it's just user confirmation (they know they're installing an already-classic snap).
@zyga Should the Racket snap change to use classic confinement instead (and maybe @samth could help with store review)??
(OR if strict confinement is a desired feature -- maybe this snap is intended for e.g. students or hobbyists exploring Racket and they want a sandbox -- that's cool. But then maybe the snap and snap yml description and snap store descriptions should explain that intent, and link to https://download.racket-lang.org/ as an alternative??)
Apologies for the late reply. I've started looking into this. I think that we can make the snap to work with classic confinement and then request it through the snap-store "store requests" category. Racket would fall under the compilers/IDEs permission so I think this should be granted.
As to what existing users should do, I think it makes sense to keep both versions around, one with strict confinement and one with classic confinement, and allow people to choose with tracks. It remains to be see which should be default.
I got the impression that even when the snap specifies "classic" (weak) confinement, the user must opt into this with the --classic flag. Otherwise it's still strict. (At least with command-line install; not sure about GUI "software store" UX.)
Assuming that's true (?), a single "classic" snap would serve both roles -- still defaulting to strict, and allowing the user to opt into "classic".
p.s. Caveat: I've only read online docs. I have just a little hands-on experience with "universal package formats", and that little experience is mostly with flatpaks not snaps.
That's not quite like it. To install a snap that uses classic confinement you have to pass --classic option to snap install. Snaps using classic confinement are incompatible with being used with strict confinement due to how the mount namespace looks like for both.
The idea I'm currently exploring is to have both snaps - classic and strict - available under different channels. One can install or switch channels with the --channel argument, for example (hypothetical): snap install --classic --channel=classic/stable racket vs snap install racket. We can invert where the classic snap would be published (we could have a strict channel instead).
I'd just like to make a gentle pitch that the default channel, or path of least resistance, give people the classic, unconfined thing if possible. (Why: 1. Selfishly, it might make my life a little easier. 2. Generally, it seems appropriate for a programming language, as opposed to say a productivity app.)
However, if you believe it's better for the default to be confined, or anyway it's just too late to change that on the snapcraft repo -- no worries! Once it settles down I can write documentation to explain whatever the new situation is. And thanks again for looking at this!
re the discussion there about additional criteria: You make a good point about the open-ended nature. As support: The Racket main distribution and packages repo has many examples, including using Unix domain sockets, making systemd daemons, userspace FUSE filesystems, ....