Debugging Building Snaps

Building snaps can be a new experience for many developers. Here’s some tips which can help you successfully, reliably build snaps for publication in the Snap Store. This is a wiki post so feel free to add more tips to this page, to help build successful snaps!

Build Environment

Snaps are built to run on top of a ‘base’ (core) runtime. This base is provided by an automatically-installed snap. Currently the most widely used core image is based on Ubuntu 16.04. As such we commend all snaps are built either on bare metal running Ubuntu 16.04, or in a virtual machine or container running Ubuntu 16.04.

Building on a newer version of Ubuntu will likely pull in and depend on newer versions of low-level libraries. These snaps may well work on the developer build machine by virtue of building against installed libraries, but will fail once installed on end-user computers, where Ubuntu 16.04 is predominantly in use as the base image.

Missing libraries

Most applications will need additional libraries added to the snap in order to function correctly. As the developer of the application, you’re best placed to know which libraries you need to stage in the snap. Sometimes when a snap is initially built, libraries are missing because they were not explicitly specified by the developer. There’s a couple of ways to bundle required libraries in a snap, both of which are covered below.

Staging Packages

It’s common to bundle required libraries in snaps using stage-packages in the snapcraft.yaml. These are standard package names from the Ubuntu 16.04 repository. For those unfamiliar with the naming of packages in the Ubuntu archive, the package search at https://packages.ubuntu.com/ can be an invaluable tool. It enables search for files (such as libraries) within packages in the archive. Just be sure to choose ‘Xenial’ (the Ubuntu 16.04 development code-name) when searching.

Don’t include glibc/libc6 in your list of staged packages. Doing so is unnecessary as the ‘base’ (core) snap contains those libraries already, and bundling them into your snap can cause unexpected behaviour.

Staging individual libraries

Some application developers already have ‘vendored’ libraries which they’ve well tested with their application. If that’s the case, those libraries can be bundled in the snap in a similar fashion. Place the libraries in the /lib folder when constructing the snap. This folder is added to the LD_LIBRARY_PATH and as such should be found successfully by your application when the resulting snap is installed on an end-user computer

Interfaces

When applications are confined in a snap, they have a restricted view of the world, with access to resources governed by standard Linux security features apparmor and seccomp. Interfaces enable the developer to choose specify what access is required by the application to resources such as the network, camera, joystick and X11 display.

Identifying missing interfaces

The full list of interfaces details the capabilities enabled by each. Developers should consult this list to identify the necessary interfaces required by their application. When an interface is omitted, this may result in the application misbehaving.

The Snap security team have provided a tool to debug these situations. Install the tool with snap install snappy-debug. This helps identify missing interfaces by reporting on application security failures, and will make suggestions on how to improve the snap, perhaps by adding interfaces.

  1. In a terminal, run snappy-debug.security scanlog
  2. Launch the snapped application (in another terminal)
  3. Operate the snapped application until failure occurs
  4. Examine the output from snappy-debug

Typically the output will report on failed attempts to access system resources, and suggest additional interfaces which should be specified. If so, add the interface(s) listed and rebuild the snap.

Iterating without rebuilding

It can be time consuming to iterate over a snap via tweaking the snapcraft.yaml or application itself, then rebuild and re-install. The snap try command can be used to accelerate iteration.

Typically the process for developing a snap looks a little like this:

  1. Modify snapcraft.yaml or update application
  2. Run snapcraft to rebuild the snap
  3. Install the snap
  4. Test the snap

In the event of failure, repeating tasks 1-3 can be streamlined to the following.

  1. Modify snapcraft.yaml or update application
  2. Run snapcraft to rebuild the snap
  3. snap try prime
  4. Test the snap

At the end of a snapcraft run, the prime directory contains the result of the build, as it would appear inside the snap. snap try prime will present the contents of the prime directory as if it were an installed snap. The benefit here is that you can modify the contents of the prime directory, thus affecting the ‘installed’ snap. This can often be useful to inject libraries into the snap, or modify shell scripts or move files around to make the snap work.

Once debugging is complete, snap remove <snapname> to 'unmount ’ the prime directory and ‘uninstall’ the snap. Then replicate whatever fixes were done into the snapcraft.yaml or upstream source, so a final working snap can be built.

Last updated 3 months ago. Help improve this document in the forum.