Plasma in a Snap?

…why not!

Shortly before FOSDEM, Aleix Pol asked if I had ever put Plasma in a Snap. While I was a bit perplexed by the notion itself, I also found this a rather interesting idea.

So, the past couple of weeks I spent a bit of time here and there on trying to see if it is possible.

img_20170220_154814

It is!

But let’s start in the beginning. Snap is one of the Linux bundle formats that are currently very much en-vogue. Basically, whatever is necessary to run an application is put into a self-contained archive from which the application then gets run. The motivation is to isolate application building and delivery from the operating system building and delivery. Or in short, you do not depend on your Linux distribution to provide a package, as long as the distribution can run the middleware for the specific bundle format you can get a bundle from the source author and it will run. As an added bonus these bundles usually also get confined. That means that whatever is inside can’t access system files or other programs unless permission for this was given in some form or fashion.

Putting Plasma, KDE’s award-winning desktop workspace, in a snap is interesting for all the same reasons it is interesting for applications. Distributing binary builds would be less of a hassle, testing is more accessible and confinement in various ways can lessen the impact of security issues in the confined software.

With the snap format specifically Plasma has two challenges:

  1. The snapped software is mounted in a changing path that is different from the installation directory.
  2. Confining Plasma is a bit tricky because of how many actors are involved in a Plasma session and some of them needing far-reaching access to system services.

As it turns out problem 1, in particular, is biting Plasma fairly hard. Not exactly a great surprise, after all, relocating (i.e. changing paths of) an installed Plasma isn’t exactly something we’ve done in the past. In fact, it goes further than that as ultimately Plasma’s dependencies need to be relocatable as well, which for example Xwayland is not.

But let’s talk about the snapping itself first. For the purposes of this proof of concept, I simply recycled KDE neon‘s deb builds. Snapcraft, the build tool for snaps, has built-in support for installing debs into a snap, so that is a great timesaver to get things off the ground as it were. Additionally, I used the Plasma Wayland stack instead of the X11 stack. Confinement makes lots more sense with Wayland compared to X11.

Relocatability

Relocatability is a tricky topic. A lot of times one compiles fixed paths into the binary because it is easy to do and it is somewhat secure. Notably, depending on the specific environment at the time of invocation one could be tricked into executing a malicious binary in $PATH instead of the desired one. Explicitly specifying the path is a well-understood safeguard against this sort of problem. Unfortunately, it also means that you cannot move your installed tree anywhere but where it was installed. The relocatable and safe solution is slightly more involved in terms of code as you need to resolve what you want to invoke relative from your location, it being more code and also not exactly trivial to get right is why often times one opts to simply hard-compile paths. This is a problem in terms of packing things into a relocatable snap though. I had to apply a whole bunch of hacks to either resolve binaries from PATH or resolve their location relative. None of these are particularly useful patches but here ya go.

Session

Once all relocatability issues were out of the way I finally had an actual Plasma session. Weeeh!

Confinement

Confining Plasma as a whole is fairly straightforward, albeit a bit of a drag since it’s basically a matter of figuring out what is or isn’t required to make things fly. A lot of logouts and logins is what it takes. Fortunately, snaps have a built-in mechanism to expose DBus session services offered by them. A full blown Plasma session has an enormous amount of services it offers on DBus, from the general purpose notification service to the special interest Plasma Activity service. Being able to expose them efficiently is a great help in tweaking confinement.

Not everything is about DBus though! Sometimes a snap needs to talk with a system service, and obviously, a workspace as powerful as Plasma would need to talk to a bunch of them. Doing advanced access control needs to be done in snapd (the thing that manages installed snaps). Snapd’s interfaces control what is and is not allowed for a snap. To get Plasma to start and work with confinement a bunch of holes need to be poked in the confinement that are outside the scope of existing interface. KWin, in particular, is taking the role of a fairly central service in the Plasma Wayland world, so it needs far-reaching access so it can do its job. Unfortunately, interfaces currently can only be built with snapd’s source tree itself. I made an example interface which covers most of the relevant core services but unless you build a snapd this won’t be particularly easy to try 😉

Summary

All in all, Plasma is easily bundled up once one gets relocatability problems out of the way. And thanks to the confinement control snap and snapd offer, it is also perfectly possible to restrict the workspace through confinement.

I did not at all touch on integration issues however. Running the workspace from a confined bundle is all nice and dandy but not very useful since Plasma won’t have any applications it can launch as they either live on the system or in other snaps. A confined Plasma would know about neither right now.

There is also the lingering question of whether confining like this makes sense at all. Putting all of Plasma into the same snap means this one snap will need lots of permissions and interaction with the host system. At the same time it also means that keeping confinement profiles up to date would be a continuous feat as there are so many things offered and used by this one snap.

One day perhaps we’ll see this in production quality. Certainly not today 🙂

mascot_konqi-app-dev

KDE neon + Kernel 4.8

We are currently looking to roll out Kernel 4.8 and I’d love to get some informal testing done first. Everyone who wants to help with testing the 4.8 Kernel please install and reboot afterward:

pkcon refresh; pkcon install linux-generic-hwe-16.04 xserver-xorg-hwe-16.04

Once you are on 4.8, please let me know if you have any problems or if everything is fine 🙂

Kanboard to Phabricator

A while ago KDE migrated our todo management from Kanboard to Phabricator to reduce the amount of software our System Administrators have to manage and maintain. In KDE neon we did this move already ahead of time so I happened to have a primitive migration script at hand, ultimately making me the person to auto migrate everyone’s todos.

Over the course of the migration, the script grew quite a bit in functionality and so I thought it may be useful to others and also to look at as an example for how to talk to the two systems. It’s no secret that I love having computers do all the work, so some nifty scripting goes a long way in making every day a happy day.

Fortunately, both systems feature a lovely REST API to easily grab data out of one and move it to the other. Kanboard uses JSON-RPC while Phabricator uses a largely RPC-like API (the API documentation is actually available in the conduit module of every Phabricator instance).

Particularly relevant API interfaces for moving would be:

Kanboard

Phabricator

To make things easy I simply hardcoded some stuff. Namely the id’s of projects in the respective systems, they don’t change and are easy enough to get via the web UIs.

You can have a look at the Ruby code over on Github.

It is fairly horrendous spaghetti but hopefully still readable enough to get the gist of it. The process itself is very straightforward.

  1. Grab all tasks from Kanboard
  2. Get all Comments of the tasks we want to migrate
  3. Create new tasks in Phabricator
  4. Edit the tasks to add comments. For simplicities sake, the code at hand simply re-creates the comments with a leading line mentioning the original author and time as obtained from Kanboard
  5. One could do additional meddling at this point, such as tag additional projects, set priority etc. My script doesn’t do that since we wanted a very lightweight simple migration.
  6. Remove the creating-user from subscribers (prevents the migrator from getting flooded with a million task notifications whenever someone does anything on Phabricator involving a task :))

Possibly the trickiest API endpoint to use is maniphest.edit. It is a very generic interface and when I created the script the documentation wasn’t overly clear either.

maniphest.edit is a transaction-based interface as you can see from the documentation. The payload sent to the endpoint describes which object to edit and which transactions to apply in which order. A Transaction is generally defining which action to carry out with which value. The value, in this case, is a variant dependent on the type of action.

Here’s an example payload for illustration

{
  "objectIdentifier": "PHID-TASK-xtokm64ym25mdvvbt3g4",
  "transactions": {
    "0": {
      "type": "comment",
      "value": "add a fancy comment"
    },
    "1": {
      "type": "subscribers.remove",
      "value": "PHID-USER-4kerus6xjnzeqjtp3t2k"
    }
  }
}

In this example, we’d be editing PHID-TASK-xtokm64ym25mdvvbt3g4 by first adding a comment and then unsubscribing PHID-USER-4kerus6xjnzeqjtp3t2k.
This is equal to doing the same combined changes in the web UI:

spectacle-s18029

 

Of course, you could just as well only do one transaction at a time (that will, however, cause more mails/notifications to be sent; during a mass migration that hardly would matter though).

I hope this is helpful to someone 🙂