Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix corrupted package cache for outputs in subpackage tests #5184

Merged
merged 3 commits into from
Feb 14, 2024

Conversation

mbargull
Copy link
Member

@mbargull mbargull commented Feb 14, 2024

Description

Fix corrupted package cache for outputs in subpackage tests

This re-introduces conda_build.environ.clean_pkg_cache with slight
changes to not use conda.models.dist.Dist and handle multiple pkgs_dirs
better.

Addresses #5179 (comment)

Checklist - did you ...

  • Add a file to the news directory (using the template) for the next release's release notes?
  • Add / update necessary tests?
  • [ ] Add / update outdated documentation?

@conda-bot conda-bot added the cla-signed [bot] added once the contributor has signed the CLA label Feb 14, 2024
@mbargull mbargull force-pushed the fix-multi-output-package-corruption branch from 1fcbd9a to dc95fee Compare February 14, 2024 10:52
@mbargull mbargull changed the title Fix subpackage outputs corrupting base package output Fix corrupted package cache for outputs in subpackage tests Feb 14, 2024
@mbargull mbargull marked this pull request as ready for review February 14, 2024 13:08
@mbargull mbargull requested a review from a team as a code owner February 14, 2024 13:08
@mbargull mbargull force-pushed the fix-multi-output-package-corruption branch from a7ab905 to dd90768 Compare February 14, 2024 13:10
@mbargull
Copy link
Member Author

cc @h-vetinari,

What happened in #5179 (comment) / conda-forge/boost-feedstock#189 (comment) was that one of the subpackage's build changed files from the base subpackage it depends on (libboost) in that it overwrote libraries with the non-rpath-patched versions.
This in turn lead to those libraries having the wrong library load paths in the test environment which made the tests fail.

This didn't produce corrupted package files, but rather only corrupted the extracted packages in the package cache.
Overall, this is an issue with conda-build using separate files/caches for different builds (e.g., see #5078 ) and/or the fact that conda still only has 3 types of operation:

  1. hardlink package files from cache to environment (for all files it is not told not to),
  2. softlink package files from cache to environment,
  3. copy package files from cache to environment.

Options 1 & 2 are disk space efficient, of course, but allow potential corruption of shared files.
Option 3 can be very wasteful in terms of disk usage and thus not used by default.

To have a space efficient but also corruption resistant option, conda would need support copy-on-write or overlay filesystems or something alike. (This is a long standing issue...)

Comment on lines +3398 to +3416
# Remove any previously cached build from the package cache to ensure we
# really test the requested build and not some clashing or corrupted build.
# (Corruption of the extracted package can happen, e.g., in multi-output
# builds if one of the subpackages overwrites files from the other.)
# Special case:
# If test is requested for .tar.bz2/.conda file from the pkgs dir itself,
# clean_pkg_cache() will remove it; don't call that function in this case.
in_pkg_cache = (
not hasattr(recipedir_or_package_or_metadata, "config")
and os.path.isfile(recipedir_or_package_or_metadata)
and recipedir_or_package_or_metadata.endswith(CONDA_PACKAGE_EXTENSIONS)
and any(
os.path.dirname(recipedir_or_package_or_metadata) in pkgs_dir
for pkgs_dir in pkgs_dirs
)
)
if not in_pkg_cache:
environ.clean_pkg_cache(metadata.dist(), metadata.config)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is the one removed in gh-5031 , but with a more descriptive comment and changed to handle all entries from pkgs_dirs (because environ.clean_pkg_cache does now).

Comment on lines 1272 to 1294
def clean_pkg_cache(dist, config):
with utils.LoggingContext(logging.DEBUG if config.debug else logging.WARN):
locks = get_pkg_dirs_locks([config.bldpkgs_dir] + pkgs_dirs, config)
with utils.try_acquire_locks(locks, timeout=config.timeout):
for pkgs_dir in pkgs_dirs:
if any(
os.path.exists(os.path.join(pkgs_dir, f"{dist}{ext}"))
for ext in ("", *CONDA_PACKAGE_EXTENSIONS)
):
log.debug(
"Conda caching error: %s package remains in cache after removal",
dist,
)
log.debug("manually removing to compensate")
package_cache = PackageCacheData.first_writable([pkgs_dir])
for cache_pkg_id in package_cache.query(dist):
package_cache.remove(cache_pkg_id)

# Note that this call acquires the relevant locks, so this must be called
# outside the lock context above.
remove_existing_packages(pkgs_dirs, [dist], config)


Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is essentially what https://github.com/conda/conda-build/pull/5151/files#diff-3ba52da5dde963be464da17aa3a40b91541d9709735c97fd03b59d3a0fb54a78L1223-L1266 did, just removed unnecessary Dist stuff and handles multiple pkgs_dirs and .conda better.

This re-introduces conda_build.environ.clean_pkg_cache with slight
changes to not use conda.models.dist.Dist and handle multiple pkgs_dirs
better.

Signed-off-by: Marcel Bargull <[email protected]>
@mbargull mbargull force-pushed the fix-multi-output-package-corruption branch from dd90768 to 34552d5 Compare February 14, 2024 13:48
@mbargull mbargull mentioned this pull request Feb 14, 2024
43 tasks
@mbargull
Copy link
Member Author

@kenodegard, I've added this to #5134 (comment) for 24.1.2.

@mbargull mbargull changed the base branch from main to 24.1.x February 14, 2024 13:55
)
)
if not in_pkg_cache:
environ.clean_pkg_cache(metadata.dist(), metadata.config)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

N.B.: This only ensures the current to-be-tested package gets cleaned.
I.e., if some other package's files are altered in the package cache, this is not handled (we didn't handle this in <=3.27 either).
E.g., in the added test case below we only alter the package file during build; if we were do it during the test (package first-... overwriting file from base-...), then the subsequent test of second-... would fail since only second-... but not base-... is passed on to clean_pkg_cache.

conda_build/environ.py Outdated Show resolved Hide resolved
dist,
)
log.debug("manually removing to compensate")
package_cache = PackageCacheData.first_writable([pkgs_dir])
Copy link
Contributor

@kenodegard kenodegard Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could the cached package exist in a one of the non-writable locations?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and it would raise a NoWritablePkgsDirError then.
We have 2 options here:

  1. Let is fail somehow (we may want to have better error handling at somepoint),
  2. Ignore the existing package and risk to test a different package build we didn't intend to test.

kenodegard
kenodegard previously approved these changes Feb 14, 2024
Signed-off-by: Marcel Bargull <[email protected]>
Co-authored-by: Ken Odegard <[email protected]>
@kenodegard kenodegard enabled auto-merge (squash) February 14, 2024 15:43
@kenodegard kenodegard merged commit 355d6df into conda:24.1.x Feb 14, 2024
26 checks passed
mbargull added a commit to mbargull/boa that referenced this pull request Mar 16, 2024
mbargull added a commit to mbargull/boa that referenced this pull request Mar 16, 2024
mbargull added a commit to mbargull/boa that referenced this pull request Mar 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed [bot] added once the contributor has signed the CLA
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants