Split Personality Snaps

by Alan Pope on 25 June 2020

Broadly speaking, most snaps in the Snap Store fall into one of two categories, desktop applications and server daemons. The graphical applications such as Chromium and Spotify use desktop files, which ensure they can be opened on demand by any user via a menu or launcher. The server applications such as NextCloud and AdGuard-Home typically have systemd units, which control their automatic (background) startup.

Taking an existing desktop application and converting it to an always-running appliance leads to some interesting engineering challenges. Applications and games tend to have expectations for what programs and services are accessible at runtime, which need mitigating. Application confinement in snaps on Ubuntu Core means some assumptions about file and device access may no longer apply.  

We will typically need to stand-up a configuration in which the application believes it’s running in a standard desktop environment. The application will also need the startup automated in an appliance setting, but launched on demand when in a desktop environment.

We can be quite creative with snaps and build a “split personality” snap that can run both as a desktop application and as an appliance!

Building Blocks

Ubuntu Core doesn’t ship with Xorg or PulseAudio out of the box. This isn’t a problem if the appliance doesn’t require a connected monitor, nor makes any sounds, as is the case with Plex Media Server and Mosquitto but this can be a problem with applications which require access to the display or sound hardware.

Unlike multi-user desktop environments, appliances tend to only require one local system user under which services automatically start. On a desktop system, the logged-in user launches applications on demand, whereas with an appliance, a system user launches the appliance on boot. 

Our snap needs to service the needs of running on a desktop environment where Xorg and PulseAudio exist, and on an Ubuntu Core system where they don’t. It also needs to be capable of being manually launched in a window, but also auto-start full-screen on an appliance.

Multiple Personality Order

Let’s have a look at ScummVM, where we’ve done this work already.

ScummVM is a program that allows you to run a variety of  classic graphical point-and-click adventure games like The Secret of Monkey Island, provided you already have their data files. This makes it a great asset in the hands of old-game fans.

It’s published as a snap in the Snap Store, and runs on many different desktop Linux distributions. We thought it might be fun to make a “ScummVM Appliance” using this snap on top of Ubuntu Core. The goal is to create a single purpose device, which boots directly to the game selection screen, and functions like a ScummVM console. 

As Ubuntu Core has no Xorg, we need to use mir-kiosk to provide a Wayland-compatible display stack to drive an external monitor. Ubuntu Core also ships without PulseAudio, so  we’ll get no in-game sound. This is resolved by installing the pulseaudio snap. Keyboards & mice will just work as expected.

To enable the snap to function both on-demand on a desktop, and launch automatically on an appliance, we need to create two ‘apps’ stanzas in the snapcraft.yaml file that is used to build the ScummVM snap. 

apps:
scummvm:
command: desktop-launch $SNAP/bin/wayland-if-possible.sh $SNAP/bin/scummvm-launch.sh
daemon:
command: daemon-start.sh $SNAP/bin/scummvm-launch.sh -f
daemon: simple

The daemon: simple directive means the specified command will launch automatically on start.

This command includes logic that detects whether the program is running on an Ubuntu Core appliance, and if it is, it will launch using Mir as the Wayland display system. If the logic determines it’s not running on an Ubuntu Core appliance, the script exits immediately.

#!/bin/sh
if [ "$(id -u)" = "0" ] && [ "$(snapctl get daemon)" = "false" ]
then
# If not configured to run as a daemon we have to stop here
# (There's no "snapctl disable …")
snapctl stop $SNAP_NAME.daemon
exit 0
fi
mkdir -p "$XDG_RUNTIME_DIR" -m 700
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
ln -sf "${real_wayland}" "$XDG_RUNTIME_DIR"
exec "$@"

That’s essentially all we need! One single yaml and a smattering of scripting is all that’s required to make a dual-personality snap that can run on-demand in desktop contexts, and automatically when run as an appliance.

ScummVM running on a traditional Linux desktop


ScummVM running under Ubuntu Core in a Virtual Machine

The ScummVM snap is built for both x86 and arm based CPUs, we could create a simple self-updating boot-to-game device based on a low-cost device like a Raspberry Pi. Plugin a keyboard, screen and mouse, and we can be gaming like it’s 1990 all over again.

If you have an idea for something we could turn into an official Ubuntu Appliance, please join the discourse and post a suggestion in the proposed new appliances category.

Newsletter Signup

Related posts

CanonicalがFlutterにLinuxデスクトップアプリのサポートを提供

Chris Sells(Google)、Ken VanDine(Canonical) GoogleはFlutterの開発当初から、ターゲットプラットフォームを問わず、ネイティブ速度で動作する美しいUIを構築するための移植可能なフレームワークを目指しています。このため当初はAndroidとiOSのモバイルプラットフォームに力を注ぎました。Google Playには、すでに8万種類以上の美しいFlutterアプリが公開されています。 この成功を踏まえ、1年以上前から、ウェブOSとデスクトップOS(macOS、Windows、Linux)の両方でデスクトップクラスの体験を提供することに努めてきました。たとえば、デスクトップタイプのマウス入力とキーボード入力のほか、サイズ調整可能 […]

Canonical通过Flutter支持Linux桌面应用

本文由Chris Sells(Google)和Ken VanDine(Canonical)所写 Google对Flutter的目标一直是提供一个构建以原生速度运行的精美UI的可移植的框架,无论您使用的平台是什么。为了验证此功能,我们首先关注于Android和iOS移动平台,我们已经在Google Play上看到了8万多个快速和精美的Flutter应用程序。 为了获得成功,一年多来,我们一直将重点扩展到包括桌面级体验,包括针对Web和桌面系统(macOS,Windows和Linux)的体验。这项工作包括对引擎的大量重构,以支持桌面样式的鼠标和键盘输入以及可调整大小的顶层窗口。它还包括可以很好地适应桌面的新UI功能,例如Material Density支持和Navigatio […]

How to manage snap updates

Updates are an integral part of the software lifecycle. Quite often, they bring improvements, vital security patches – and sometimes, unfortunately, bugs, too. In mission-critical environments, it is important to assert a high degree of oversight and precision over updates. Snaps come with a built-in automatic update mechanism, whereby sn […]