Ubuntu Linux + Racket 8.10 snap + Emacs racket-mode

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.

Alex.

This sounds like install and racket-run permission denied · Issue #654 · greghendershott/racket-mode · GitHub when Racket is a Snap.

See also racket-documentation-search doesn't work with snap browsers in default configuration · Issue #620 · greghendershott/racket-mode · GitHub when Firefox or other web browser is a Snap.

(Possibly also a problem when Emacs is a Snap??)


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/).

1 Like

p.s. I updated that issue with a detail you contributed -- it looks like the issue is dotfile dirs, not the home dir per se.

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.

Alex.

@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.

Alex.

@alexh Is https://snapcraft.io/emacs the Emacs Snap you installed?

If so, its description says GitHub - alexmurray/emacs-snap: GNU Emacs in a snap is its source definition.

As a wild a$$ guess, its use of confinement:classic seems relevant?

@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?

The snap source is here: zygoon / racket-snap · GitLab
It's maintained by @zyga

I've added some of that information to the snap page.

Thanks for the link!


@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??)

Anyway/meanwhile I made an FAQ in a pinned issue: FAQ: "permission denied" when running your Racket program · Issue #666 · greghendershott/racket-mode · GitHub

2 Likes

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.

EDIT: I've filed a snap store request at: Request for classic confinement of racket - store-requests - snapcraft.io

Thanks!

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).

1 Like

Ah OK.

I should probably stay out of the details. :smile:

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!

1 Like

I don't know yet. I see your point and it does make sense. I need to get things to work first though.

I have a working version with classic confinement. I've pushed my branch to Files · classic · zygoon / racket-snap · GitLab and I'm working on Request for classic confinement of racket - #4 by zyga - store-requests - snapcraft.io to allow this through the store.

I believe the classically confined version should be the default, with strict confinement being available in a separate channel.

1 Like

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, ....