Adventures in classic Python snaps, part II

Barry Warsaw barry at
Fri Mar 17 21:25:03 UTC 2017

A few days I asked about classic snaps and problems I was having turning
ubuntu-image into a classic snap (from devmode).  For the recently released
u-i 1.0 I thought I'd solved the problem, and had an autopkgtest to prove it.
Since then I realized the problem was *not* solved and the autopkgtest had
some dependency pollution that caused it to succeed when it should have
failed.  I've fixed that, but now I'm finding that classic Python snaps don't
work -at least not in the way I'd expect.

For reference, here's a baseline snapcraft.yaml that "works":

-----snip snip-----
name: ubuntu-image
summary: Create Ubuntu images
description: |
  Use this tool to create Ubuntu images.
version: 1.0+snap2
grade: stable
confinement: classic

    command: usr/bin/ubuntu-image

  PATH: $SNAP/usr/bin:$PATH

    plugin: python
    source: .
      - PyYAML
      - attrs
      - voluptuous
      - usr
      - lib
      - sbin
      - e2fsprogs
      - mtools
      - python3-debian
      - python3-parted
      - util-linux
      - ubuntu-image
    plugin: go
    source-type: git
      - bin/snap
-----snip snip-----

I was pointed to LP: #1670388 which helped me understand that I have to set
$PATH (as seen in the `environment` section) so that the 'python3'  found in
the script's shebang is the one inside the snap, not the one in the system.
That's good enough to not *also* require $PYTHONPATH afaict.

This only works for Zesty; it fails in Yakkety and Xenial, presumably because
of LP: #1665756.  The bug says this is fixed in snapd 2.23, which is available
atm only in zesty, yakkety-proposed, and xenial-proposed.

There are a few other things to note.

I don't think we need the snapd part.  Isn't it guaranteed that if someone is
running a classic snap, that /usr/bin/snap *must* be installed on their
system?  It does seem to work when I remove that part, but I want to make sure
that autopktest package pollution isn't causing a false positive.

There's one big cheat here.  I had to put ubuntu-image in stage-packages
because afaict, for classic snaps, the Python snapcraft plugin does not
arrange for the ubuntu_image Python package to live in stage, and thus it
doesn't get into prime.  I don't think there's anything you could add to a
`stage` section that would make that work.  After experimenting (the
documentation is unclear) files listed in stage are relative to the part's
installation directory:

modified   snapcraft.yaml
@@ -21,6 +21,8 @@ parts:
       - PyYAML
       - attrs
       - voluptuous
+    stage:
+      - stageme
       - usr
       - lib

Staging ubuntu-image 
[Errno 2] No such file or directory: '/tmp/autopkgtest.LgVE5q/build.9QK/ubuntu-image-1.1+17.04ubuntu1/parts/ubuntu-image/install/stageme'

root at autopkgtest:/tmp/autopkgtest.LgVE5q/build.9QK/ubuntu-image-1.1+17.04ubuntu1# find parts/ubuntu-image/install -name ubuntu_image
root at autopkgtest:/tmp/autopkgtest.LgVE5q/build.9QK/ubuntu-image-1.1+17.04ubuntu1# ls parts/ubuntu-image/install/usr/lib/python3/dist-packages/
chardet-2.3.0.egg-info  pkg_resources               pyparted-3.10.7.egg-info
debian                  python_debian-0.1.30.egg-info
debian_bundle           six-1.10.0.egg-info

You can see that the ubuntu_image package doesn't end up in the part's
dist-packages, and there's nothing that can be staged.

I haven't yet tried to play with scriptlets or other workaround.  Obviously,
we don't want to snap up the ubuntu-image that's in the archive, but instead
the one in the current source directory.

This seems like a bug, but I wanted to get some feedback before I filed a bug

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <>

More information about the Snapcraft mailing list