From c21cb5964f9b5f93b7ac332e82cd38199545736c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=98=E5=85=B8?= Date: Sun, 9 Aug 2026 07:20:28 +0800 Subject: [PATCH] Correct pywinrm distribution name in HAS_WINRM detection salt.utils.cloud looked up the distribution name "winrm" with importlib.metadata.version(), but the PyPI package is distributed as "pywinrm" (imported as `winrm`). version("winrm") raises PackageNotFoundError, which the surrounding `except ImportError` swallows, so HAS_WINRM is always False and salt-cloud WinRM deployments fail with "WinRM requested but module winrm could not be imported" even when pywinrm is installed (>= 0.3.0). Use the correct "pywinrm" distribution name. The existing test_winrm_pinnned_version already queries version("pywinrm"). Closes #69976 --- salt/utils/cloud.py | 6 ++++-- tests/pytests/unit/utils/test_cloud.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/salt/utils/cloud.py b/salt/utils/cloud.py index 79389ea8a9c7..a6293181a446 100644 --- a/salt/utils/cloud.py +++ b/salt/utils/cloud.py @@ -80,9 +80,11 @@ import importlib import importlib.metadata - # Verify WinRM 0.3.0 or greater + # Verify WinRM 0.3.0 or greater. The PyPI distribution is "pywinrm" + # (imported as `winrm`); looking up "winrm" raises PackageNotFoundError + # (an ImportError subclass), leaving HAS_WINRM always False. See #69976. - version = importlib.metadata.version("winrm") + version = importlib.metadata.version("pywinrm") if not salt.utils.versions.compare(version, ">=", WINRM_MIN_VER): HAS_WINRM = False else: diff --git a/tests/pytests/unit/utils/test_cloud.py b/tests/pytests/unit/utils/test_cloud.py index 4dfe796b2bb9..8c148846dbef 100644 --- a/tests/pytests/unit/utils/test_cloud.py +++ b/tests/pytests/unit/utils/test_cloud.py @@ -561,6 +561,23 @@ def test_winrm_pinnned_version(): assert winrm_version >= "0.3.0" +def test_has_winrm_detection_uses_pywinrm_distribution(): + """ + HAS_WINRM must be detected via the "pywinrm" distribution name (the PyPI + package), not "winrm". ``importlib.metadata.version("winrm")`` raises + ``PackageNotFoundError`` (an ``ImportError`` subclass), which the surrounding + ``except ImportError`` swallows, leaving ``HAS_WINRM`` always ``False`` and + breaking salt-cloud WinRM deployments. See #69976. + """ + import importlib.metadata + + try: + importlib.metadata.version("pywinrm") + except importlib.metadata.PackageNotFoundError: + pytest.skip("pywinrm is not installed in this env.") + assert cloud.HAS_WINRM is True + + def test_ssh_gateway_arguments_default_alive_args(): server_alive_interval = 60 server_alive_count_max = 3