Wrong Gunicorn wrapper


We had a Gitlab pipeline to build a snap for a Python-Django-Gunicorn project, and the most recent builds somehoe generate a the wrong wrapper for $SNAP/bin/gunicorn.

If I build the snap on my computer, it builds fine, and the first shebang line is #!/usr/bin/env python2. However the gitlab bulit package results in the following shebang line:

'''exec' /builds/mygitlabnamespace/mygitlabproject/parts/mysnap/install/usr/bin/python2 "$0" "$@"
' '''

As a results the Gunicorn service cannot be started since /builds/[..] is not a valid path in the snap.

The Gitlab CI runners use a docker image for the builds. If I use the same image locally to spawn a conatiner and build the snap in there, the shebang is correct again.

Any ideas why the shebang gets wrong when built via gitlab?

Hmm… the logic that creates a shebang like that in Snapcraft does so if the shebang has arguments to Python, e.g. #!/usr/bin/python2 -Es. In order to work in the snap, snapcraft rewrites the shebangs to use /usr/bin/env, which doesn’t support such args, thus the /bin/sh hack. It doesn’t look right, though, and I can’t quite explain why it would be different when running in gitlab versus manually. Any chance you have access to the entire dirty tree after a build completes? I’m curious what that file (particularly its shebang) looks like through the lifecycle (e.g. in parts/<part name>/src, parts/<part name>/install, and stage/ before finally being primed and snapped.

Note that this functionality is not new (it was introduced in 2.35), however, 2.42.1 introduced wider use of it. What version of snapcraft are you using? 2.42.1 is in candidate-- any chance gitlab is using candidate, and you’re using stable (which is still 2.42)?

Checking it during the build was tricky since the containers are destroyed by gitlab, but I managed to copy the snap build folders before. The locations you asked:

  • parts/<part name>/src
    The gunicorn wrapper does not exist here. Since it’s not part of our source it’s not that surprising I suppose?
  • parts/<part name>/install
    bin/gunicorn exists with the #!/bin/sh [..] shebang line.
  • stage/
    bin/gunicorn exists with the #!/bin/sh [..] shebang line.

The snapcraft version in the docker image used by the ci runners:

root@1d33708c76dc:/# snapcraft --version
snapcraft, version 2.41

I checked and our image was updated (rebuilt) not so long ago. The previous successful snap build via gitlab was using this older image which had version snapcraft, version 2.39.3+really2.35. I will try to run the pipeline with the older image and see what happens.