`snapcraftctl stage` not staging stage-package; is it a bug?

Here is a minimal snapcraft.yaml with which I can reproduce the problem using Snapcraft 7.1.3:

name: chromium
version: "1"
summary: Chromium web browser, open-source version of Chrome
description: |
 An open-source browser project that aims to build a safer, faster, and more
 stable way for all Internet users to experience the web.
confinement: strict
base: core20
assumes:
  - snapd2.43 # for 'snapctl is-connected', used in chromium.launcher
compression: lzo

parts:
  va-drivers:
    plugin: nil
    stage-packages:
      - mesa-vulkan-drivers
    override-stage:
      set -ex
      snapcraftctl stage
    prime:
      - usr/**/libvulkan_*.so
      - usr/**/libVkLayer_*.so
$ snapcraft --debug --use-lxd
Pulling va-drivers
+ snapcraftctl pull
Building va-drivers
+ snapcraftctl build
Staging va-drivers
+ set -ex snapcraftctl stage
Priming va-drivers
+ snapcraftctl prime
[Errno 2] No such file or directory: '/root/stage/usr'
...

snapcraft-chromium # find / -name 'libVk*' 2>/dev/null
/root/parts/va-drivers/install/usr/lib/x86_64-linux-gnu/libVkLayer_MESA_overlay.so
/root/parts/va-drivers/install/usr/lib/x86_64-linux-gnu/libVkLayer_MESA_device_select.so

I expected that, since mesa-vulkan-drivers is in stage-packages, its contents showed up in /root/stage.

Am I wrong in my assumptions or is there something awry in Snapcraft?

Aha,

    override-stage:
      set -ex
      snapcraftctl stage

is to blame. If I remove it the problem goes away,

snapcraft-chromium # find stage -name 'libVk*'
stage/usr/lib/x86_64-linux-gnu/libVkLayer_MESA_overlay.so
stage/usr/lib/x86_64-linux-gnu/libVkLayer_MESA_device_select.so

Is this a bug in snapcraftctl or do I misunderstand it? The documentation does say

In order to run the default stage step, call snapcraftctl stage from within the scriptlet.

Aah I think I’m missing the pipe symbol, i.e. override-stage: |.

1 Like

Seems to be because you started out with set -ex

$ set -ex snapcrafctl foo
+ set -ex snapcrafctl foo
++ _direnv_hook
++ local previous_exit_status=0
++ trap -- '' SIGINT
+++ /usr/bin/direnv export bash
++ eval ''
++ trap - SIGINT
++ return 0

You essentially ran into a YAML loading caveat combined with set -ex

1 Like

Yes, it is a funny combination; Because of how set works the remaining stuff becomes positional arguments to the shell, so $1 = snapcraftctl, $2 = stage etc. and it silently moves on.