Packaging Apps To Run on Any Linux Device

It's a Snap!

Classic Chroots

With Ubuntu 16.04 onward, many of the snap tools required for building a snap appear to be readily available.

To avoid read-only filesystem issues (i.e., no useful package manager like Apt), you can create a chroot environment in which you develop your application. A chroot ignores the file path and some of the host system innards. Within the chrooted environment, you share the home/ directory between the container (your snap) and the ubuntu-core snap (your snap's OS). The next command lets you run a "classic" Ubuntu environment on a Snappy system:

$ snap install classic --edge --devmode
classic (edge) 16.04 from 'canonical' installed

When you run classic, it changes the prompt, after loads of output, by prepending (classic), which is also a reminder to always run this from your home directory so snapd knows what's going on.

$ classic

Unlike my example, you should probably avoid using root and, if needed, sudo from your user or use it directly.

You need to throw in some compilers and other build tools now, which, if your prompt has the classic prefix, gets chucked into your chroot and not directly onto your system:

(classic)root@chris:~# apt install build-essential

If you did not install the snapcraft package before this point, you should add that package to this command, as well. After hitting the Enter key, you're faced with the usual (potentially insecure, if you leave it on a system unnecessarily) more than 200MB of compiler tools, such as the omnipotent gcc package.

Make It Snappy

Unlike the init command example in Figure 6, in this case, I'm running it inside my chroot. For this example, I create and change to a directory called echo-chrisbinnie before running the init command. Pay close attention: If you're not in a directory off your home directory, your chroot might not work as expected and could potentially reference other system paths within the snap by accident.

Figure 6: Some helpful output from the friendly, neighborhood init function.

In a slightly alarming oh-no-it's-all-badly-broken sort of way, you might see a screen full of errors. Fret not, though, because on Ubuntu 16.04, I entered two suggested export commands,

$ export LC_ALL=C.UTF-8; export LANG=C.UTF-8

and then ran the snapcraft init command again with complete success. Thankfully, it's happy days again when you see the friendly Edit the file to your liking greeting that you saw in Figure 6. As you've probably guessed, the next thing to do is edit the template file under the snap/ directory.

When I first looked at snaps, I have to admit that I needed to tinker with paths, and source file downloads, but ultimately, unless you're building a massive file from source, it's a relatively simple and rewarding experience to build your first snap. Once your YAML is correct, you witness a welcome screen of progress as your snap is being packaged (Figure 7). To compile your snapcraft.yaml file, just make sure you're in the snap/ directory within your chroot, and run the

(classic)root@chris:~/echo-chrisbinnie/snap# snapcraft

command a few times, adjusting your configuration according to any errors. Also, pay attention to the configflags compile flags (Listing 5, last line). Would you believe even a simple echo command needs tweaking with compile flags?!

Listing 5

Working Config for Echo Snap

name: echo-chrisbinnie
version: '0.1'
summary: Echo a name
description: |
  Enter a name and I will echo it.
grade: devel
confinement: devmode
    command: bin/echo
    command: bash
    plugin: autotools
    configflags: ["FORCE_UNSAFE_CONFIGURE=1"]

If you get stuck, you'll find more docs [13] at the Ubuntu developer site that are much easier to use if you spin up a fully supported (ephemeral) Ubuntu 16.04 cloud instance/droplet/VM somewhere. Note that I simply looked up Ubuntu's 16.04 source files online for the coreutils URL (which is the package that provides the echo binary).

Once compilation and packaging was complete, I found an echo-chrisbinnie_0.1_amd64.snap file inside my snap/ directory. If you're happy that your version worked like mine (Figure 7), you can change confinement from devmode to strict and grade from devel to stable for publishing.

Figure 7: After loads of compiling and a bit of tweaking and rerunning, here's the snapcraft command in a chrooted environment; this output indicates everything is working as hoped (probably!).

Now, you need to run the packaging command one more time:

$ snapcraft

Assuming your last line says Snapped with the snap name (and you're not uploading the snap to the Snap Store but installing it locally), you'll face the moment of truth when you try to execute your snap.

Oh No, It's Snapped!

Because your hand-crafted snap hasn't been signed by Canonical's Snap Store at this stage, you'll have to add --dangerous to the end of the install command. (By this stage, to publish your snap successfully, you have to have edited the config file with the changes to confinement and grade, as mentioned in the previous section). Even though confinement is strict, your snap is still apparently dangerous. Don't forget to run the snapcraft command whenever you make a change to your config file.

A simple snap installation looks like this example:

(classic)root@chris: ~/echo-chrisbinnie/snap# snap install echo-chrisbinnie_0.1_amd64.snap --dangerous
echo-chrisbinnie 0.1 installed

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Container Apps
    Canonical’s Snapcraft (Snappy) package manager creates self-contained applications that work across Linux distributions. We show you how to install, publish, and run a simple snap.
comments powered by Disqus