This is a bit of a dayjob post, but as I maintain a bunch of snaps in my own time, I figured it’s not out of place here.
Typically when I (or indeed any developer) uses snapcraft
to build a snap, a snapcraft.yaml
drives the process. I’ll integrate some kind of CI or build system, and start publishing to the Snap Store. Usually, once created, the yaml doesn’t need much in the way of changes. Back when we first started building snaps, we were using Ubuntu 16.04 LTS systems. At runtime the snap would leverage the base
of core
. The core
snap is a super minimal Ubuntu 16.04 LTS runtime environment.
Since then we’ve had releases of core18
based on Ubuntu 18.04 LTS and more recently, core20
based off Ubuntu 20.04 LTS. The observant will note the original base core
isn’t called core16
which is a shame, but hey-ho. In the early days it wasn’t necessary to specify a base
in the snapcraft.yaml
because it was assumed to always be core
. Indeed I don’t think early releases of snapcraft
even had a base
option.
Since then snapcraft
has been re-engineered and restructured such that specifying base
makes it behave differently than if you don’t specify one at all. Effectively not specifying a base
gives backwards-compatibility so existing snaps continue to build. However the newer features and optimisations that land in snapcraft
are only in the codepath where a base
is specified.
So to get access to these juicy features, we reccommend developers migrate their snaps from not specifying a base, to specifying one, specifically one newer than Ubuntu 16.04 LTS. Specifying a newer base
like core18
or core20
means that as well as newer snapcraft
, the publisher also gets access to updated packages from the Ubuntu 18.04 or 20.04 archives.
Sadly it’s not just a case of adding base: core20
and you’re done. There’s a few other things that need adjusting. We’re working on comprehensive documentation to cover all of the.. uh.. bases, but below you’ll find a taster.
I noticed the cointop snap wasn’t using a base
. By “noticed”, I grepped:
alan@robot:~$ snap install cointop
cointop 0a0530d from Miguel Mota (miguelmota) installed
alan@robot:~$ grep ^base /snap/cointop/current/meta/snap.yaml
alan@robot:~$
No base
found implies core
which is Ubuntu 16.04 LTS based, as mentioned earlier. So what did I do to update it? Here’s the diff.
-version: master
-version-script: git -C parts/cointop/build rev-parse --short HEAD
+adopt-info: cointop
summary: Interactive terminal based UI application for tracking cryptocurrencies
description: |
cointop is a fast and lightweight interactive terminal based UI application for tracking and monitoring cryptocurrency coin stats in real-time.
grade: stable
confinement: strict
+base: core20
parts:
- go:
- source-tag: go1.14
cointop:
- after: [go]
source: .
plugin: go
- go-importpath: github.com/miguelmota/cointop
+ build-packages:
+ - git
+ override-pull: |
+ snapcraftctl pull
+ snapcraftctl set-version $(git rev-parse --short HEAD)
apps:
cointop:
- command: cointop
+ command: bin/cointop
plugs:
- network
- network-bind
Let’s break it down!
The version-script
option is deprecated, replaced by adopt-info
and snapcraftctl set-version
inside the override-pull
section.
-version: master
-version-script: git -C parts/cointop/build rev-parse --short HEAD
+adopt-info: cointop
The override-pull
is a series of commands which can be run to override the pull stage of the snapcraft
lifecycle. Here we yoink the git revision and use that as the version number on the built snap.
+ override-pull: |
+ snapcraftctl pull
+ snapcraftctl set-version $(git rev-parse --short HEAD)
The go
plugin pulls in a newer golang, so we don’t need to have a separate part which forces us to get a newer go
binary than shipped in Ubuntu 16.04 LTS. Further, the go-importpath
is no longer required, simplifying this section.
- go:
- source-tag: go1.14
cointop:
- after: [go]
source: .
plugin: go
- go-importpath: github.com/miguelmota/cointop
Somehow the old version of snapcraft
or maybe the go
part was pulling in a git
binary from somewhere. We try not to automagically do stuff that is unexpected. So I need to be explicit that we need the git
build package as part of the build. So I added that.
+ build-packages:
+ - git
The newer snapcraft
code-path is more strict on explicitly specifying binary locations in the apps
section. As the cointop
binary ends up in $SNAP/bin
we just need to prepend bin/
to solve this.
- command: cointop
+ command: bin/cointop
Oh, and we need to actually add the new base
.
+base: core20
That’s it. I submitted this as a pr on the upstream project.
Other snaps will certainly require more invasive changes, but I thought this would be a good example of a simple snap which only needed a few updates to bring it up to spec.