Organizing a file into the default partition gives bad error message
Metadata
Current evaluation
Resolved by canonical/craft-parts#1201, merged as ae1de9f6, which handles organize rules targeting a file in its existing location without the misleading self-link error.
Resolution: closed resolved
Reason: PR #1201 was merged as commit ae1de9f6 and fixes the self-organization failure by recognizing when source and destination are the same file.
Evaluated by: mr-cal-bot
No scores available.
Issue body
### Bug Description
Given a(n incorrect) part definition like:
```
parts:
bootloader:
...
organize
usr/lib/systemd: (default)/usr/lib/systemd
...
```
You'll get a "file not found":
```
craft_parts.errors.CopyFileNotFound: Failed to copy '/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/examples/busybox-gadget/parts/bootloader/install/usr/lib/systemd/boot/efi/linuxx64.elf.stub': no such file or directory.
```
Which is triggered by a FileNotFouind error, which is triggered by a FileExistsError. Pretty sure this happens because craft-parts is trying to hard link a file to itself.
Ideas for improvement:
* Add a check before the link operation and raise a specific error if the src and dest are the same file.
* Pre-check `organize` directives and fail if src and dest are the same.
* Raise a warning and ignore the operation if organizing a file into itself.
### To Reproduce
Organize as above.
### part yaml
_No response_
### Relevant log output
```shell
2024-09-11 11:33:21.628 :: + dpkg -x systemd_249.11-0ubuntu3.7_amd64.deb /home/mrc/dev/worktrees/croncraft/cronos-a-is-default/examples/busybox-gadget/parts/bootloader/install
2024-09-11 11:33:21.887 Failed to copy '/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/examples/busybox-gadget/parts/bootloader/install/usr/lib/systemd/boot/efi/linuxx64.elf.stub': no such file or directory.
2024-09-11 11:33:21.889 Traceback (most recent call last):
2024-09-11 11:33:21.889 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 98, in link_or_copy
2024-09-11 11:33:21.889 link(source, destination, follow_symlinks=follow_symlinks)
2024-09-11 11:33:21.889 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 141, in link
2024-09-11 11:33:21.889 os.link(source_path, destination, follow_symlinks=False)
2024-09-11 11:33:21.889 FileExistsError: [Errno 17] File exists: '/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/examples/busybox-gadget/parts/bootloader/install/usr/lib/systemd/boot/efi/linuxx64.elf.stub' -> '/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/examples/busybox-gadget/parts/bootloader/install/usr/lib/systemd/boot/efi/linuxx64.elf.stub'
2024-09-11 11:33:21.889
2024-09-11 11:33:21.889 During handling of the above exception, another exception occurred:
2024-09-11 11:33:21.889 Traceback (most recent call last):
2024-09-11 11:33:21.889 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 141, in link
2024-09-11 11:33:21.889 os.link(source_path, destination, follow_symlinks=False)
2024-09-11 11:33:21.889 FileNotFoundError: [Errno 2] No such file or directory: '/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/examples/busybox-gadget/parts/bootloader/install/usr/lib/systemd/boot/efi/linuxx64.elf.stub' -> '/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/examples/busybox-gadget/parts/bootloader/install/usr/lib/systemd/boot/efi/linuxx64.elf.stub'
2024-09-11 11:33:21.889
2024-09-11 11:33:21.889 The above exception was the direct cause of the following exception:
2024-09-11 11:33:21.889 Traceback (most recent call last):
2024-09-11 11:33:21.889 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_application/services/lifecycle.py", line 270, in run
2024-09-11 11:33:21.889 aex.execute(action, stdout=stream, stderr=stream)
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/executor/executor.py", line 324, in execute
2024-09-11 11:33:21.890 self._executor.execute(actions, stdout=stdout, stderr=stderr)
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/executor/executor.py", line 136, in execute
2024-09-11 11:33:21.890 self._run_action(act, stdout=stdout, stderr=stderr)
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/executor/executor.py", line 211, in _run_action
2024-09-11 11:33:21.890 handler.run_action(action, stdout=stdout, stderr=stderr)
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/executor/part_handler.py", line 171, in run_action
2024-09-11 11:33:21.890 state = handler(step_info, stdout=stdout, stderr=stderr)
2024-09-11 11:33:21.890 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/executor/part_handler.py", line 333, in _run_build
2024-09-11 11:33:21.890 self._organize(overwrite=update)
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/executor/part_handler.py", line 881, in _organize
2024-09-11 11:33:21.890 organize_files(
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/executor/organize.py", line 96, in organize_files
2024-09-11 11:33:21.890 file_utils.link_or_copy_tree(src, dst)
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 254, in link_or_copy_tree
2024-09-11 11:33:21.890 copy_function(source, destination)
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 104, in link_or_copy
2024-09-11 11:33:21.890 link_or_copy(
2024-09-11 11:33:21.890 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 98, in link_or_copy
2024-09-11 11:33:21.890 link(source, destination, follow_symlinks=follow_symlinks)
2024-09-11 11:33:21.891 File "/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/venv/lib/python3.12/site-packages/craft_parts/utils/file_utils.py", line 143, in link
2024-09-11 11:33:21.891 raise errors.CopyFileNotFound(source) from err
2024-09-11 11:33:21.891 craft_parts.errors.CopyFileNotFound: Failed to copy '/home/mrc/dev/worktrees/croncraft/cronos-a-is-default/examples/busybox-gadget/parts/bootloader/install/usr/lib/systemd/boot/efi/linuxx64.elf.stub': no such file or directory.
2024-09-11 11:33:21.891 Full execution log: '/home/mrc/.local/state/croncraft/log/croncraft-20240911-113306.287089.log'
```
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| stealth/space-bunny-alpha | — | closed resolved | Resolved by canonical/craft-parts#1201, merged as ae1de9f6, which handles organize rules targeting a file in its existing location without the misleading self-link error. | |
| stealth/space-bunny-alpha | — | closed resolved | Fixed the misleading self-link error when an organize rule targets a file in its existing location. PR #1201 merged as commit ae1de9f6. | |
| qwen/qwen3.6-35b-a3b | — | — | Fixed a misleading FileNotFound error when organizing a file to the same destination. The issue stemmed from craft-parts attempting to hard link a file to itself. Resolved in pull request #1201. | |
| qwen/qwen3.6-35b-a3b | — | — | Fixed in craft-parts pull request 1201. The misleading file not found error when organizing a file to the same location was resolved by adding proper validation for identical source and destination paths during file linking. | |
| qwen/qwen3.6-35b-a3b | — | — | Fixed in PR #1201. The misleading CopyFileNotFound error triggered by organizing a file to its own destination was resolved by adding explicit checks to prevent self-linking attempts in craft-parts. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Fixed in craft-parts PR #1201. Resolves a confusing file not found error when hard linking a file to itself during organize operations. The fix validates identical source and destination paths to prevent the invalid link attempt. |
Update history
No update history recorded yet.
Related work
-
Likely Fixed By:
canonical/craft-parts#1201
(confidence 99%)
Merged fix for organizing a file to itself.
-
Related To:
craft-parts#ae1de9f6
(confidence 99%)
Commit associated with the merged fix.
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #1366 Unhandled error when organizing a file to a directory where the file already exists | craft-parts | closed | Fixed by merged PR canonical/craft-parts#1370 (commit 7fe7c84e), which checks whether an organize destination exists before moving files. |