Kiosk snaps made easy
The following assumes some familiarity with using snapcraft to package snaps, and concentrates on the specifics of snapping graphical snap intended to work with, for example, the mir-kiosk
snap on Ubuntu Core.
Kiosk snaps
Essentially kiosk snaps are Wayland applications packaged as a snap. Compared with running applications on a desktop, these do not care about integration with desktop themes and are expected to run as single fullscreen applications.
There are various types of application that fall into this category. As well as bespoke “kiosks” e.g. wpe-webkit, there are also things that might be embedded e.g. Kodi and games e.g. scummvm.
Note: While it is possible to use Xwayland to package an X11 application to use Wayland that is outside the scope of these notes.
Dancing with Wayland, Dancing with Daemons
I’ve taken the experience of writing a number of snaps to work with mir-kiosk and simplified the process. The result of this is a simple approach to snapping a Wayland application to work both on Ubuntu Core and Classic systems.
The “wayland interface dance”
Snaps use “interfaces” to access capabilities of the system and one of these is the wayland
interface. Snaps have their own $XDG_RUNTIME_DIR
but Wayland expects to use a file in this location to connect to the server. As a result, every Wayland based snap needs logic to make this work.
After writing this logic a few times, I extracted it into a wayland-launch
helper script:
#!/bin/sh
set -x
if [ -z "${WAYLAND_DISPLAY}" ]
then WAYLAND_DISPLAY=wayland-0
fi
real_wayland=$(dirname "$XDG_RUNTIME_DIR")/${WAYLAND_DISPLAY}
while [ ! -O "${real_wayland}" ]; do echo waiting for Wayland socket; sleep 4; done
mkdir -p "$XDG_RUNTIME_DIR" -m 700
ln -sf "${real_wayland}" "$XDG_RUNTIME_DIR"
unset DISPLAY
exec "$@"
This creates a link from the snap’s $XDG_RUNTIME_DIR
to the real one in the user’s $XDG_RUNTIME_DIR
.
This “dance” (by design) works equally well on Ubuntu Core, running as a daemon and on Classic systems running in a user session.
The “daemon dance”
There is a difference between the way that snaps are run on Ubuntu Core and on Classic systems. On Ubuntu Core, snaps are expected to start automatically as daemons, on a Classic system they are started by the user.
To accommodate this I’ve introduced a daemon
snap option, and on installation I set this according to the type of system. (Like other options this can then be changed using snap set
.)
To work with this I’ve written a run-daemon
helper script:
#!/bin/sh
set -x
if grep -q snap_core= /proc/cmdline || [ "$(snapctl get daemon)" = "true" ]
then exec "$@"
fi
mir-kiosk-snap-launch
After copying these scripts and hooks into a few projects I decided that it would be simpler and more consistent to create a github project for them: mir-kiosk-snap-launch.
To use this, you need a stanza to pull it into your snap:
mir-kiosk-snap-launch:
plugin: dump
source: https://github.com/MirServer/mir-kiosk-snap-launch.git
override-build: $SNAPCRAFT_PART_BUILD/build-with-plugs.sh alsa avahi-observe hardware-observe locale-control mount-observe network-observe removable-media shutdown system-observe wayland
This pulls the above scripts and the installation
and post-refresh
hooks mentioned above into the snap. The build-with-plugs.sh
script tailors some scripts to this snap including a setup.sh
script that the user can run to connect any Snap interfaces.
To make use of these scripts, they need to be added to the command:
entries for your snap. Like this (from the
mir-kiosk-kodi snap):
apps:
daemon:
command: run-daemon wayland-launch ${SNAP}/usr/bin/kodi
daemon: simple
...
mir-kiosk-kodi:
command: wayland-launch ${SNAP}/usr/bin/kodi
...
Clearly you may need to do some additional things to configure your application to run in this environment. For example, Kodi needs WINDOWING=wayland
to use Wayland, SDL2 needs SDL_VIDEODRIVER=wayland
and scummvm needs -f
added to the command-line for fullscreen.
The end result
These incantations provide you with a snap that will run both on Ubuntu Core with mir-kiosk
and on the desktop either using a Wayland supporting desktop (e.g. the “Ubuntu Wayland” login session) or running egmde).
Here are three snaps that use this technique: