Learn to make a snap
Snapcraft is a snappy packaging tool.
To take this tour of snaps and Snapcraft, you'll need to have Snapcraft 2.11 or later installed. If you've already installed Snapcraft you can check the version:
$ snapcraft --version 2.22
If you haven't installed Snapcraft, it's available on Ubuntu 16.04 LTS:
$ sudo apt install snapcraft
Note: to get the latest version of Snapcraft and future updates, make sure the
xenial-updates/universe repository is enabled on your system. Snapcraft will also run on any Linux distribution with an up-to-date version of LXD, the container hypervisor.
Some of these examples also require you to have the
build-essential package installed:
$ sudo apt install build-essential
Take the snapcraft tour
This tour walks you through the making of snaps. It starts with an overview of the snap format before introducing you to Snapcraft, the most widely used tool for creating snaps. After running through the basics of using Snapcraft the tour takes an in depth look at the key components that make up a snap. By the end of the tour you'll know how to create snaps so, if you want to, you can create them by hand or make your own snappy tools.
The tour includes all the example source code and files in a series of subdirectories, which you load using the Snapcraft tool:
$ snapcraft tour Snapcraft tour initialized in ./snapcraft-tour/ Instructions are in the README, or http://snapcraft.io/create/#tour
Each stage of the tour is in a separate subdirectory, with number prefixes showing the sequence.
Unless you specify a different directory name, the tour will be created in a new
snapcraft-tour subdirectory in your current working directory. The directory structure will look like:
$ ls snapcraft-tour/** snapcraft-tour/README.md snapcraft-tour/00-SNAPCRAFT: 01-easy-start 02-parts snapcraft-tour/10-SNAPS: 01-service 02-service-confined snapcraft-tour/20-PARTS-PLUGINS: 01-reusable-part
You can cd into each directory and work through the README, or follow along on this page.
00 - SNAPCRAFT
01-easy-start: a single snapcraft.yaml describes a snap
Snapcraft uses a single text file to describe the entire build process for a snap: the snapcraft.yaml file. Over the course of this tour you'll learn how to create this file for your own snaps. You can see an example in this directory:
$ cd snapcraft-tour/00-SNAPCRAFT/01-easy-start $ ls snapcraft.yaml
snapcraft.yaml is the only file in the directory. Snapcraft doesn't need anything else as it will fetch everything it needs to build the snap, using the
snapcraft.yaml description for the snap. Take a look inside:
$ more snapcraft.yaml name: hello version: "2.10" summary: GNU Hello, the "hello world" snap description: GNU hello prints a friendly greeting. This is part of the snapcraft tour at http://snapcraft.io/create/ confinement: strict apps: hello: command: hello parts: gnu-hello: plugin: autotools source: http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz
Don't worry about everything in there just yet. The snapcraft tool will interpret this file, fetch and install everything that is needed, build it, and give you a snap.
Start by building this snap, noting that you’ll be prompted for your system password if
snapcraft needs to download dependencies from the archive:
$ snapcraft [sudo] password for [your user name]: *** Preparing to pull gnu-hello Pulling gnu-hello Preparing to build gnu-hello Building gnu-hello ... Snapped hello_2.10_amd64.snap
You'll have seen that Snapcraft fetched the source code, configured and built it. The snap is now available in your directory, along with new parts, prime, and stage directories.
$ ls hello_2.10_amd64.snap parts prime snapcraft.yaml stage
As you can see a snap is a single file. The name of the file is based on information in the
snapcraft.yaml (its name and version) and the architecture you're building on:
Here, the snap was built on an amd64 machine, so the architecture used in the file name reflects that. The following commands use globs so you don't need to replace the architecture accordingly.
Now, everything you need for the hello app is inside the snap file. You can install it locally:
$ sudo snap install --dangerous hello_2.10_*.snap hello 2.10 installed $ snap info hello name: hello summary: "GNU Hello, the \"hello world\" snap" publisher: description: | GNU hello prints a friendly greeting. This is part of the snapcraft tour at http://snapcraft.io/create/ tracking: installed: 2.10 (x1) 745kB - refreshed: 2016-12-14 17:06:35 +0100 CET
Congratulations, you've just made and installed your first snap.
Note that the snap has both a version and a revision.
The version is purely human-readable, it isn't used for any particular purpose other than keeping you aware of what's on your system. Two different snaps can claim to have the same version (in fact, when you have daily builds of a snap, it will almost always have a version like "2.1b3" for every build until the version is updated).
The revision for a snap is unique. In this example, because you built the snap locally, it gets a local alphanumeric revision that is unique on this machine only. When you load a snap from the store, the revision is an integer number that exactly identifies the snap that is installed. While you can't do this for local revisions, with snaps loaded from the store you can compare revisions on two machines to determine if they have exactly the same content installed.
When you install a snap from the store, it includes an "assertion" that the snap was published by a trusted third party. However, in this case you're installing a snap straight from your hard drive; that assertion hasn't been generated. We use the
--dangerous option to tell snapd to trust it anyway.
You can also confirm details of all the snaps you've installed:
$ snap list Name Version Rev Developer Notes hello 2.10 X1 - ubuntu-core 16.04.1 423 canonical -
Finally, run your snap:
$ hello Hello, world!
Next, you might want to do some housekeeping and get rid of all the files that were created in the process of building the snap:
$ snapcraft clean Cleaning priming area for gnu-hello Cleaning staging area for gnu-hello Cleaning build for gnu-hello Cleaning pulled source for gnu-hello Cleaning up snapping area $ ls hello_2.10_amd64.snap snapcraft.yaml
In some trees it may be preferable to name the snapcraft YAML file
.snapcraft.yaml. Snapcraft will look for
.snapcraft.yaml, and will use either one, but it will error out if you've got both there. If you're uncertain, the recommendation is to use
One last thing to be aware of is that the
snapcraft command is shorthand for the real command, which is
snapcraft snap. You can see this from the help for snapcraft:
$ snapcraft help Usage: snapcraft [options] [--enable-geoip --no-parallel-build] snapcraft [options] init snapcraft [options] pull [<part> ...] [--enable-geoip] snapcraft [options] build [<part> ...] [--no-parallel-build] snapcraft [options] stage [<part> ...] snapcraft [options] prime [<part> ...] snapcraft [options] strip [<part> ...] snapcraft [options] clean [<part> ...] [--step <step>] snapcraft [options] snap [<directory> --output <snap-file>] snapcraft [options] cleanbuild snapcraft [options] login snapcraft [options] logout snapcraft [options] list-keys snapcraft [options] keys snapcraft [options] create-key [<key-name>] snapcraft [options] register-key [<key-name>] snapcraft [options] register <snap-name> [--private] snapcraft [options] sign-build <snap-file> [--key-name=<key-name>] [--local] snapcraft [options] upload <snap-file> snapcraft [options] push <snap-file> [--release <channels>] snapcraft [options] release <snap-name> <revision> <channel> snapcraft [options] status <snap-name> [--series=<series>] [--arch=<arch>] snapcraft [options] history <snap-name> [--series=<series>] [--arch=<arch>] snapcraft [options] close <snap-name> <channel_names>... snapcraft [options] list-plugins snapcraft [options] tour [<directory>] snapcraft [options] update snapcraft [options] gated <snap-name> snapcraft [options] validate <snap-name> <validation>... [--key-name=<key-name>] snapcraft [options] define <part-name> snapcraft [options] search [<query> ...] snapcraft [options] enable-ci [<ci-system>] [--refresh] snapcraft [options] help (topics | <plugin> | <topic>) [--devel] snapcraft (-h | --help) snapcraft --version
By the time you've finished this tour, you'll know your way around most of these.
Here are the things you should be comfortable with, before you move on. A
snapcraft.yaml describes the snap, and it should be at the top of your directory tree.
The Snapcraft tool will do all the work if you just type
The resulting snap is a single file called
You can install snaps directly with
snap install --dangerous <snapfile.snap>.
Locally created snaps have their own local revisions that are specific to that system.
Snap revisions uniquely identify the exact build of a snap that is installed. snapcraft clean will remove all the build artifacts.
snapcraft.yaml file can optionally be called
02-parts: Snapcraft makes snaps out of parts
When you make a snap, you bundle together all the pieces you want your app to provide for itself, rather than consume them from the base operating system. Normally, that means combining several different pieces of code, because your app probably isn't so simple that it consists of a single piece of code that runs without any supporting components.
snapcraft.yaml of the hello app you'll have noticed a section called parts:
gnu-hello: plugin: autotools source: http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz
This is the simplest possible snap. It has only one part, called
gnu-hello. This part is also just about the simplest kind of part. It only has two attributes; the source code location (which is instructing Snapcraft to pull the source from the gnu.org website) and the plugin to use when building this part, namely
Many parts will specify an explicit file version for the source, as this one does. This ensures that everybody who builds this part gets exactly the same code, because it's fetched from the same file. However, you could point to a source that will change every time there is a new release:
parts: foo-stable: plugin: autotools source: http://releases.foo.org/download/foo-stable.tar.gz
Now, every time someone runs Snapcraft with the foo-stable part, they might get a different codebase from the previous person to build the same part, because the
foo-stable.tar.gz file might have changed. It's generally preferable to be explicit with your parts, so people know what they are getting and can reproduce the snap build process easily.
You can refer to local source as well. For example, you can make a part that refers to a subdirectory where the part source code is kept:
parts: foo-forked: plugin: autotools source: ./src/foo
You can ask Snapcraft itself for a full specification of all the ways to refer to source:
$ snapcraft help sources Common 'source' options. Unless the part plugin overrides this behaviour, a part can use these 'source' keys in its definition. They tell snapcraft where to pull source code for that part, and how to unpack it if necessary. - source: url-or-path A URL or path to some source tree to build. It can be local ('./src/foo') or remote ('https://foo.org/...'), and can refer to a directory tree or a tarball or a revision control repository ('git:...'). - source-type: git, bzr, hg, svn, tar, deb, rpm, or zip In some cases the source string is not enough to identify the version control system or compression algorithm. The source-type key can tell snapcraft exactly how to treat that content. - source-depth: <integer> By default clones or branches with full history, specifying a depth will truncate the history to the specified number of commits. - source-branch: <branch-name> Snapcraft will checkout a specific branch from the source tree. This only works on multi-branch repositories from git and hg (mercurial). - source-commit: <commit> Snapcraft will checkout the specific commit from the source tree revision control system. - source-tag: <tag> Snapcraft will checkout the specific tag from the source tree revision control system. - source-subdir: path Snapcraft will checkout the repository or unpack the archive referred to by the 'source' keyword into parts/<part-name>/src/ but it will only copy the specified subdirectory into parts/<part-name>/build/ Note that plugins might well define their own semantics for the 'source' keywords, because they handle specific build systems, and many languages have their own built-in packaging systems (think CPAN, PyPI, NPM). In those cases you want to refer to the help text for the specific plugin. snapcraft help <plugin>
The more interesting attribute of
gnu-hello is the plugin,
autotools. Snapcraft has a plugin system so that it can drive different build systems for different parts. In this case,
gnu-hello uses the
autotools build conventions — essentially
make install. You can generally snap anything that follows that convention very easily, just use the
autotools plugin for the part.
Snapcraft can tell you which plugins it has installed:
$ snapcraft list-plugins ant copy kernel nodejs tar-content autotools go make python2 catkin jdk maven python3 cmake kbuild nil scons
Each of these plugins knows how to drive a particular set of conventions for a particular build system. The important distinction is that Snapcraft is not itself a build system. It doesn't replace
scons. Instead, a part describes which of those build systems to use, so that Snapcraft can drive the build system that the part author selected.
The next example is a more interesting snap that uses two parts:
$ cd ../02-parts $ more snapcraft.yaml name: hello-debug version: "2.10" summary: GNU Hello with Bash for debugging description: GNU hello prints a friendly greeting. This is part of the snapcraft tour at http://snapcraft.io/create/ apps: hello: command: hello bash: command: bash parts: gnu-hello: plugin: autotools source: http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz gnu-bash: plugin: autotools configflags: ["--infodir=/var/bash/info"] source: http://ftp.gnu.org/gnu/bash/bash-4.3.tar.gz
Now build and install it:
$ snapcraft ... $ sudo snap install --dangerous hello-debug_2.10_*.snap ...
The result is that two apps are exposed:
- The hello app pointing to the hello binary (the command) inside the snap. The command can be executed using
The bash app pointing to the bash binary (command) and is executed using
$ hello-debug.hello $ hello-debug.bash
You'll also see that Snapcraft has created various subdirectories:
parts/ contains one subdirectory for each part:
gnu-hello. Each part's subdirectory has a
src/ directory (to where the code is pulled),
build/ where the build happens, and
make install is processed.
stage/ is where all the content from
parts/<part_name>/install is copied and consolidated in a single directory.
prime/ is the actual snap content. The
stage/ directory is copied there. Binaries are stripped, wrappers are generated by Snapcraft, and the snap metadata files are also generated there. The final
.snap file is just a
squashfs archive of this
prime/ directory. You can use and debug the snap's content from here.
Snapcraft also lets you work with individual commands so you can update and customize your snap. This section looks at some of those options and shows how you could clean and rebuild the gnu-bash part.
clean: resetting individual parts or the whole snap
snapcraft clean removes the directories and data created by Snapcraft. By default it will delete all the directories and data created by Snapcraft from your snap's directory. However, you can use
snapcraft clean <part> to delete a specific part:
$ snapcraft clean gnu-bash Cleaning priming area for gnu-bash Cleaning staging area for gnu-bash Cleaning build for gnu-bash Cleaning pulled source for gnu-bash
As you can see
snapcraft clean has now deleted all your directories from the
$ ls parts gnu-hello
pull: pulling dependencies to refresh code
When the source code in an online or local repository changes you can use
snapcraft pull to pull the updated source code from that repository, remembering to do a
snapcraft clean first. You can pull the code for all your dependencies or only the parts you know have changed by using
snapcraft pull <part>.
$ snapcraft pull Skipping pull gnu-hello (already ran) Preparing to pull gnu-bash Pulling gnu-bash
gnu-hello had already been pulled, when you first built the snap, so it's not pulled again.
As you can see
snapcraft pull has created some new directories and populated
$ ls parts/gnu-bash/** parts/gnu-bash/bin: pkg-config parts/gnu-bash/build: parts/gnu-bash/install: parts/gnu-bash/src: [...] lot of files parts/gnu-bash/state: pull parts/gnu-bash/ubuntu:
build: build a specific part, or all of them
You can use
snapcraft build to build any parts that haven't been built and install them in their part directory, or specify specific parts to be built:
$ snapcraft build Skipping pull gnu-bash (already ran) Skipping pull gnu-hello (already ran) Preparing to build gnu-bash Building gnu-bash ./configure --prefix= --infodir=/var/bash/info [...] Skipping build gnu-hello (already ran)
As you can see
snapcraft build has now populated both the
$ ls parts/gnu-bash/build/ [...] lots of files $ ls parts/gnu-bash/install/ [...] lots of files
stage: move the files installed from different parts into a single directory
Having built all the parts for your snap, use
snapcraft stage to move all the relevant content into stage/ (to prepare for creating the snap package):
$ snapcraft stage Skipping pull gnu-bash (already ran) Skipping pull gnu-hello (already ran) Skipping build gnu-bash (already ran) Skipping build gnu-hello (already ran) Staging gnu-bash Skipping stage gnu-hello (already ran) As you can see snapcraft stage has now added stage/bin/bash: $ ls stage/** stage/bin: bash bashbug hello stage/share: doc info locale man stage/var: bash
prime: move the files needed for the snap into place
Once you're satisfied with the snap created in the
stage/ directory, create the final snap in its correct location using
$ snapcraft prime Skipping pull gnu-hello (already ran) Skipping pull gnu-bash (already ran) Skipping build gnu-hello (already ran) Skipping build gnu-bash (already ran) Skipping stage gnu-hello (already ran) Skipping stage gnu-bash (already ran) Skipping prime gnu-hello (already ran) Priming gnu-bash
As you can see
snapcraft prime has copied the content of
prime/ and added some wrapper and metadata scripts:
$ ls prime/ bin command-bash.wrapper command-hello.wrapper meta share var
However, in most cases once you've cleaned a part from your snap directories you can rebuild the part and snap using
snapcraft, which by default will only rebuild any parts missing from your snap.
snap: compress any directory into a single .snap squashfs file
snapcraft snap command is essential, especially if you craft your own
prime/ directory. The directory name itself doesn't matter, you just need to ensure you provide any required wrapper and meta (
snap.yaml) files, from your build system. Then
snapcraft snap will create a snap from the folder content.
The default action in the Snapcraft lifecycle is to compress the
prime/ directory into a single
.snap squashfs file.
$ snapcraft snap prime/ Snapping 'hello-debug' - Snapped hello-debug_2.10_amd64.snap
In this section of the tour you've seen how a snap:
- Can deliver an application
- Is defined by a single
- Can (and in most cases will) be made up of several parts
- Is created in a number of stages that pull and build parts, before creating the snap package
10 - SNAPS
Now you'll build on the knowledge you've gained about snaps, by looking at the other types of snap app types and some of the key technology that underpins snaps.
01-service: defining services and commands
The example snap in the first part of this guide delivered a simple terminal application. However, you can deliver any type of application or service with a snap that you might do with a standard deb package. This example shows how you do this for a service:
$ cd ../../10-SNAPS/01-service $ snapcraft $ sudo snap install --dangerous hello-world-service_0.1_*.snap --devmode hello-world-service 0.1 installed $ snap info hello-world-service name: hello-world-service summary: "A hello world style nodejs webserver app" publisher: description: | This example demonstrates how to have nodejs webserver. This is part of the snapcraft tour at http://snapcraft.io/create/ tracking: installed: 0.1 (x1) 11MB devmode refreshed: 2016-12-15 09:20:04 +0100 CET
--devmode will be explained in the next chapter, so for now open http://localhost:8000 in your browser and you'll find the running web service.
The key components of
snapcraft.yaml that enabled this are:
parts: hello: plugin: nodejs source: .
Here the hello part uses the nodejs plugin, a plugin to handle Node.js projects. It takes all the npm information from
apps: hello-service: command: hello-world daemon: simple
hello-service app is declared and specified as a simple (i.e. non-forking) daemon (a service that starts at boot and keeps running on your system). This daemon executes the
02-service-confined: confinement and devmode
You may have noticed the
--devmode option was used in snap install. Reinstall the snap without it:
$ sudo snap install --dangerous hello-world-service_0.1_*.snap error: cannot perform the following tasks: - Mount snap "hello-world-service" (unset) (snap "hello-world-service" requires devmode or confinement override)
The snap has failed to install because its
snapcraft.yaml declares it needs to run in
$ more snapcraft.yaml [...] confinement: devmode
All snaps run confined by default. They're able to access any functions in the snap and data written to their own private writable area, but have restricted and secured access to the system.
The hello world service needs to listen to the network (a restricted and secured part of the system), but hasn't been setup with the additional permissions to do so yet.
To simplify development,
--devmode enables you to run the snap outside the confinement sandbox and get unrestricted access to system resources, in this case, listening to the network. However, you do need to tell the snap that it requires devmode, by making a
devmode declaration in
This enables quick iteration to perfect the functionality of the snap before you need to worry about making it work under confinement. It should be noted that snaps uploaded to the store with confinement set to devmode are not visible with the snap find command. However, devmode snaps can still be installed if you specify the exact snap name.
plugs-and-slots: integration with the system and other snaps
However, once you're happy with the functionality of your snap you'll need to focus on its confinement.
To enable snaps to access external resources (or make their own resources available to other snaps) a system of plugs and slots is used. A plug is a request for access to an external interface, while a slot is an interface provided by the snap.
hello-world-service snap needs to have access to the network, so it can listen for and serve requests, this access is requested using the [
network-bind] plug. This plug is then declared in the
network-bind plug essentially pokes a hole in the otherwise-complete confinement, telling snappy that this snap requires access to the network through the
network-bind interface. The plug then connects to the network-bind slot provided by the base OS as an helper.
So now, without using
--devmode, you can run the confined version of the hello world service:
$ cd ../02-service-confined $ snapcraft $ sudo snap install --dangerous hello-world-service_0.1_*.snap hello-world-service 0.1 installed
Open your browser at http://localhost:8000, the application looks identical to the previous example.
Finally, there has been one further very important change made to the
To indicate that this snap is now confined.
structure: the directory layout of a snap
Now you've got to grips with some basic and advanced snap features, it's worth gaining an understanding of what's inside a snap. And seeing the snap's content is easy, as it's all in the
$ ls prime/** prime/CHANGELOG.md prime/command-hello-service.wrapper prime/LICENSE prime/README.md prime/bin: hello-world node npm prime/etc: prime/include: node prime/lib: node_modules prime/meta: snap.yaml prime/share: doc man systemtap
Most of the content should be self explanatory, the obvious components to deliver the Node.js capabilities and the service. However the two highlighted files may not be so obvious.
wrapper: defining how the binaries are launched
This file (
prime/command-hello-service.wrapper) provides a small wrapper that will launch the real binaries: typically a small shell script that sets
LD_LIBRARY_PATH or other runtime specific environment variables. Snapcraft generated these wrappers for you.
metadata: snap.yaml defines the properties of a snap
snap.yaml file provides the configuration file for the snap's content and is similar to the
snapcraft.yaml file, with two exceptions:
$ more prime/meta/snap.yaml apps: hello-service: command: command-hello-service.wrapper daemon: simple plugs: - network-bind architectures: - amd64 confinement: strict description: This example demonstrates how to have nodejs webserver. This is part of the snapcraft tour at http://snapcraft.io/create/ grade: stable name: hello-world-service summary: A hello world style nodejs webserver app version: 0.1
The first exception is that
snap.yaml includes a specification of the architecture that the snap has been built for (highlighted). The second difference is that there is no parts definition (as the parts are now in the snap and no longer need to be defined).
Armed with this information you can, if you wish, build your snap package more directly by:
- Creating a
- Adding the built assets and code
- Adding a wrapper file
snapcraft snap prime/
And you'll have a hand crafted snap file.
You've now added some depth to your knowledge of snaps and learned about:
- Delivering services (in addition to apps) in your snaps
- How all snaps are confined (unable to access system resources) but can be unconfined with
--devmodeto simplify development
- How plugs and slots enable snaps to consume resources outside the confinement (or make their own resources available to other snaps)
- The structure of a snap's content and the option to hand build a snap
20 - PARTS & PLUGINS
You first met parts at the start of this guide and have been working with them in all the examples so far. So, it's time to take a closer look at how parts work and the options they provide you. Then there are a couple of references for plugins, in case you would like to explore further.
parts-intro: a "part" is a reusable component of a snap
Parts are reusable components that can be used when building a snap. They're analogous to a library that you would call in your program. There are three types of parts:
Parts from local source that use local files on your machine. For example (as seen in
parts: hello: plugin: nodejs source: .
Parts from online sources, such as
tarball, or any code repository you like. For example:
parts: godd: plugin: go source: https://github.com/mvo5/godd.git gnu-hello: plugin: autotools source: http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz
You've already seen the last part in
To see parts built and shared by others — https://wiki.ubuntu.com/snapcraft/parts
The features of parts shared by this last method are the focus of our next example:
$ cd ../../20-PARTS-PLUGINS/01-reusable-part $ snapcraft $ sudo snap install --dangerous hello-world-desktop_0.1_*.snap
Which can be run with the
hello-world-desktop command as defined in the
hello-world-desktop: command: qt5-launch hello-world-desktop
But notice this involves an extra tool
qt5-launch, which prepares the environment for launching the real application. These
hello-world-desktop commands come from:
parts: hello-world: plugin: cmake source: src/ build-packages: - qtbase5-dev stage-packages: # Here for the plugins-- they're not linked in automatically. - libqt5gui5 after: [qt5conf] # A part in the cloud
In this part definition:
build-packageslists the dependencies needed to build the contents of the snap. These aren't packed into the final snap.
qtbase5-devhas been specified here since that package contains the headers, libraries, and tools needed to build the app
stage-packageslists the dependencies needed to actually run the contents of the snap. They'll be packed into the final snap. Here, the requirement is for the hello-world part to download and unpack
libqt5gui5with all its dependencies. This method can reuse any of the 48000 .deb packages that traditional Ubuntu provides. It's really that easy: just specify the packages you need embedded into your snap
qt5conf] lists the parts that must be staged before this part can be built. However, you may have noticed that this YAML doesn't actually contain the
qt5confpart. That's because it's a part in the cloud, which is a way for collaborating, reusing, and sharing already-written parts. The previously mentioned
qt5-launchtool comes from the
qt5confpart, without any additional effort from you. This way you can make use of and build upon what others have created
sharing: sharing your parts with other developers
If you would like to publish your own parts, you can contribute them on the wiki at https://wiki.ubuntu.com/snapcraft/parts.
Your contributions will always be welcome!
plugins: each part is built using a snapcraft plugin
Plugins tell Snapcraft how to build the content of the snap's parts. You'll probably use the supplied plugins for most of your snaps. However, you can add your own plugins for other languages. Details of how to do this are beyond this get started, but if you would like to explore more here are a couple of plugin examples and basic building details:
autoconf-make: the standard "configure, make, make install" plugin
Get more info from:
$ snapcraft help autotools $ snapcraft help make
golang: the Golang plugin
Get more info from:
$ snapcraft help go x-plugins: Local plugins
You can build your own plugin and reference it from your part. To do this, copy your plugin into
parts/plugins/x-<plugin_name>.py. Get inspiration from https://github.com/ubuntu-core/snapcraft/blob/master/snapcraft/plugins/go.py
30 - STORE
In order to share your snaps with the world, you will need to publish them in the Store. First, create an account on https://myapps.developer.ubuntu.com/. This is your developer portal. Here you can customize how your snap is presented, review each new upload, and control publishing.
You'll need to choose a unique developer namespace as part of the account creation process. In a future version, developer branches of reserved name snaps will be referred to by this name (for example firefox@mark).
Once you've confirmed your account, you're ready to start pushing your snaps to the Store. Make sure Snapcraft and snap know about you by logging in using the email address you provided at signup:
$ snapcraft login $ sudo snap login firstname.lastname@example.org
devspace: you can generally publish your own version of a snap
You can publish your own version of a snap, provided you do so under a name you have rights to. New names can be registered by clicking the New Snap button on the developer portal, or by visiting: https://myapps.developer.ubuntu.com/dev/click-apps/register-name/
Use "hello-" suffixed by your name for this exercise (for example hello-mark), since you don't have rights to the "hello" snap name.
names: you can reserve names for software you publish
You can follow the same registration process for names that you have rights.
We can, if needed, rename snaps to ensure they match the expectations of most users. If you are the publisher most users expect for a name then claim it at: https://myapps.developer.ubuntu.com/dev/click-apps/register-name-dispute/
revisions: you get a new revision every time you push
Once you've registered your snap name, go back to your
snapcraft.yaml file and update the name field. Run Snapcraft again to quickly rebuild with the new name. With that done, the new revision of your snap can be uploaded to the Store:
$ snapcraft push hello-world_1.0_*.snap
publication: users only see your published revisions
Uploading your snap won't make it immediately available for installation. You'll have to choose the channel(s) you wish to release into.
There are four channels available for your use:
- Stable is what most users will consume and as the name suggests, should be your most polished and tested versions
- Candidate is used to vet uploads that should require no further code changes before moving to stable
- Beta is used to provide preview releases of semi-stable changes
- Edge is for your most recent changes, probably untested and with no guarantees attached
Open the URL that was returned from
snapcraft push or open the snap from the developer portal front page: https://myapps.developer.ubuntu.com
You should see the 1.0 version in the lefthand column. Clicking on that link will bring up further details about this revision. Here you can edit the list of channels it should be released into.
Click on the
Edit link next to the Channels field. In the page that appears, select
Stable and click
Your upload is now ready to be released into the stable channel. Click the
Publish button on the page you return to.
The build you uploaded is now the selected revision in the stable channel, meaning that installs of your snap will select this upload by default.
You can confirm this by installing the snap locally, replacing '
hello-mark' with your snap name:
$ snap install hello-mark Name Version Rev Developer hello-mark 1.0 1 sabdfl
Note that, now that the snap has been published in the store, we no longer need the
40 - CONFINEMENT
confinement: specify how the snap can be used with the security sandbox
By default snaps run in a restrictive sandbox to ensure that snaps only access the system and other snaps in controlled ways. confinement is used in
snapcraft.yaml to specify whether or not the snap is expected to work correctly when the specified interfaces are connected and the snap is confined. You specify strict to indicate the snap works properly when confined or devmode to indicate it only works properly when unconfined. If confinement is unspecified, the snap is assumed to work correctly when confined since developers are expected to develop their snaps for running in the sandbox. You're only allowed to upload snaps to the stable channel when strict confinement is used.
When first making a snap it is often useful to specify confinement: devmode in your YAML like so:
name: hello-world-service confinement: devmode apps: hello-service: command: command-hello-service.wrapper daemon: simple plugs: - network-bind ...
You then would specify
--devmode when installing the snap for testing and development (you must always specify
--devmode when installing in devmode regardless of how confinement is set in your yaml). Once the application is working well in devmode, install it without specifying
--devmode and iterate until it is working properly under confinement. When satisfied, you may indicate it works under confinement with:
name: hello-world-service confinement: strict apps: hello-service: command: command-hello-service.wrapper daemon: simple plugs: - network-bind ...
When debugging your snap when it is installed in strict mode (without
--devmode), you can look in
/var/log/syslog for sandbox denials. Alternatively, you may use the '
snappy-debug' snap to assist you:
$ sudo snap install snappy-debug $ sudo snap connect snappy-debug:log-observe ubuntu-core:log-observe $ sudo /snap/bin/snappy-debug.security scanlog hello-world-service
This scanlog command will tail the syslog and make suggestions on what interfaces to use and suggest changes to make to your snap so it will work within the sandbox.