Packaging up a Go app as a snap
After building my first Python snap I was asked to try to build a Go snap.
There is a video about building Go snaps with snapcraft here so after watching it I gave Kurly a try.
First of all I got familiar with the code and got it on my PC:
$ git clone https://github.com/davidjpeacock/kurly.git
I entered the kurly directory:
$ cd kurly
I created a snap directory and entered it:
I created a snapcraft.yaml file with the go plugin (plugin: go):$ mkdir snap
$ cd snap
name: kurly
version: master
summary: kurly is an alternative to the widely popular curl program.
description: |
kurly is designed to operate in a similar manner to curl, with select features. Notably, kurly is not aiming for feature parity, but common flags and mechanisms particularly within the HTTP(S) realm are to be expected.
confinement: devmode
apps:
kurly:
command: kurly
parts:
kurly:
source: .
plugin: go
go-importpath: github.com/davidjpeacock/kurly
The go-importpath keyword is important and tells the checked out source to live within a certain path with 'GOPATH'. This is required to work with absolute imports and path checking.
I went back to the root of the project and launched the snapcraft command to build the snap:
$ cd ..
$ snapcraft
Once snapcraft has finished building you will find a kurly_master_amd64.snap file in the root directory of the project.
I installed the kurly snap in devmode to test it and see if worked well in non confined mode so that then I could run it in confined mode and add the plugs needed by the snap to work properly:
$ sudo snap install --dangerous --devmode kurly_master_amd64.snap
If you run:
$ snap list
you will see the kurly snap installed in devmode:
Name Version Rev Developer Notes
core 16-2 2312 canonical -
kurly master x1 devmode
Now i tried kurly out a bit to see if it worked well, for instance:
$ kurly -v https://httpbin.org/ip$ kurly -R -O -L http://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-8.7.1-amd64-netinst.iso
Ok fine, it worked so now I tried to install it in confined mode changing the snapcraft.yaml file accordingly (confinement: strict).
I ran snapcraft again and installed the snap:
$ snapcraft
$ sudo snap install --dangerous kurly_master_amd64.snap
You can see from the snap list command that the app is installed not in devmode anymore:
$ snap list
Name Version Rev Developer Notes
core 16-2 2312 canonical -
kurly master x2 -
I tried out kurly again and got some errors:
$ kurly -v https://httpbin.org/ip> GET /ip HTTP/1.1
> User-Agent [Kurly/1.0]
> Accept [*/*]
> Host [httpbin.org]
*Error: Unable to get URL; Get https://httpbin.org/ip: dial tcp: lookup httpbin.org: Temporary failure in name resolution
From the error I could understand that kurly needs the network plug (plugs: [network]) so I changed the snapcraft.yaml file so:
name: kurly
version: master
summary: kurly is an alternative to the widely popular curl program.
description: |
kurly is designed to operate in a similar manner to curl, with select features. Notably, kurly is not aiming for feature parity, but common flags and mechanisms particularly within the HTTP(S) realm are to be expected.
confinement: strict
apps:
kurly:
command: kurly
plugs: [network]
parts:
kurly:
source: .
plugin: go
go-importpath: github.com/davidjpeacock/kurly
I ran snapcraft and installed the kurly snap again:
But when I ran a kurly command for downloading a file I got another error:$ snapcraft
$ sudo snap install --dangerous kurly_master_amd64.snap
Kurly could not write the file to my home direcotry, so I added the home plug to the snapcraft.yaml file, ran snapcraft and installed the snap again.$kurly -R -O -L http://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-8.7.1-amd64-netinst.iso
*Error: Unable to create file 'debian-8.7.1-amd64-netinst.iso' for output
This time kurly worked fine.
So here's the final snapcraft.yaml file ready for a PR in Git Hub:
name: kurly
version: master
summary: kurly is an alternative to the widely popular curl program.
description: |
kurly is designed to operate in a similar manner to curl, with select features. Notably, kurly is not aiming for feature parity, but common flags and mechanisms particularly within the HTTP(S) realm are to be expected.
confinement: strict
apps:
kurly:
command: kurly
plugs: [network, home]
parts:
kurly:
source: .
plugin: go
go-importpath: github.com/davidjpeacock/kurly
That's it.
The Go snap is done!