I’ve been working through trying to get my Python 3.6 application which has a command-line interface to be packaged with Snap. I’ve managed to solve most problems through a combination of the documentation and brute force. However, I think I am stuck on the last hurdle.
I’ve managed to install both Python 3.6 and then my application using parts. But my apps command appears to be isolated from the build parts so I’m unable to get the command to call my python program.
As I understand it the final build will not contain any of the things created in the parts and I need to specify what I want to bring over (using things like prime
). However, I can’t seem to figure out exactly how.
Here’s what I have currently:
name: mzo
version: '0.0.1'
summary: my summary
description: |
My description.
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
apps:
mzo:
command: /usr/local/bin/mzo
plugs: [network, network-bind]
parts:
python36:
plugin: nil
stage-packages:
- make
- zlib1g-dev
- openssl
- libssl-dev
- libffi-dev
source: https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xz
source-checksum: md5/9f49654a4d6f733ff3284ab9d227e9fd
override-build: |
./configure --enable-optimizations
make
sudo make install
mzo:
after: [python36]
plugin: nil
source: https://github.com/jamesstidard/Mzo-Cli/archive/v0.0.5.tar.gz
source-checksum: sha256/ad70091661bc3bf920022b59423999d82c7f050338832f14c84a3044a431d48c
override-build: |
/usr/local/bin/python3 -m pip install --upgrade pip wheel setuptools pipenv
pipenv lock --requirements > requirements.txt
/usr/local/bin/python3 -m pip install -r requirements.txt
Any pointers would be very much appreciated; I’m not getting very far very fast.
Thanks
The command must not be anchored to the root directory because that will be outside of your snap’s readable filesystem. If you install your mzo
into your snap at usr/local/bin/mzo
then you may reference it as:
apps:
mzo:
command: usr/local/bin/mzo
Note that this will be in your snap’s filesystem, such that when you run it the command will expand to $SNAP/usr/local/bin/mzo
where $SNAP
points into your snap.
Here you’re running commands outside of the snap build directory, so the resulting files will not be added into your snap. You need to use the python
plugin and the requirements:
key to install the requirements and your application into $SNAPCRAFT_PART_INSTALL
. From there snapcraft will copy the files into $SNAPCRAFT_STAGE
followed by ./prime
before finally packaging the ./prime
directory into a .snap
file:
parts:
mzo:
plugin: python
python-version: python3
source: https://github.com/jamesstidard/Mzo-Cli/archive/v0.0.5.tar.gz
requirements: requirements.txt
You can generate the requirements.txt
using the method you already are if you do not include it directly in the download and then call back into snapcraft to run the build:
override-build: |
pipenv lock --requirements > requirements.txt
snapcraftctl build
Even better would be to generate the requirements.txt
at pull
so that snapcraft can discover it before running the build:
override-pull: |
snapcraftctl pull
pipenv lock --requirements > requirements.txt
Hi @lucyllewy, really appreciate the help and the detail. I will give this a shot this evening.
I am building Python 3.6 and not using the Python plugin as my code has some 3.6 specific syntax and I believe the plugin currently only supports 2.7.x and 3.5.x.
If I want to use 3.6 should I then be installing python to somewhere like $SNAPCRAFT_PART_INSTALL/python. Or maybe it is easier to fork the existing Python plugin and edit it to use 3.6.
Thanks again.
You could wait till building against core18
works out of the box, but I’m not sure how far away that is yet…
Alternatively, your theory about using a modified plugin is actually a good one. The process to do so is to find the snapcraft plugin’s source (if you installed snapcraft as a snap then it’s at less /snap/snapcraft/current/lib/python3.5/site-packages/snapcraft/plugins/python.py
) and copy that into your project so that it is inside a directory called plugins
, which sits alongside your snapcraft.yaml
:
project/
- snap/
- plugins/
- x-python.py
- snapcraft.yaml
Here I’ve called the plugin x-python
so that is the name you need to use in your snapcraft.yaml
instead of python
- this is to prevent undefined behaviour where the python plugin might exist in two places.