Saturday, July 15, 2017


My first Snap 


I have been testing for Ubuntu for quite a while so I decided to change a bit and give packaging apps  a go, so here I am writing about how I managed to create my first Python Snap.

Snapcraft is new way to package apps and so I thought it would be nice to learn about it, so I went to the Snapcraft site https://snapcraft.io/ and found out, that with Snapcraft you can:
"Package any app for every Linux desktop, server, cloud or device, and deliver updates directly".

"A snap is a fancy zip file containing an application together with its dependencies, and a description of how it should safely run on your system, especially the different ways it should talk to other software.
Snaps are designed to be secure, sandboxed, containerised applications isolated from the underlying system and from other applications. Snaps allow the safe installation of apps from any vendor on mission critical devices and desktops."

So if you got an app that is too new for the Ubuntu archive, you can get it in the Snaps store and install it on Ubuntu or any other Linux distribution  that supports Snaps.

I started by getting in touch with the guys in the Snapcraft channel on Rocket chat:  https://rocket.ubuntu.com/channel/snapcraft that told me to how to start.

First of all I read the "Snap a Python App" tutorial and then applied what I learned to Lbryum a Lightweight lbrycrd client, a fork of the Electrum bitcoin client.

I couldn't believe how easy it was, I am not a developer but  I know how to code and I know a bit of Python.

First of all you need to get familiar with the code of the app you want to snap so I got Lbryum code from Git Hub:

$ sudo apt install git
$ git clone https://github.com/lbryio/lbryum.git


Once I got familiar with the code I installed Snapcraft:

 $ sudo apt install snapcraft

I generated a Snapcraft projet in the lbryum root directory with:

$ snapcraft init

If everything works, you will get this output:

Created snap/snapcraft.yaml.
Edit the file to your liking or run `snapcraft` to get started
 
Now if you check the content of the project's directory, it has been populated with  a "snap" folder containing the snapcraft.yaml file  that I modified  for creating the Lbryum app snap:


name: lbryum 
version: 'master'
summary: Lightweight lbrycrd client
description: |
        Lightweight lbrycrd client, a fork of the Electrum bitcoin client
grade: stable 
confinement: devmode 

apps:
  lbryum:
     command: lbryum
  parts:
  lbryum:
     source: . 
     plugin: python
      
Here is the documentation so you can find the meaning of the fields in the snapcraft.yaml file (the fields are quite self explanatory): 



To find out what plugs or parts your app needs, you need to run snapcraft and debug it until you find out all that's needed, so I tried to build it at this stage to make sure that I had the basic definition correct. 

I ran this command from the root of the lbryum-snap directory:

$ snapcraft prime

Obviously I had some errors  that made me make some changes to the snapcraft.yaml file. I found out that the app needs Python2 so I added "python-version: python2" and I specified to use the requirements.txt file of the Lbryum project for the packages needed during install (requirements: requirements.txt):
 
name: lbryum 
version: 'master'
summary: Lightweight lbrycrd client
description: |
        Lightweight lbrycrd client, a fork of the Electrum bitcoin client
grade: stable 
confinement: devmode 

apps:
  lbryum:
     command: lbryum
parts:
  lbryum:
     source: . 
     plugin: python
     requirements: requirements.txt
     python-version: python2
I  ran:

$ snapcraft clean 

and 
 
$snapcraft prime
 again.



Success!!!! :)

Ok, so now I tried the snap with:

$ sudo snap try --devmode prime/
$ lbryum daemon start
$ lbryum version
$ lbryum commands

played a bit around with it to see if the snap worked well.

Now before shipping the snap or opening a PR in Git Hub, we need to turn confinement on and see if the snap works or if it needs further changes to the snapcraft.yaml file.

So I changed the confinement from devmode to strict (confinement: strict) and then ran:

$ snapcraft

I got this output:

Skipping pull lbryum (already ran)
Skipping build lbryum (already ran)
Skipping stage lbryum (already ran)
Skipping prime lbryum (already ran)
Snapping 'lbryum' -                                                           
Snapped lbryum_master_amd64.snap
I installed the snap:

$ sudo snap install --dangerous lbryum_master_amd64.snap

When I ran lbryum I started getting a lot of errors that made me understand that lbryum needs to access the network for working so I added the network plug (plugs: [network]) : 
name: lbryum 
version: 'master'
summary: Lightweight lbrycrd client
description: |
        Lightweight lbrycrd client, a fork of the Electrum bitcoin client
grade: stable 
confinement: strict 

apps:
  lbryum:
     command: lbryum
     plugs: [network]
parts:
  lbryum:
     source: . 
     plugin: python
     requirements: requirements.txt
     python-version: python2
I ran:

$ snapcraft

again and installed the snap again:

$ sudo snap install --dangerous lbryum_master_amd64.snap
$ lbryum daemon start
$ lbryum version
$ lbryum commands

Works!

Fine, so I opened a PR on Git Hub proposing my snapcraft.yaml file so that they could use it for creating a Lbryum snap.



If you need to debug your snap for finding what is wrong there is also a debugging tool for debugging confined apps:

https://snapcraft.io/docs/build-snaps/debugging


Thats it. End of my first snap adventure :).

1 comment: