link_or_copy: do not try to create hardlinks to symlinks.
Metadata
Current evaluation
Merged PR #3174 (commit 221a43803) to copy symlinks instead of attempting hard links, preventing errors on mounted macOS volumes.
Resolution: closed resolved
Reason: PR #3174 was merged as commit 221a43803. The change makes link_or_copy preserve symlinks by copying them, avoiding the erroneous hard-link creation and EEXIST fallback failure described in the report.
Evaluated by: mr-cal-bot
No scores available.
Issue body
while creating a snapcraft package within a docker image with a mounted mac volume I encountered a weird error:
```
Staging authpass
Sorry, an error occurred in Snapcraft:
[Errno 17] File exists: 'libbsd.so.0.8.7' -> '/code/authpass/stage/lib/x86_64-linux-gnu/libbsd.so.0'
```
It seems like on a mounted mac volume a hard link created for a symlink behaves weirdly (throws an error, but still creates the link). Although I'm not sure what the expected behaviour is. imho the expected behavior would be: if there is a symlink in the source folder, that there is a symlink in the destination folder. So my fix does exactly that. And with this fix the snapcraft build succeeded for me.
The problem can be reproduced even without python, just on the commandline in a docker running on mac:
```
root@1051363b90ac:/home/authpass/tmp# touch first ; ln -s first symlink ; ln symlink hardlink
ln: failed to create hard link 'hardlink' => 'symlink': Input/output error
root@1051363b90ac:/home/authpass/tmp# ls -l
total 0
-rw-r--r-- 2 root root 0 Jun 13 10:53 first
-rw-r--r-- 2 root root 0 Jun 13 10:53 hardlink
lrwxrwxrwx 1 root root 5 Jun 13 10:53 symlink -> first
```
creating a hardlink to the symlink throws an error, but still creates a file. In the python code this results in an exception being thrown, and falls back to copying the file, which fails with 'already exists'.
- [ ] Have you followed the [guidelines for contributing](https://github.com/snapcore/snapcraft/blob/master/CONTRIBUTING.md)?
- [ ] Have you signed the [CLA](http://www.ubuntu.com/legal/contributors/)?
- [ ] Have you successfully run `./runtests.sh static`?
- [ ] Have you successfully run `./runtests.sh tests/unit`?
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| stealth/space-bunny-alpha | — | closed resolved | Merged PR #3174 (commit 221a43803) to copy symlinks instead of attempting hard links, preventing errors on mounted macOS volumes. | |
| stealth/space-bunny-alpha | — | closed resolved | Merged PR #3174 (commit 221a43803) to copy source symlinks instead of attempting hardlinks, avoiding Errno 17 failures on macOS-mounted Docker volumes. | |
| qwen/qwen3.6-35b-a3b | — | — | Merged a fix to prevent creating hardlinks to symlinks in link_or_copy. This resolves an Errno 17 failure during snapcraft builds on Docker with mounted Mac volumes by falling back to copying symlinks instead. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Merged a fix preventing hardlinks to symlinks in link_or_copy. This resolves an Errno 17 failure on macOS Docker volumes by copying symlinks instead. Maintainer assisted with CLA verification prior to merge. |
Update history
No update history recorded yet.
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #478 Follow symlinks while hard-linking migrated files. | snapcraft | merged | Merged PR #478 as commit 313023188, resolving symlinks with os.path.realpath() before hard-linking migrated files and preventing broken links in generated snaps. | |
| #728 Use link_or_copy instead of just hard-links for deb cache. | snapcraft | merged | Merged PR #728 as commit 3d1835b5d, replacing deb-cache hard links with link_or_copy so caching works across filesystem boundaries; fixes LP #1612813. |