description: fx is a terminal JSON viewer and processor for developers. It works like jq with an interactive TUI, and also reads YAML and TOML. Users run fx path/to/file.json to browse a file, or pass JavaScript expressions to query and transform it.
upstream-relation: I am the author and maintainer of fx.
supported-category: development tools
reasoning: fx’s main job is opening files that the user names on the command line, and in developer and ops work those files are often outside $HOME: /var/www, /srv, /etc, /opt, container volumes, mounted project directories. The snap is currently strict, with the home, network and personal-files (~/.fxrc.js) plugs. It can’t open these files and fails with open <file>: no such file or directory, even with sudo. Users report this as a bug: open *.json: no such file or directory (but exists!) · Issue #430 · antonmedv/fx · GitHub
Existing interfaces don’t cover this:
home only covers $HOME.
removable-media only covers /media, /mnt and /run/media, and has to be connected manually.
system-files needs a fixed list of paths, but users open files at arbitrary locations.
Piping (fx < file.json) works around it, but it drops the file-based features (the filename, YAML/TOML detection by extension), and users don’t expect
it.
fx is a static Go binary (CGO_ENABLED=0) with no host library dependencies, no daemons or services, and no privileged operations.
I understand that strict confinement is generally preferred over classic.
I’ve tried the existing interfaces to make the snap to work under strict confinement.
While I understand the reasoning provided, I am unable to grant classic confinement for this snap for two reasons:
As per our policy, this falls under the Unsupported category:
Access to arbitrary files on the system due to developer/user inertia (home and removable-media are almost always sufficient, though personal-files and system-files may be used under certain circumstances).
There is currently no supported Development tools category, and fx (being a terminal JSON viewer and processor) does not cleanly fit into any of the supported categories.
Understood, thanks for the review. Withdrawing the classic request.
fx stays strict. Next release adds the removable-media plug and documents
the pipe workaround (sudo cat /etc/foo.json | fx) for paths outside $HOME.
I’ll file a separate auto-connect request for removable-media.
@Lin-Buo-Ren to be honest I am not quite familiar with this process, however I don’t really see how fx would be a good candidate for a separate classicmode track. What do other @reviewers think?
I don’t really see how fx would be a good candidate for a separate classicmode track
Like jq, fx is commonly used to read files outside of what home and removable-files interfaces allow. For example, many Node.js based applications store their config files as JSON documents under hidden directories right under the user’s home directory (e.g. Visual Studio Code’s ~/.config/Code/User/settings.json configuration file). Being able to access them without specific workarounds helps.
Whilst it is true that fx does not clearly fit into any of the supported categories, I believe this is pretty much the same case as with text editors, which have been granted classic confinement in the past.
Thus, given that the project has been around for a long time and seems to have a reasonably large community around it, I wonder if this might be one of those cases where we want to relax the requirements for classic confinement. Of course, this would be after verifying that the snap publisher is, in fact, a member of the upstream project.
Since I started reviewing store requests, I haven’t seen the classicmode track being used much, but I think it’s a good approach that we should try to use more frequently. That way, users will receive the strictly confined snap by default, and they can switch to the classic one only if they need the additional access and trust the software. This also allows the snap to work on Ubuntu Core.
Additionally, as noted in Reviewing classic confinement snaps - Snap documentation, maintaining classic-confined snaps that live up to the promise of reliably working on any distro where snapd runs may require a significant maintenance effort.
snaps that use confinement: classic […] run in the global mount namespace (ie, the host’s filesystem) as opposed to what is specified by base in the snap’s yaml. […] great care must be taken for the snap to work reliably across all distributions since, for example, as part of the build process snapcraft will adjust the snap’s binaries through binary patching and/or setting environment variables to look into the $SNAP directory for paths, either of which could affect the snap’s reliability when running on arbitrary cross-distribution host filesystems. In contrast, strict mode snaps use what is specified by base in the snap’s yaml as the basis for its root filesystem at runtime and can depend on it not changing.