Skip to content

Conversation

@dwoz
Copy link
Contributor

@dwoz dwoz commented Jan 27, 2026

What does this PR do?

What issues does this PR fix or reference?

Fixes

Previous Behavior

Remove this section if not relevant

New Behavior

Remove this section if not relevant

Merge requirements satisfied?

[NOTICE] Bug fixes or features added to Salt require tests.

Commits signed with GPG?

Yes/No

twangboy and others added 30 commits December 19, 2025 15:46
Fix typo in salt.utils.cloud to be winrm
A 5 second timeout causes things to start failing when 2 second
artificial network delay is introduced. Changeing the default here to 15
seconds to avoid causeing all programatic usages of LocalClient to
adjust their timeouts.
Bump LocalClient pub and pub_async timeouts
* Remove RPATH from shared libraries that do not link to any other libraries in
  our environment.
* Ensure we always return a proper and consistang default python version for
  create, fetch, build commands.
Adds lazy_loader_strict_matching option and grains cleanup to reduce
memory footprint by 51% through configuration-based optimization.

Changes:

1. salt/loader/lazy.py:
   - Add lazy_loader_strict_matching config option to disable expensive
     Bueller fallback search in _iter_files()
   - Enhance clean_modules() to clear internal caches (_dict,
     loaded_modules, loaded_files, missing_modules) in addition to
     removing modules from sys.modules

2. salt/loader/__init__.py:
   - Call funcs.clean_modules() at end of grains() function to free
     memory after grains are loaded

Impact when lazy_loader_strict_matching is enabled:
- Memory: 127 MB → 62 MB (65 MB saved, 51% reduction)
- Modules: 1122 → 74 (1048 fewer, 93% reduction)
- Requires opt-in configuration
- No code changes to execution/state modules needed
- Clean, simple implementation

Configuration:
Set lazy_loader_strict_matching: True in minion config to enable.
Validates that grains modules are properly unloaded and garbage collected
after salt.loader.grains() completes.

Tests cover:
- Modules removed from sys.modules
- Modules actually garbage collected (via weakrefs)
- Idempotent cleanup on repeated calls
- Internal loader state cleared (_dict, loaded_modules, etc)
- Cleanup works even with errors
- clean_modules() method functionality
- Both normal and force_refresh modes

All 8 tests pass, confirming grains cleanup is working correctly.
Critical fix: base stub modules (salt.loaded.int, salt.loaded.int.{tag},
salt.loaded.ext, salt.loaded.ext.{tag}) are shared infrastructure used
by multiple loaders and must not be removed during cleanup.

Changes:
- salt/loader/lazy.py: Updated clean_modules() to preserve base stubs
  while still removing actual loaded modules
- tests: Added test_base_stubs_preserved_across_loaders() to verify
  one loader's cleanup doesn't break other loaders
- tests: Updated all tests to account for base stubs correctly

Without this fix, cleaning up one loader would remove the base stubs,
breaking any other loaders that depend on them.

All 9 tests pass.
Adds lazy_loader_strict_matching: True to test configurations to validate
that strict matching mode works correctly across the entire test suite.

Changes:
- tests/pytests/conftest.py: Added to all minion factory configs
  (salt_minion_factory, salt_sub_minion_factory, salt_proxy_minion_factory)
- tests/pytests/unit/conftest.py: Added to unit test minion_opts fixture
- tests/pytests/functional/conftest.py: Added to functional test minion config
- tests/integration/files/conf/minion: Added to integration test config file

This will help validate that:
1. Strict matching doesn't break any existing tests
2. All virtualname lookups work with partial matching (step 2)
3. Bueller (step 3) is truly unnecessary
4. Memory optimization works in real-world scenarios

Running the test suite with this enabled will provide comprehensive
validation of our assumptions about loader behavior.
- Only remove modules matching this loader's tag, not all modules
- Recursively clean injected loaders in pack (__utils__, etc.)
- Prevent infinite recursion from circular loader references

Fixes KeyError when runners execute after grains cleanup.
The test now allows base stub modules to remain after clean_modules(),
matching the new behavior that preserves shared infrastructure.
@twangboy twangboy merged commit 3de3526 into saltstack:master Jan 28, 2026
2034 of 2046 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:full Run the full test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants