Snap up your development – Tools for making the snap trek easier

Tags: snapcraft.io

This article was last updated 5 years ago.


Software development is what happens in between users and bug reports.

Niccolo Machiavelli

In an ideal world, developers would be able to create new applications without any errors, and live happily ever after. Unfortunately, errors, warnings and bugs are an inseparable part of the process. Sometimes, these problems are caused or magnified by the very development framework, making the coding that much harder.

Snapcraft comes with its own basket of mysteries, side by side with the benefits and advantages that it brings. We want to make snapcraft as streamlined and elegant as possible, so that developers can focus on productivity, translating their ideas to creation, and not having to fight the environment and the tools they are using. To that end, we’d like to share several practical, useful tips and tricks that can make your snap journey as a developer more pleasant and effective.

YAML linting

One of the most trivial checks to run before building a snap is to make sure the snapcraft.yaml file has a correct, valid syntax. There could be minor typos in your file, and running the code against a validator can save time. Snapcraft has some built-in checks, but you can make the process even more robust.

You can use tools like JS-YAML or YAML Lint online. This is not a perfect solution, and some errors may slip under the radar, but you can at least detect and fix the obvious ones before you start your application build. Various linting tools for YAML are also available in most Linux distribution repositories, so you can also use those, and maybe even integrate them into your development build environment.

yamllint snapcraft.yaml
snapcraft.yaml
1:1 warning missing document start "---" (document-start)
19:81 error line too long (91 > 80 characters) (line-length)
51:26 error trailing spaces (trailing-spaces)
56:21 error trailing spaces (trailing-spaces)
57:16 error trailing spaces (trailing-spaces)

Clean build

It is best to build snaps in a clean environment. There are several ways you can do this. The ideal solution is to use the base keyword in your snapcraft.yaml, e.g.:

base: core18

The base keyword specifies a special kind of snap that provides a minimal set of libraries common to most applications. It will be mounted as the root filesystem for your application. Using core18 as the base is the recommended option.

In the background, snapcraft will instantiate virtual machines and build snaps in a pristine, isolated and consistent environment. If you encounter errors or problems, you can then run snapcraft clean <part> to delete created artifacts and re-run your builds.

Alternatively, if you are not using the base keyword, you can use the snapcraft cleanbuild command. This command will span a new container with the necessary build tools inside, parse the snapcraft.yaml file and try to build your snap.

Review Tools snap

Once you have built your snap successfully, the next step is to upload it to the store for a review. After it’s been approved, it will be published and made available to users. Sometimes, your snap may be rejected, and it is frustrating to have to wait and then start over again.

You can save time by reviewing your own snaps – using the same tools normally involved in the vetting process. The review-tools snap is a set of scripts that can analyze your newly built snap before you upload it, allowing you to remedy any errors and warnings you encounter. First, start by installing the tools:

snap install review-tools --beta

After the snap is installed, run it against your snap:

snap-review <snap file>

The review-tools snap also comes with several options, so you can tweak your testing. It allows for overrides, classic confinement, and other flags. You can check the full list by running the tool without a target and only the –help argument.

After the tool finishes running, it will print output, which you can then use to better understand the nature of your non-compliant code and rebuild the snap. You should publish the snap once you get a clean run.

 - lint-snap-v2:meta_gui_desktop

desktop interfaces (unity7,x11) specified without a corresponding meta/gui/*.desktop file. If using snapcraft, please see https://snapcraft.io/docs/build-snaps/metadata#fixed-assets. Otherwise, please provide a desktop file in meta/gui/*.desktop (it should reference one of the 'apps' from your snapcraft/snap.yaml).

xyz_amd64.snap: FAIL

The output above shows a typical error a developer may see after running the review-tools snap. Some of the explanations are self-explanatory, and you will also usually get a reference to the online documentation.

Finally, like the linting tools, you can add snap-review into your Continuous Integration (CI) environment or your software release process, so you get an automated report of your builds before uploads. This can be helpful if you develop applications as part of a team, and allow you to detect possible breakages before the software lands in the Snap Store.

Home directory contents and configurations

If you’re testing the behavior of your snaps, you may discover that it is not using the configuration normally found in your home directory. For example, if you have GIMP 2.8 installed from the repositories and GIMP 2.10 as a snap, the scripts, brushes, themes, and templates you may have stored in the program’s hidden folder in your home will not be available in the snap, which could hamper your experience. The reason for the separation stems from security considerations, to prevent confined snaps from accessing configuration files and potentially sensitive data.

You can move content – either for testing or actual use – into the snap environment. This is a seemingly trivial action, but it can save a lot of time and effort, especially if you need to troubleshoot specific behavior in your snap.

For each snap, go to ~/snap/<application name>. In this folder, there may be several versions of the program available, with current being a symbolic link pointing to the relevant version. Inside, you will find the expected hierarchy of files and folders as you’d normally find in your home directory. You can now manually copy the files from outside the snap environment into it, so your applications will use the content on next launch. For instance:

cp ~/.gimp-2.8/scripts/file.scm ~/snap/gimp/current/    

Interfaces

Snaps are designed to be confined and restricted in what they can do. In some cases, the snap may be packaged in a way that do not use folders inside the home directory, so you won’t be able to move or copy content into the snap environment using the method shown above. Specifically, the home interface will be auto-connected on classic systems, but it will not be on Ubuntu Core. Instead, you can connect to the home interface manually to perform necessary tasks. For instance:

snap connect easy-openvpn:home
sudo easy-openvpn.add-client laptop > laptop.ovpn
snap disconnect easy-openvpn:home

Snappy Debug

We briefly touched on the interfaces, but there’s more we can do to troubleshoot our applications. Specifically, when an interface is omitted in snapcraft.yaml (or not auto-connected), but your software expects it to be available, this may result in the application misbehaving.

The snap security team have provided a tool to debug these situations, and it’s called snappy-debug. Like the review-tools, it is available as a snap. Once it’s installed, you can use it to help identify missing interfaces by reporting on application security failures. It will also make suggestions on how to improve the snap, perhaps by adding interfaces.

snap install snappy-debug

After the snappy-debug tool is installed, run it in a separate shell:

snappy-debug.security scanlog
INFO: following '/var/log/syslog'. If have dropped messages, use:
INFO: $ sudo journalctl --output=short --follow --all | sudo snappy-debug.security scanlog

Then, in another window, run your application and go through the expected behavior steps until you encounter an error. You can then consult the log for more details, which should highlight any issues with your snap. For instance, if you use a Firefox snap with the removable-media that isn’t auto-connected, and you try to save a file to a USB drive, you will see something like this:

= AppArmor =
Time: Oct 24 13:39:04
Log: apparmor="DENIED" operation="open" profile="snap.firefox.firefox" name="/etc/fstab" pid=25299 comm="firefox" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /etc/fstab (read)
Suggestions:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON
* add 'mount-observe' to 'plugs'

= AppArmor =
Time: Oct 24 13:39:05
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/org/freedesktop/hostname1" interface="org.freedesktop.DBus.Properties" member="GetAll" mask="send" name=":1.289" pid=25299 label="snap.firefox.firefox" peer_pid=22465 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'hostname-control' to 'plugs'

= AppArmor =
Time: Oct 24 13:39:07
Log: apparmor="DENIED" operation="open" profile="snap.firefox.firefox" name="/media/alan/9098a06f-f509-452a-b2b8-3f00aee808a2/" pid=25299 comm="pool" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0
File: /media/alan/9098a06f-f509-452a-b2b8-3f00aee808a2/ (read)
Suggestion:
* adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON

Strace

Sometimes, you have be interested in profiling the behavior of your application in detail. You might want to compare the initial startup between your application as a snap and the version distributed through the repository channels. Or you might want to examine the performance, or resolve an issue with a missing theme.

The snap binary comes with a built-in strace functionality. The invocation is slightly different from the standard usage, but the tool works exactly like the strace program normally would, including the different flags. For example, -c for a summary run, or -s512 to get the log printed with 512 characters per line (often useful if you need to debug long file name paths). To use strace, you need to use the equal sign to pass the arguments to strace and enclose the options in double quotation marks:

snap run --strace=”-s512 -f”

Conclusion

We believe that software tools should work with the developers – not against them. If the development framework is not transparent, then it can hurt the productivity and creativity of the developer. Snapcraft has many useful, practical features, and we’re working on making the experience even more streamlined.

If you are developing snaps, we’d like to see you spend as little time debugging errors and warnings and focus on making your software as robust as possible. To that end, the tips and tricks presented in this article, from linting to review and configurations, ought to help you enjoy snapcraft.

If you have any questions or perhaps useful tips of your own own you’d like to share, please join the discussion forum.

P.S. No Star Trek fans were harmed in the production of this blog post.

Photo by Hunter Haley on Unsplash

Ubuntu desktop

Learn how the Ubuntu desktop operating system powers millions of PCs and laptops around the world.

Newsletter signup

Get the latest Ubuntu news and updates in your inbox.

By submitting this form, I confirm that I have read and agree to Canonical's Privacy Policy.

Related posts

Creating Snaps on Ubuntu Touch

This article was written in collaboration with Alfred E. Neumayer of the UBports Project. Tablets, phones and current technology’s capabilities are...

Managing software in complex network environments: the Snap Store Proxy

As enterprises grapple with the evolving landscape of security threats, the need to safeguard internal networks from the broader internet is increasingly...

We wish you RISC-V holidays!

There are three types of computer users: the end user, the system administrator, and the involuntary system administrator. As it happens, everyone has found...