Skip to content
Commit cb10e2bd authored by Sam Thursfield's avatar Sam Thursfield Committed by Tristan Van Berkom
Browse files

plugins/elements/compose.py: Avoid losing files inside directory symlinks

The logic for determining which files were removed by integration
commands was broken when dealing with files staged within symlink
directories.

This rather weird scenario is only possible because of the way
BuildStream layers artifacts. If artifact 1 contains a symlink from
`/sbin` to `/usr/sbin`, and artifact 2 is staged on top and contains
a file `/sbin/init`, then the resulting filesystem contains a file at
`/usr/sbin/init`.

The manifest used by the compose element is generated from the contents
of the individual artifacts, so it lists the original paths such as
`/sbin/init`, but would would not contain `/usr/sbin/init` as nothing
has processed the symlinks.

The path `/sbin/init` is valid inside the composed tree, but filesystem
traversals that don't follow symlinks will not report that path in their
results. The compose plugin would look for `/sbin/init` in the results
of `utils.list_relative_paths()`, find it missing, and would act as if
some integration command had removed the file. This meant it would not
end up in the results.

To fix this, I have inverted the logic that processes the results of the
integration commands. We now work through every path in the manifest
and check it against the results of the integration commands, rather
than the other way around, and if any path from the manifest doesn't
appear in the snapshot we assume that it has staged in a different
location due to symlinks.

See: #270
parent d423732f
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment