Monday, July 18, 2016

Running X Apps on Ubuntu Devices

Running X Apps on Ubuntu Devices You can install, launch, and use traditional debian-packaged X apps on Ubuntu devices. This may be unexpected given that Ubuntu devices do not seem to support user-installed debian packages, nor do they run the X Display Server. But it does work, courtesy of Mir/XMir and Libertine.

So here’s a bit of background to get started.

But first, please note that at this time, display and use of X apps on an external monitor is only available on the Pro5/M10 and on future devices. (BQ 4.5/E5 and Meizu MX4 do not support this feature.)

Hello Mir (Goodbye X)

Traditionally, and still on the Ubuntu Classic desktop with Unity 7, Ubuntu runs an X Display Server. Apps are debian packaged. And, they are written for X:

Due in part to X’s inherent security shortcomings, the Mir display server is now used on Ubuntu Devices under Unity 8 (although not yet by default on the desktop). XMir bridges traditional X apps to Mir. That is, apps written for X can run fine in a Mir/XMir environment:

Packages and the root file system

Ubuntu Classic has a root file system (rootfs) that is populated through installation of a carefully curated set of debian packages. At run time, users can install debian packages to add apps or modify their system.

This approach raises security concerns because debian packages execute installation scripts with root level privileges and because debian packages can alter what the rootfs provides by modifying or replacing core system components.

Ubuntu devices are designed for security and reliability. Ubuntu devices have a read-only rootfs that is small and tight, providing just what is needed and simplifying system updates. The rootfs is not modifiable by the user. Indeed it is mounted as a read-only partition. Users install apps through click packages that do not modify the rootfs.

Given all of this: how do users install debian packaged apps that use X on Ubuntu Devices? The answer is LIbertine with XMir.

Hello Libertine

Libertine is a system to manage app containers. It is specifically designed to support the many traditional X apps that are debian packaged. Each container is a separate Ubuntu rootfs populated through debian package installations. (Currently these containers are chroots: later, LXD contains will be supported. Also, currently the containers must be of the same Ubuntu series as the device: Vivid.)

So, you can install or create a libertine container, install debian packaged X apps into it, and launch them using the XApps scope. The apps access to the user’s key directories: Documents, Downloads, Music, Pictures, and Videos. So data files created and saved by an app in one container are available to apps in any other container, and indeed outside of the containers.

Let’s take a quick look at the XApps scope.

XApps Scope

This scope simply lists the containers and, for each container, it displays its apps. Here’s a look at a device with two containers. This system has two containers (Puritine and My Container). And each has a few apps:

  • Tap an app to launch it.
  • long press an app to hide it.
  • If you have any hidden apps, see them from the search icon (magnifying glass) and tap Hidden X Apps. Long press a hidden app to unhide it.
  • Note that a container with no apps does not display in the scope.
So how does one create and delete containers, and add or remove apps from them?

Libertine Container Manager

libertine-container-manager is a command line tool you use on the device to create and manage containers. This includes installing debian packaged apps into them. (These containers are created in the phablet user’s home directory and are not a part of the read-only rootfs.)

Note: libertine-container-manager currently cannot be run in the Terminal App. Instead please connect to your device from an Ubuntu system using phablet-shell.
Listing Containers
phablet@ubuntu-phablet:~$ libertine-container-manager list
puritine
my-container

The “puritine” container is pre-installed on many devices through the com.ubuntu.puritine click package (“Desktop Applications”):

phablet@ubuntu-phablet:~$ click list | grep puritine
com.ubuntu.puritine 0.11

The second container (“my-container”) was created on the device with libertine-container-manager.

Note: It is possible to pre-install customized containers through bespoke channels.
Creating a Libertine Container
You can create a new container on a device. The container needs a unique ID and (optionally) a name.

Note: The container must be the same Ubuntu series as the device, currently: vivid.

phablet@ubuntu-phablet:~$ libertine-container-manager create --id my-container --name "My Container" --distro vivid --type chroot

I: Retrieving Release
I: Retrieving Release.gpg
I: Checking Release signature
I: Valid Release signature (key id 790BC7277767219C42C86F933B4FE6ACC0B21F32)
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
[...]
Listing Apps in a Container
It’s easy to list the apps in a container. You just use the container’s id, as follows:

Note: We add the optional --json argument here and show only lines with “name” for display convenience.

phablet@ubuntu-phablet:~$ libertine-container-manager list-apps --id my-container --json | grep "\"name\""
"name": "Panel Manager",
"name": "Python (v3.4)",
"name": "Python (v2.7)",
"name": "gedit",
"name": "Help",
"name": "Notification Daemon",
"name": "Terminal",
Also note that all apps that install a .desktop file are listed by this command, although many of them are not displayed in the XApps scope since they are not appropriate.
Installing an app in a container
To install a debian package in a container, you just use install-package with the container id and the debian binary package name, as follows:

phablet@ubuntu-phablet:~$ libertine-container-manager install-package --id my-container --package terminator

The package and all of its dependencies are installed in the container. After this, assuming the package installs a .desktop file, it displays in the XApps scope and is launchable with a tap as expected.
Installing an app from a specific Launchpad PPA
By default, available debian packages are installed from the standard Ubuntu archive the chroot’s apt configuration points to. You can add a launchpad PPA, as follows:

phablet@ubuntu-phablet:~$ libertine-container-manager configure --id my-container --archive ppa:USER/PPA-NAME

(Currently, private PPAs are scheduled for an upcoming release.)

After this, you can install packages into the container as usual, including from the PPA.
Removing apps from a container
Remove a debian package from a container with:

phablet@ubuntu-phablet:~$ libertine-container-manager remove-package --id my-container --package PACKAGE_NAME
Libertine-container-manager help
Use the --help for top level help.

You can see details on each subcommand, for example remove-package, as follows:

phablet@ubuntu-phablet:~$ libertine-container-manager remove-package --help
usage: libertine-container-manager remove-package [-h] -p PACKAGE [-i ID] [-r]


optional arguments:
-h, --help show this help message and exit
-p PACKAGE, --package PACKAGE
Name of package to remove. Required. -i ID, --id ID Container identifier. Default container is used if
omitted.
-r, --readline Readline mode. Use text-based frontend during debconf
Interactions.
Updating a container
Want the debian packages in a container updated? Easy:

phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ libertine-container-manager update --id my-container
Executing a Command in a Container
phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ libertine-container-manager exec --command "apt-get update" --id my-container
Atteint http://ppa.launchpad.net vivid InRelease
Atteint http://ports.ubuntu.com vivid InRelease
Atteint http://ports.ubuntu.com vivid-updates InRelease
Atteint http://ppa.launchpad.net vivid/main armhf Packages
Atteint http://ppa.launchpad.net vivid/main Translation-en
Atteint http://ports.ubuntu.com vivid/main armhf Packages [...]

Note: Running the apt-get update command in a container may be useful to update the container’s knowledge of newly available packages without installing/updating them all. You can then see whether a package is available, with:

phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ libertine-container-manager exec --command "apt-cache policy firefox" --id my-container
firefox:
Installé : (aucun)
Candidat : 44.0+build3-0ubuntu0.15.04.1
Table de version :
44.0+build3-0ubuntu0.15.04.1 0
500 http://ports.ubuntu.com/ubuntu-ports/ vivid-updates/main armhf Packages
37.0+build2-0ubuntu1 0
500 http://ports.ubuntu.com/ubuntu-ports/ vivid/main armhf Packages

More about the Libertine Containers

As noted, the container is a directory containing an Ubuntu rootfs. Container directories are here:

phablet@ubuntu-phablet:~/.cache/libertine-container$ pwd
/home/phablet/.cache/libertine-container
phablet@ubuntu-phablet:~/.cache/libertine-container$ ls
my-container puritine
phablet@ubuntu-phablet:~/.cache/libertine-container$ cd my-container/
phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ ls
rootfs

You can get a bash shell into the container as follows:

phablet@ubuntu-phablet:~/.cache/libertine-container/my-container$ libertine-container-manager exec --command "/bin/bash" --id my-container
groups: cannot find name for group ID 1001
[...]
root@ubuntu-phablet:/#