Snapcraft makes use of LXD and Multipass to both simplify the build process and to confine the build environment. LXD and Multipass are referred to as providers because they provide snapcraft with build environments.
Depending on which core you’re using as a base for Snapcraft, are a handful of ways to declare which provider to use.
On Linux, LXD is the default provider. On other systems (macOS and Windows), Multipass is the default.
There are three ways to choose a different provider. The following table is ranked by precedence, so for example a provider chosen by the first method overrides the second and third method, and so on.
Method | Priority | Command |
---|---|---|
Command-line argument | 1 | --use-lxd |
Environmental variable | 2 | SNAPCRAFT_BUILD_ENVIRONMENT=<provider-name> |
Snap configuration of Snapcraft | 3 | snap set snapcraft provider=<provider-name> |
On all platforms, Multipass is the default provider.
There are four ways to choose a different provider. The following table is ranked by precedence, so for example a provider chosen by the first method overrides the second and third method, and so on.
Method | Priority | Command |
---|---|---|
Command-line argument | 1 | --provider=<provider-name> |
Environmental variable | 2 | SNAPCRAFT_BUILD_ENVIRONMENT=<provider-name> |
Command-line argument | 3 | --use-lxd |
Snap configuration of Snapcraft | 4 | snap set snapcraft provider=<provider-name> |
The snap configuration method mentioned in the previous sections is a feature of Snap.
Like most snaps, Snapcraft isn’t installed with any default configuration values. As a result, you won’t be able to check the provider programmatically if you haven’t already set it on the system.
To set the provider, run snap set snapcraft provider=<provider-name>
where <provider-name>
can be lxd
or multipass
.
To check the provider after it’s been set, run snap get snapcraft provider
.
To unset the provider, run snap unset snapcraft provider
.
If LXD is not installed, snapcraft will prompt the user if they’d like to automatically installed and configure LXD. If LXD is not installed while running in a non-interactive mode (running from a CI/CD pipeline), snapcraft will log an error and exit.
Recent non-desktop versions of Ubuntu install LXD by default - you can check whether it is installed with the following command:
$ lxd version
5.6
A brief overview of installation and configuration is listed below. For more details and information, see the LXD docs.
LXD can be installed via its snap:
$ sudo snap install lxd
Next, initialise LXD with the following command and accept all the default options unless you have specific requirements:
$ sudo lxd init
If the system you are installing LXD onto is using a network with a 10.x.x.x
subnet then network create may fail. Step through the following to resolve this.
If you try to run lxd init
on a system that is connected to a network with a 10.x.x.x
subnet, then the final step of the init* may fail with the following error:
Error: Failed to create network 'lxdbr0': Failed to automatically find an unused IPv4 subnet, manual configuration required
To resolve this issue, you must manually create the network with the following command:
$ sudo lxc network create lxdbr0 ipv4.address=10.0.3.1/24 ipv4.nat=true
You can then re-run lxd init
. When you are prompted to create a new network bridge you must respond no
.
Would you like to create a new network bridge (yes/no) [default=yes]? no
If you want to build snaps as a non-root user, which is advised, then you need to add your user account to the lxd
group:
$ sudo usermod -a -G lxd ${USER}
You now need to either restart your session, reboot your computer, or use newgrp
to acquire the new group assignment:
$ newgrp lxd
The newgrp command will start a new sub-shell (shell within a shell) with the new lxd
group assigned.
Snapcraft uses caching to speed up build times with LXD. On the first run, snapcraft creates a generic build environment for LXD and saves it locally as a LXD image.
When building a new snap or after running snapcraft clean
, this cached image is used as a starting point for the new environment.
If Multipass is not installed, snapcraft will prompt the user if they’d like to automatically installed and configure Multipass. If Multipass is not installed while running in a non-interactive mode (running from a CI/CD pipeline), snapcraft will log an error and exit.
Multipass can be installed via it’s snap:
$ sudo snap install multipass
With Multipass, the default virtual machine is assigned 2 CPUs and 2GB of memory. If you have the hardware capabilities, use the following environment variables to modify CPU and memory allocation to improve performance:
$ export SNAPCRAFT_BUILD_ENVIRONMENT_CPU=8
$ export SNAPCRAFT_BUILD_ENVIRONMENT_MEMORY=16G
These environmental variables are not supported when building a core22
snap.
Debugging a problematic build can require entering the build environment. Snapcraft provides the commands --shell
, --shell-after
, and --debug
to allow the developer to quickly enter a shell inside the build environment. See Iterating over a build for more details.
Build environments are re-used for every build of the same snap. If the snapcraft.yaml or source is changed significantly, the environment may need to be cleaned.
A build environment can be cleaned with snapcraft clean
. This deletes the environment. The next time snapcraft runs, a new environment will be used.
Running snapcraft clean <part-name>
only cleans directories for a particular part. The environment will still be reused.
These instructions are intended to be only a general guide. For further details on using LXD as a container environment, see the LXD Documentation.
First, create and run a new container based on Ubuntu 22.04 LTS. Our example calls this container mysnapcraft:
$ lxc launch ubuntu:22.04 mysnapcraft
Copy your snap’s snapcraft.yaml to this new container:
$ lxc file push snap/snapcraft.yaml mysnapcraft/home/ubuntu/
Now open an interactive shell within your container and install snapcraft:
$ lxc exec mysnapcraft -- /bin/bash
$ snap install snapcraft --classic
Finally, staying within the container, start the build by running snapcraft with the --destructive-mode
argument. This forces snapcraft to build the snap directly within the current host (the mysnapcraft LXD container):
$ cd /home/ubuntu
$ snapcraft --destructive-mode
You can troubleshoot the build process just as you would on the native machine. The container is persistent and will remain until stopped and deleted.
With the build complete, you can copy your new snap to your native environment with the following command:
$ lxc file pull mysnapcraft/home/ubuntu/mysnap.snap .
Last updated a month ago.