Unexpected Behavior of the Dump Plugin during Build Step in a Remote Part

I’m creating a remote part with the following part recipe:

parts:
  workaround-snap-arch-triplet:
    plugin: dump
    source: snap/local/launchers
    organize:
      '*-launch': bin/
    stage:
    - -README.*

and the following source tree:

tree .
.
├── README.md
└── snap
    ├── local
    │   ├── launchers
    │   │   ├── README.md
    │   │   └── workaround-snap-arch-triplet-launch
    │   └── README.md
    └── snapcraft.yaml

3 directories, 5 files

It works as expected as local part:

$ snapcraft pull workaround-snap-arch-triplet
Pulling workaround-snap-arch-triplet 

$ tree parts/workaround-snap-arch-triplet/
parts/workaround-snap-arch-triplet/
├── build
├── install
├── src
│   ├── README.md
│   └── workaround-snap-arch-triplet-launch
└── state
    └── pull

4 directories, 3 files

$ snapcraft build workaround-snap-arch-triplet
Skipping pull workaround-snap-arch-triplet (already ran)
Building workaround-snap-arch-triplet 

$ tree parts/workaround-snap-arch-triplet/
parts/workaround-snap-arch-triplet/
├── build
│   ├── README.md
│   └── workaround-snap-arch-triplet-launch
├── install
│   ├── bin
│   │   └── workaround-snap-arch-triplet-launch
│   └── README.md
├── src
│   ├── README.md
│   └── workaround-snap-arch-triplet-launch
└── state
    ├── build
    └── pull

5 directories, 8 files

$ snapcraft stage workaround-snap-arch-triplet
Skipping pull workaround-snap-arch-triplet (already ran)
Skipping build workaround-snap-arch-triplet (already ran)
Staging workaround-snap-arch-triplet 

$ tree stage
stage
└── bin
    └── workaround-snap-arch-triplet-launch

1 directory, 1 file

I added my part on snapcraft/parts - Ubuntu Wiki, and here’s the resulting patched remote part recipe from snapcraft define workaround-snap-arch-triplet:

workaround-snap-arch-triplet:
  organize:
    '*-launch': bin/
  plugin: dump
  source: https://github.com/Lin-Buo-Ren/snap-arch-triplet-part.git
  source-subdir: snap/local/launchers
  stage:
  - -README.*

But when I try to incorporate the remote part in another snap, here comes the problem:

Pull Step

$ snapcraft pull workaround-snap-arch-triplet
Pulling workaround-snap-arch-triplet 
Cloning into '/home/ubuntu/doc-gtk-themes/parts/workaround-snap-arch-triplet/src'...
remote: Enumerating objects: 62, done.
remote: Counting objects: 100% (62/62), done.
remote: Compressing objects: 100% (44/44), done.
remote: Total 62 (delta 29), reused 48 (delta 16), pack-reused 0
Unpacking objects: 100% (62/62), done.
Checking connectivity... done.

$ tree parts/workaround-snap-arch-triplet/
parts/workaround-snap-arch-triplet/
├── build
│   └── snap                 # ???
│       └── local            # ???
│           └── launchers    # ???
├── install
├── src
│   ├── README.md
│   └── snap
│       ├── local
│       │   ├── README.md
│       │   └── launchers
│       │       ├── README.md
│       │       └── workaround-snap-arch-triplet-launch
│       └── snapcraft.yaml
└── state
    └── pull

10 directories, 6 files

Note the shouldn’t be available snap/local/launchers directories under the builddir

Build Step

$ snapcraft build workaround-snap-arch-triplet
Skipping pull workaround-snap-arch-triplet (already ran)
Building workaround-snap-arch-triplet 
Sorry, an error occurred in Snapcraft:
Traceback (most recent call last):
  File "/usr/bin/snapcraft", line 9, in <module>
    load_entry_point('snapcraft==2.43.1', 'console_scripts', 'snapcraft')()
  File "/usr/lib/python3/dist-packages/click/core.py", line 716, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/click/core.py", line 696, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3/dist-packages/click/core.py", line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3/dist-packages/click/core.py", line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3/dist-packages/click/core.py", line 534, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/snapcraft/cli/lifecycle.py", line 85, in build
    _execute(steps.BUILD, parts, **kwargs)
  File "/usr/lib/python3/dist-packages/snapcraft/cli/lifecycle.py", line 35, in _execute
    lifecycle.execute(step, project_config, parts)
  File "/usr/lib/python3/dist-packages/snapcraft/internal/lifecycle/_runner.py", line 90, in execute
    executor.run(step, part_names)
  File "/usr/lib/python3/dist-packages/snapcraft/internal/lifecycle/_runner.py", line 194, in run
    self._handle_step(part_names, part, step, current_step, cli_config)
  File "/usr/lib/python3/dist-packages/snapcraft/internal/lifecycle/_runner.py", line 208, in _handle_step
    getattr(self, "_run_{}".format(current_step.name))(part)
  File "/usr/lib/python3/dist-packages/snapcraft/internal/lifecycle/_runner.py", line 261, in _run_build
    self._run_step(step=steps.BUILD, part=part, progress="Building")
  File "/usr/lib/python3/dist-packages/snapcraft/internal/lifecycle/_runner.py", line 327, in _run_step
    getattr(part, step.name)()
  File "/usr/lib/python3/dist-packages/snapcraft/internal/pluginhandler/__init__.py", line 523, in build
    self._do_build()
  File "/usr/lib/python3/dist-packages/snapcraft/internal/pluginhandler/__init__.py", line 545, in _do_build
    self._runner.build()
  File "/usr/lib/python3/dist-packages/snapcraft/internal/pluginhandler/_runner.py", line 97, in build
    "override-build", self._override_build_scriptlet, self._builddir
  File "/usr/lib/python3/dist-packages/snapcraft/internal/pluginhandler/_runner.py", line 162, in _run_scriptlet
    scriptlet_name, function_call.strip()
  File "/usr/lib/python3/dist-packages/snapcraft/internal/pluginhandler/_runner.py", line 218, in _handle_builtin_function
    function(**function_args)
  File "/usr/lib/python3/dist-packages/snapcraft/plugins/dump.py", line 53, in build
    copy_function=lambda src, dst: _link_or_copy(src, dst, self.installdir),
  File "/usr/lib/python3/dist-packages/snapcraft/file_utils.py", line 200, in link_or_copy_tree
    raise NotADirectoryError("{!r} is not a directory".format(source_tree))
NotADirectoryError: '/home/ubuntu/doc-gtk-themes/parts/workaround-snap-arch-triplet/build/snap/local/launchers' is not a directory
We would appreciate it if you created a bug report at
https://launchpad.net/snapcraft/+filebug with the above text included.

The build step breaks with a spurious NotADirectoryError, which shouldn’t happen as the dump plugin should simply copy all the files from the srcdir to the builddir, including the _srcdir_/snap/local/launchers directory.

Any ideas?

Reproduced With

Debian Distribution

$ which snapcraft
/usr/bin/snapcraft

$ snapcraft version
snapcraft, version 2.43.1+18.4

Snap Distribution

$ which snapcraft
/snap/bin/snapcraft

$ snapcraft version
snapcraft, version 2.43.1+git95.g3465f98

Regular bump…

I suspect this is due to you putting the files in snap/. Move everything to the top-level so that you get:

./
./launchers/
./launchers/workaround-snap-arch-triplet-launch
./snapcraft.yaml

You might be able to get away with putting the snapcraft.yaml into ./snap/ but remote parts are picky so it possibly won’t work well.

1 Like

What’s the goal of this? What does snap-arch-triplet do that needs working around? Is there a bug which should be tracked?

It is essentially a duplicate of https://github.com/kyrofa/snap-arch-triplet-generator , which I’m currently moving the efforts to.