Fix locale.set_locale failing on containers without systemd-localed#68859
Open
sujitdb wants to merge 7 commits intosaltstack:masterfrom
Open
Fix locale.set_locale failing on containers without systemd-localed#68859sujitdb wants to merge 7 commits intosaltstack:masterfrom
sujitdb wants to merge 7 commits intosaltstack:masterfrom
Conversation
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 saltstack#68858 Made-with: Cursor
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
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.
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.
Summary
_localectl_set()falls back to writing/etc/locale.confdirectly whenlocalectl set-localereturns non-zero. On containers wheresystemd-localedis not running,localectl status(read) works fine by reading the file directly, whilelocalectl set-locale(write) requires D-Bus and fails. After the fallback write,get_locale()immediately sees the updated value vialocalectl status._check_systemctl()in the integration test is hardened to catch the full range of D-Bus unavailability messages (Connection refused,Failed to connect to bus,Failed to get D-Bus connection) and handlesFileNotFoundErrorwhenlocalectlis absent.Failing test
Affected platforms from the nightly run:
Root cause
A container image update changed the D-Bus error message emitted by
localectlwhensystemd-localedis not running. The prior skip guard only matched"No such file or directory"in stderr; the updated containers emit"Connection refused"or similar, so the test ran instead of being skipped. Whenlocalectl set-localefailed,_localectl_set()returnedFalsedirectly with no fallback, causing the assertion failure.Test plan
test_localemod.py::LocaleModuleTest::test_set_localeon Amazon Linux 2023 Arm64localectl set-localehappy path is unchanged)Made with Cursor