Classic Confinement for wtfutil

I made a snap for the utility wtfutil that requires classic confinement to work. wtfutil is a terminal dashboard application that pulls in data from various APIs as well as local commands to provide an easy to access and quick dashboard of data right in your terminal.

Resources:

Original Project Repo: link
Original Project Website: link

My Snap Repo: link

Reasoning:

external binaries

Data that wtfutil pulls in via APIs works just fine in strict confinement. I’d use the network plug and everything is good. The problem is, many of the “modules” in wtfutil get their data from local commands on the machine. A quick search through their source will reveal many instances where external calls are made to commands such as git, hg, ufw, nmcli, upower and more.

It’s possible than some of these commands could be covered by plugs or installing the command within the snap, but not all of them. Some need context of the command that’s already running on the user’s machine.

config file

Then there’s also the config file, $HOME/.config/wtf/config.yml. This is less of an issue. I could create a personal-files interface for this, but that in itself would also require a “Store Request” approval. The problem there will still be that existing users won’t be able to use their config file without migrating it without the approval, and for new users, the app can’t create the config and so fails. This is because they’re not respecting XDG_HOME for which I’ve already opened an Issue. While I can do a request for the personal files interface, considering the above issue with multiple binaries, this can all be wrapped up nicely with classic confinement.

Due to the need to execute almost arbitrary commands on the host system, classic confinement is the only real appropriate solution as there is no good way to handle this with strict confinement. Given this, the requirements for classic confinement are understood - @advocacy could you please perform publisher vetting?

Before the vetting is done, I’d like to better understand the requirements. Based on what was listed, git and hg could be covered by personal-files, ufw by firewall-control, nmcli by network-manager and upower by upower-observe (and possible others).

Can you answer the following?

  • Can you expand on “pulls in data from various APIs as well as local commands”?
  • Is the dashboard composed of user-defined arbitrary commands or a finite set that wtfutil uses internally?
  • Does the dashboard run as root or use sudo?
  • What are examples of functionality that do not have corresponding interfaces?

I mean that it calls various APIs (typically via curl) and runs many local commands/binaries. As of right now, the command list for Linux consist of:

  • git rev-parse --abbrev-ref
  • git status --porcelain
  • hg branch <a path>
  • hg status <a path>
  • who -us
  • lsb_release -a
  • nmcli -t -f in-use,security dev wifi
  • nmcli device show
  • ufw status
  • upower -e
  • upower -i target
  • pmset -g ps

Can we find interfaces for all of these? Manually added by the user?

My two concerns here is that

  1. The number of interfaces needed, if they need to be manually added, is very cumbersome for the user.
  2. If you take a look at the repository, wtf is a very active repository that’s constantly getting new PRs and new contributors. This list of binaries and commands can rapidly change via additionals, removals, etc. How well is that going to play with interfaces once a strict snap is published with a set of interfaces that will change a few times a year? Last I remember it’s not easy to add onto the snap later.

A great example of this is that there’s a PR open right now that’s attempting to change the commands being used by the WiFi module.

Umm I might describe it as both? wtfutil is a Go binary. The set of commands it needs remains static once a version is publish, the user can’t change it. That being said, the project is very much driven my contributors. Almost all new features and changes to features are by community PRs.

Both. By default it’s going to run as your own user. Since some of the modules contain commands that need root access (ufw status for example), they provide instructions on how to run as root as well.

I’m not sure yet. You’d know better than me. I will make a testing, strict snap just for myself and see how many of the commands/binaries above I can get running with an interface and report back.

Thank you for the additional details!

This could be handled by home and removable-media (and possibly personal-files depending on the use of $HOME wrt .git and .hg). You would stage-package git and mercurial.

This would need a new interface or an adjustment to an existing one, perhaps system-observe.

You might want to parse /etc/lsb-release directly, though you might be able to get away with staging lsb-release.

You can stage network-manager and plugs the network-manager interface.

You can stage ufw and plugs the firewall-control interface.

You stage upower and plugs upower-observe.

I’m unfamiliar with this command and command-not-found isn’t helping me. You would need to ship this in your snap but googling suggests it is OS X specific.

The snap developer declares what interfaces should be used by the snap, not the user. Some interfaces are manually connected, some auto-connected. We have a process for requesting auto-connection such that when granted your users need only ‘snap install wtfutil’ and everything works.

You would need to change things a little bit since snaps aren’t allowed to call sudo directly. Users could either invoke wtfutil with sudo, or you can create a daemon in your snap that listens on a socket which can run these commands. wtfutil then talks to this daemon over the socket instead of calling ufw/etc directly. You would want to put some mechanisms in place in the daemon to perhaps verify the connecting process’ uid, lookup the supplementary groups and verify it is in an approved list so as not to allow arbitrary processes to talk to your snap and run the commands. Other options are possible.

In summary, snapd supports everything you listed (except who, which I’ve taken a todo to add to snapd 2.43 (the next release)). It will take a bit of work to convert it over, but each of the commands you gave is something other snap developers have done (again, except who).

When developing your strict mode snap, you might be interested in snappy-debug. It will provide suggestions for things to plug as your snap is running. Good luck and feel free to ask questions in the #snapcraft category.