Parts should be handled in a consistent order through multiple runs
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Snapcraft |
Fix Released
|
Wishlist
|
Kyle Fazzari |
Bug Description
Say one has three parts:
- lib
- libuser
- other
The 'lib' part builds libfoo from source, and installs it to /lib. The 'libuser' builds and links to libfoo, so it has an `after: [lib]` property. The 'other' part is completely independent of the others (or so the developer thinks), so there is no `after` relationship on it or with it. However, it has stage-packages, and unknown to the developer, somewhere in the dependencies of its stage-packages is the version of libfoo in the archive, which gets installed into /usr/lib/
As far as Snapcraft is concerned, it has two independent branches of parts that need to be build. One branch is "build lib, then build libuser", and the other is "build other". Today there is no logic to choose which one goes first, so it's non-deterministic-- one run may see "other" built first, the next may see "lib" built first and then perhaps "other", and the third run may see "lib" built first followed by "libuser" finally followed by "other".
However, depending on the order in which these are primed (which follows the rules above), it's possible for libuser to link to the libfoo from the "other" part instead of the "lib" part like intended, which may break the snap. Similarly, it's possible for the contents of "other" to link to the libfoo from the "lib" part instead of its own stage-package. It's also possible for it to work out completely fine!
There doesn't seem to be a good way for Snapcraft to know that these parts are ACTUALLY somewhat related, but if it behaved in a more consistent and deterministic way so that breakage was always reproducible, these issues would be much easier to find.
If I may spitball, I suggest simply sorting parts alphabetically if order is not enforced by `after`.
Here's an example of a snap with five parts, pulled three times, notice that the order is never the same:
$ snapcraft pull
Preparing to pull part5
Pulling part5
Preparing to pull part2
Pulling part2
Preparing to pull part3
Pulling part3
Preparing to pull part4
Pulling part4
Preparing to pull part1
Pulling part1
$ snapcraft clean && snapcraft pull
Cleaning up priming area
Cleaning up staging area
Cleaning up parts directory
Preparing to pull part5
Pulling part5
Preparing to pull part2
Pulling part2
Preparing to pull part3
Pulling part3
Preparing to pull part1
Pulling part1
Preparing to pull part4
Pulling part4
$ snapcraft clean && snapcraft pull
Cleaning up priming area
Cleaning up staging area
Cleaning up parts directory
Preparing to pull part2
Pulling part2
Preparing to pull part5
Pulling part5
Preparing to pull part3
Pulling part3
Preparing to pull part1
Pulling part1
Preparing to pull part4
Pulling part4
Changed in snapcraft: | |
milestone: | none → 2.43 |
Changed in snapcraft: | |
importance: | Medium → Wishlist |
Changed in snapcraft: | |
status: | In Progress → Fix Committed |
Changed in snapcraft: | |
status: | Fix Committed → Fix Released |
Proposed fix: https:/ /github. com/snapcore/ snapcraft/ pull/2146