Open
Conversation
The RPM specfile runs compileall in %post to byte-compile Python modules under /opt/saltstack/salt/lib. This worked fine until commit 48c7d58 (Bump relenv version to 0.20.0). In relenv >=0.20.0, the interpreter bootstrap actively imports ppbt and extracts toolchains if available, rather than just checking if they're already there. This should not have been a problem, as commit 4bd2832 (Remove ppbt after building the salt onedir) removed ppbt from the final package so it never gets installed at runtime. However, the subtleties of RPM scriptlet ordering cause issues on upgrade. The %post scriptlet executes after the new version has been installed, but before the stale files of the old version have been removed. This means that ppbt is still present when the compileall runs, so the bootstrap hooks extract the ppbt toolchain into /root/.local/relenv. This is usually harmless, but silently eats about 215 MiB of disk space, which can be anywhere from mildly annoying to severely damaging depending on how tight the root filesystem is. Since both 48c7d58 and 4bd2832 went into 3006.15, any in-place upgrade of salt that crosses this version will generate this spurious toolchain. Move the compileall into %posttrans, at which point we guarantee the old package has been completely removed and we are only acting on the correct python libraries.
When we regenerate the pycache on upgrade, stale files from removed libraries may persist. Clear everything out first to avoid this. For consistency, change the existing pycache clear-on-uninstall to use the simpler -delete pattern instead of invoking xargs.
This change ensures that Salt file and directory ownership is correctly detected and preserved during upgrades, and that salt-call and salt-pip correctly honor the configured user for privilege dropping. Core Changes: - Update salt-pip to detect the configured user and drop privileges when run as root, ensuring files in the onedir 'extras' directory maintain correct ownership. - Update salt-call to properly distinguish between the configured user (for environment verification/ownership) and the execution user (provided via --priv), preventing accidental ownership resets to root when running maintenance tasks. RPM Changes: - Implement robust ownership detection in %pre by checking runtime PID files, PKI directories, and cache paths. - Restore ownership in %post and %posttrans for all critical Salt paths, including the onedir installation directory (/opt/saltstack/salt) and extras directories. - Fix a bug in %posttrans where upgrades were incorrectly detected as fresh installs. A marker file is now used for reliable state transition. - Clean up debug logging and fix shell logic errors in the spec file. Debian Changes: - Prevent usermod from resetting the salt user's shell in preinst, ensuring salt-call and salt-pip remain functional after upgrade. - Ensure onedir installation paths are included in ownership management. - Update service postinst scripts to only apply default ownership on fresh installs, preventing resets during upgrades. Test and Tooling Changes: - Update Debian upgrade tests to use exact version pinning. - Add comprehensive upgrade tests to verify ownership preservation and the functionality of salt-call and salt-pip under non-root configurations. - Remove temporary relenv runtime patches from build rules. Fixes #68684
- Add ci_build_pkg and ci_test_pkg tools to salt-test MCP server - Generalize MCP server launcher to work across different worktrees - Update agents documentation for package building - Add changelog entry and update work summary
When beacons_refresh() creates a new Beacon instance, the old instance's beacon modules (e.g. inotify) held open file descriptors that were never closed. Each new Beacon gets a fresh empty __context__ dict via LazyLoader, so inotify's _get_notifier() creates a new pyinotify.Notifier while the old one is orphaned with its fds still open. Over repeated refreshes, this exhausts the inotify instance limit (default 128 on RHEL8), causing "Too many open files (EMFILE)" errors. Add close_beacons() to the Beacon class that calls close() on each beacon module before the instance is replaced. Also add __del__() as a safety net for garbage collection, and call close_beacons() explicitly from Minion.beacons_refresh() before creating a new Beacon instance. Fixes: #66449 Fixes: #58907 Made-with: Cursor
This change moves core metadata to the [project] table in pyproject.toml, cleans up requirement files for PEP 517 compatibility, ensures dependencies are dynamically discovered from .txt files, updates static requirement files via pre-commit hooks, and inhibits automatic code rewriting hooks to maintain scope.
Tornado remains vendored as salt.ext.tornado on the 3006.x branch. This change removes the erroneous external dependency and updates static requirement files.
The documentation build needs all Salt dependencies to correctly import modules for autodoc. Adding requirements/crypto.txt ensures that cryptographic dependencies (like pycryptodomex) are available.
Update *-crypto.txt files across all platforms and Python versions to ensure version consistency and resolve pre-commit hook discrepancies.
Synchronize with CI environment by applying formatting changes made by the black pre-commit hook.
Include base.txt and zeromq.txt in the Windows packaging requirement compilation hooks. This ensures that the static windows.txt requirement files contain all necessary dependencies for onedir builds, resolving failures in install_salt.ps1.
The myst-parser requirement for documentation builds on Python 3.9 requires mdit-py-plugins which in turn requires markdown-it-py < 3.0.0. Other packages like rich were pulling in markdown-it-py >= 3.0.0 on some platforms, causing resolution failures. This commit adds a Python version-specific constraint and regenerates the affected static requirement files.
…ures Move Salt's dynamic metadata and dependency logic from setup.py to a custom PEP 517 build backend (tools/pkg/salt_build_backend.py). This modernizes the build system while preserving Salt's complex multi-platform requirement selection logic. Fix installation failures in compiler-less environments by moving timelib and linode-python out of core base requirements. These packages require compilation on Linux and are now only included in packaging-specific static requirement sets where pre-built wheels are verified. Key changes: - Implement tools/pkg/salt_build_backend.py to handle dynamic versioning, requirements, and entry points. - Refactor setup.py to delegate dynamic properties to the new backend. - Move timelib and linode-python from requirements/base.txt to platform-specific .in files in requirements/static/pkg/. - Restore pycryptodomex>=3.9.8 as a core base requirement. - Fully regenerate all static packaging pins for Python 3.9-3.13. - Update tests/pytests/functional/test_pip_install.py to skip on Linux systems without a C compiler.
Add hatchling to --only-binary in onedir_dependencies() so pip installs it from its universal wheel instead of attempting a source build. When --no-binary :all: is active (Linux builds), pip 25.2 tries to source-build hatchling but hatchling lists itself as its own PEP 517 build backend, causing pip's build tracker to raise: LookupError: hatchling is already being built Fixes #68858 Made-with: Cursor Fix locale.set_locale failing on containers without systemd-localed On updated Amazon Linux 2023 and Photon OS 5 containers, localectl set-locale fails with a non-zero exit code because systemd-localed is not running (D-Bus write access unavailable), while localectl status continues to work by reading /etc/locale.conf directly. _localectl_set() now falls back to writing /etc/locale.conf directly when localectl set-locale returns non-zero. Modern systemd's localectl status reads that file without D-Bus, so a subsequent get_locale() call immediately reflects the change. _check_systemctl() in the integration test is hardened to skip the test for the full range of D-Bus connection error messages (Connection refused, Failed to connect to bus, Failed to get D-Bus connection) and guards against FileNotFoundError when localectl is absent. Fixes test_localemod.py::LocaleModuleTest::test_set_locale on: - Amazon Linux 2023 Arm64 - Photon OS 5 Arm64 (fips) - Photon OS 5 Made-with: Cursor Provide a generous timeout for traceroute Fix pre-commit whoops The "Parallel cache failure" test failure this had two root causes, both related to Python 3.14's new default multiprocessing start method (forkserver, via PEP 741): Root Cause 1: `spawning_platform()` didn't recognize `forkserver` salt/utils/platform.py only checked for "spawn", not "forkserver". This caused AttributeError: 'Process' object has no attribute '_args_for_getstate' because Process.__new__ didn't set up pickling support for forkserver-spawned children. Fix: Changed spawning_platform() to return True for both "spawn" and "forkserver". Root Cause 2: Circular import when `extmods/utils/platform.py` shadows stdlib In Python 3.14, the forkserver itself is a fresh Python process (spawned via exec). When it creates child processes: 1. It sets sys.path from the parent salt-call process via preparation_data 2. The parent's sys.path had extmods/utils/ at index 0 (inserted by insert_system_path) 3. In the fresh child, import platform found extmods/utils/platform.py (salt's platform util) before stdlib's platform.py 4. extmods/utils/platform.py does from salt.utils.decorators import memoize which creates a circular import: • salt.utils.decorators → salt.utils.versions → salt.version → import platform → (itself) → salt.utils.decorators ♻️ Fix 1 (targeted): Replaced from salt.utils.decorators import memoize as real_memoize in salt/utils/platform.py with functools.lru_cache(maxsize=None) — a stdlib-only alternative that breaks the circular dependency. Fix 2 (defensive): Changed insert_system_path() in salt/config/__init__.py from sys.path.insert(0, ...) to sys.path.append(...), so extension module directories never appear before stdlib paths. Use functools.cache for real_momoize Update traceroute test
Fix inotify file descriptor leak during beacon refresh
This changes is to account for CVE fixes, so that scanning tools will not flag false posisitves.
71a68b4 to
416b2bb
Compare
…boundLocalError
416b2bb to
0939e2c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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