diff --git a/_lastrevision b/_lastrevision index e94004b..e594333 100644 --- a/_lastrevision +++ b/_lastrevision @@ -1 +1 @@ -d7c50289494a6b41234aee2204209083e30fbd8d \ No newline at end of file +8f1380c684ce9206e70a536da663e053bfc125da \ No newline at end of file diff --git a/fix-issues-that-break-salt-in-python-3.12-and-3.13-6.patch b/fix-issues-that-break-salt-in-python-3.12-and-3.13-6.patch new file mode 100644 index 0000000..e20e9ee --- /dev/null +++ b/fix-issues-that-break-salt-in-python-3.12-and-3.13-6.patch @@ -0,0 +1,71 @@ +From d7a6f923ed86be59183161590b60698ea2fd1a21 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= + +Date: Wed, 22 Jan 2025 13:01:09 +0000 +Subject: [PATCH] Fix issues that break Salt in Python 3.12 and 3.13 + (#698) + +--- + salt/ext/tornado/netutil.py | 22 +++++++++++++--------- + salt/utils/url.py | 5 ++--- + 2 files changed, 15 insertions(+), 12 deletions(-) + +diff --git a/salt/ext/tornado/netutil.py b/salt/ext/tornado/netutil.py +index f86b430674..3e7fa130b5 100644 +--- a/salt/ext/tornado/netutil.py ++++ b/salt/ext/tornado/netutil.py +@@ -48,15 +48,19 @@ except ImportError: + if PY3: + xrange = range + +-if hasattr(ssl, 'match_hostname') and hasattr(ssl, 'CertificateError'): # python 3.2+ +- ssl_match_hostname = ssl.match_hostname +- SSLCertificateError = ssl.CertificateError +-elif ssl is None: +- ssl_match_hostname = SSLCertificateError = None # type: ignore +-else: +- import backports.ssl_match_hostname +- ssl_match_hostname = backports.ssl_match_hostname.match_hostname +- SSLCertificateError = backports.ssl_match_hostname.CertificateError # type: ignore ++try: ++ from salt.ext.ssl_match_hostname import CertificateError as SSLCertificateError ++ from salt.ext.ssl_match_hostname import match_hostname as ssl_match_hostname ++except ImportError: ++ if hasattr(ssl, 'match_hostname') and hasattr(ssl, 'CertificateError'): # python 3.2+ ++ ssl_match_hostname = ssl.match_hostname ++ SSLCertificateError = ssl.CertificateError ++ elif ssl is None: ++ ssl_match_hostname = SSLCertificateError = None # type: ignore ++ else: ++ import backports.ssl_match_hostname ++ ssl_match_hostname = backports.ssl_match_hostname.match_hostname ++ SSLCertificateError = backports.ssl_match_hostname.CertificateError # type: ignore + + if hasattr(ssl, 'SSLContext'): + if hasattr(ssl, 'create_default_context'): +diff --git a/salt/utils/url.py b/salt/utils/url.py +index a30610394c..0a10e0e1b6 100644 +--- a/salt/utils/url.py ++++ b/salt/utils/url.py +@@ -5,7 +5,7 @@ URL utils + + import re + import sys +-from urllib.parse import urlparse, urlunparse ++from urllib.parse import urlparse, urlunparse, urlunsplit + + import salt.utils.data + import salt.utils.path +@@ -47,8 +47,7 @@ def create(path, saltenv=None): + path = salt.utils.data.decode(path) + + query = "saltenv={}".format(saltenv) if saltenv else "" +- url = salt.utils.data.decode(urlunparse(("file", "", path, "", query, ""))) +- return "salt://{}".format(url[len("file:///") :]) ++ return f'salt://{salt.utils.data.decode(urlunsplit(("", "", path, query, "")))}' + + + def is_escaped(url): +-- +2.47.0 + diff --git a/fix-virtual-grains-for-vms-running-on-nutanix-ahv-bs.patch b/fix-virtual-grains-for-vms-running-on-nutanix-ahv-bs.patch new file mode 100644 index 0000000..62081b7 --- /dev/null +++ b/fix-virtual-grains-for-vms-running-on-nutanix-ahv-bs.patch @@ -0,0 +1,282 @@ +From 609a9fb9c0a66fa57b02f03267bbaa00bd624f20 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= + +Date: Wed, 22 Jan 2025 13:01:39 +0000 +Subject: [PATCH] Fix virtual grains for VMs running on Nutanix AHV + (bsc#1234022) (#697) + +* Fix virtual grains for Nutanix AHV instances + +* Add changelog +--- + changelog/67180.fixed.md | 1 + + salt/grains/core.py | 14 ++ + tests/pytests/unit/grains/test_core.py | 184 +++++++++++++++++++++++++ + 3 files changed, 199 insertions(+) + create mode 100644 changelog/67180.fixed.md + +diff --git a/changelog/67180.fixed.md b/changelog/67180.fixed.md +new file mode 100644 +index 0000000000..bcdc0e9360 +--- /dev/null ++++ b/changelog/67180.fixed.md +@@ -0,0 +1 @@ ++Fix virtual grains for VMs running on Nutanix AHV +diff --git a/salt/grains/core.py b/salt/grains/core.py +index 98bbd3868e..84d5b179dd 100644 +--- a/salt/grains/core.py ++++ b/salt/grains/core.py +@@ -768,6 +768,9 @@ def _windows_virtual(osdata): + # Manufacturer: Parallels Software International Inc. + elif "Parallels" in manufacturer: + grains["virtual"] = "Parallels" ++ elif "Nutanix" in manufacturer and "AHV" in product_name: ++ grains["virtual"] = "kvm" ++ grains["virtual_subtype"] = "Nutanix AHV" + # Apache CloudStack + elif "CloudStack KVM Hypervisor" in productname: + grains["virtual"] = "kvm" +@@ -927,6 +930,10 @@ def _virtual(osdata): + elif "parallels" in line: + grains["virtual"] = "Parallels" + break ++ elif "nutanix" in line: ++ grains["virtual"] = "kvm" ++ grains["virtual_subtype"] = "Nutanix AHV" ++ break + elif "hyperv" in line: + grains["virtual"] = "HyperV" + break +@@ -978,6 +985,9 @@ def _virtual(osdata): + grains["virtual"] = "Parallels" + elif "Manufacturer: Google" in output: + grains["virtual"] = "kvm" ++ elif "Manufacturer: Nutanix" in output and "Product Name: AHV" in output: ++ grains["virtual"] = "kvm" ++ grains["virtual_subtype"] = "Nutanix AHV" + # Proxmox KVM + elif "Vendor: SeaBIOS" in output: + grains["virtual"] = "kvm" +@@ -1234,6 +1244,7 @@ def _virtual(osdata): + grains["virtual"] = "virtual" + + # Try to detect if the instance is running on Amazon EC2 ++ # or Nutanix AHV + if grains["virtual"] in ("qemu", "kvm", "xen", "amazon"): + dmidecode = salt.utils.path.which("dmidecode") + if dmidecode: +@@ -1253,6 +1264,9 @@ def _virtual(osdata): + elif re.match(r".*Version: [^\r\n]+\.amazon.*", output, flags=re.DOTALL): + grains["virtual_subtype"] = "Amazon EC2" + ++ elif "Manufacturer: Nutanix" in output and "Product Name: AHV" in output: ++ grains["virtual_subtype"] = "Nutanix AHV" ++ + for command in failed_commands: + log.info( + "Although '%s' was found in path, the current user " +diff --git a/tests/pytests/unit/grains/test_core.py b/tests/pytests/unit/grains/test_core.py +index b64b8c4bf8..3d2beaa2c9 100644 +--- a/tests/pytests/unit/grains/test_core.py ++++ b/tests/pytests/unit/grains/test_core.py +@@ -2770,6 +2770,10 @@ def test_virtual_has_virtual_grain(): + {"kernel": "Windows", "manufacturer": "Parallels Software"}, + {"virtual": "Parallels"}, + ), ++ ( ++ {"kernel": "Windows", "manufacturer": "Nutanix", "product_name": "AHV"}, ++ {"virtual": "kvm", "virtual_subtype": "Nutanix AHV"}, ++ ), + ], + ) + def test__windows_virtual(osdata, expected): +@@ -3453,6 +3457,186 @@ def test_virtual_linux_proc_files_with_non_utf8_chars(): + assert virt_grains == {"virtual": "physical"} + + ++@pytest.mark.skip_unless_on_linux ++def test_virtual_nutanix_virt_what(): ++ osdata = {} ++ ++ ( ++ osdata["kernel"], ++ osdata["nodename"], ++ osdata["kernelrelease"], ++ osdata["kernelversion"], ++ osdata["cpuarch"], ++ _, ++ ) = platform.uname() ++ ++ which_mock = MagicMock( ++ side_effect=[ ++ # Check with virt-what ++ "/usr/sbin/virt-what", ++ "/usr/sbin/virt-what", ++ None, ++ "/usr/sbin/dmidecode", ++ ] ++ ) ++ cmd_run_all_mock = MagicMock( ++ side_effect=[ ++ # Check with virt-what ++ {"retcode": 0, "stderr": "", "stdout": "nutanix_ahv"}, ++ { ++ "retcode": 0, ++ "stderr": "", ++ "stdout": "\n".join( ++ [ ++ "dmidecode 3.4", ++ "Getting SMBIOS data from sysfs.", ++ "SMBIOS 2.8 present.", ++ "", ++ "Handle 0x0001, DMI type 1, 27 bytes", ++ "System Information", ++ " Manufacturer: Nutanix", ++ " Product Name: AHV", ++ " Version: Not Specified", ++ " Serial Number: 01234567-dcba-1234-abcd-abcdef012345", ++ " UUID: 12345678-abcd-4321-dcba-0123456789ab", ++ " Wake-up Type: Power Switch", ++ " SKU Number: Not Specified", ++ " Family: Not Specified", ++ "", ++ "Handle 0x2000, DMI type 32, 11 bytes", ++ "System Boot Information", ++ " Status: No errors detected", ++ ] ++ ), ++ }, ++ ] ++ ) ++ ++ with patch("salt.utils.path.which", which_mock), patch.dict( ++ core.__salt__, ++ { ++ "cmd.run": salt.modules.cmdmod.run, ++ "cmd.run_all": cmd_run_all_mock, ++ "cmd.retcode": salt.modules.cmdmod.retcode, ++ "smbios.get": salt.modules.smbios.get, ++ }, ++ ): ++ ++ virtual_grains = core._virtual(osdata.copy()) ++ ++ assert virtual_grains["virtual"] == "kvm" ++ assert virtual_grains["virtual_subtype"] == "Nutanix AHV" ++ ++ ++@pytest.mark.skip_unless_on_linux ++def test_virtual_nutanix_dmidecode(): ++ osdata = {} ++ ++ ( ++ osdata["kernel"], ++ osdata["nodename"], ++ osdata["kernelrelease"], ++ osdata["kernelversion"], ++ osdata["cpuarch"], ++ _, ++ ) = platform.uname() ++ ++ which_mock = MagicMock( ++ side_effect=[ ++ # Check with virt-what ++ None, ++ None, ++ None, ++ "/usr/sbin/dmidecode", ++ None, ++ "/usr/sbin/dmidecode", ++ ] ++ ) ++ cmd_run_all_mock = MagicMock( ++ side_effect=[ ++ { ++ "retcode": 0, ++ "stderr": "", ++ "stdout": "\n".join( ++ [ ++ "dmidecode 3.4", ++ "Getting SMBIOS data from sysfs.", ++ "SMBIOS 2.8 present.", ++ "", ++ "Handle 0x0001, DMI type 1, 27 bytes", ++ "System Information", ++ " Manufacturer: Nutanix", ++ " Product Name: AHV", ++ " Version: Not Specified", ++ " Serial Number: 01234567-dcba-1234-abcd-abcdef012345", ++ " UUID: 12345678-abcd-4321-dcba-0123456789ab", ++ " Wake-up Type: Power Switch", ++ " SKU Number: Not Specified", ++ " Family: Not Specified", ++ "", ++ "Handle 0x2000, DMI type 32, 11 bytes", ++ "System Boot Information", ++ " Status: No errors detected", ++ ] ++ ), ++ }, ++ { ++ "retcode": 0, ++ "stderr": "", ++ "stdout": "\n".join( ++ [ ++ "dmidecode 3.4", ++ "Getting SMBIOS data from sysfs.", ++ "SMBIOS 2.8 present.", ++ "", ++ "Handle 0x0001, DMI type 1, 27 bytes", ++ "System Information", ++ " Manufacturer: Nutanix", ++ " Product Name: AHV", ++ " Version: Not Specified", ++ " Serial Number: 01234567-dcba-1234-abcd-abcdef012345", ++ " UUID: 12345678-abcd-4321-dcba-0123456789ab", ++ " Wake-up Type: Power Switch", ++ " SKU Number: Not Specified", ++ " Family: Not Specified", ++ "", ++ "Handle 0x2000, DMI type 32, 11 bytes", ++ "System Boot Information", ++ " Status: No errors detected", ++ ] ++ ), ++ }, ++ ] ++ ) ++ ++ def _mock_is_file(filename): ++ if filename in ( ++ "/proc/1/cgroup", ++ "/proc/cpuinfo", ++ "/sys/devices/virtual/dmi/id/product_name", ++ "/proc/xen/xsd_kva", ++ "/proc/xen/capabilities", ++ ): ++ return False ++ return True ++ ++ with patch("salt.utils.path.which", which_mock), patch.dict( ++ core.__salt__, ++ { ++ "cmd.run": salt.modules.cmdmod.run, ++ "cmd.run_all": cmd_run_all_mock, ++ "cmd.retcode": salt.modules.cmdmod.retcode, ++ "smbios.get": salt.modules.smbios.get, ++ }, ++ ), patch("os.path.isfile", _mock_is_file), patch( ++ "os.path.isdir", return_value=False ++ ): ++ virtual_grains = core._virtual(osdata.copy()) ++ ++ assert virtual_grains["virtual"] == "kvm" ++ assert virtual_grains["virtual_subtype"] == "Nutanix AHV" ++ ++ + @pytest.mark.skip_unless_on_linux + def test_virtual_set_virtual_ec2(): + osdata = {} +-- +2.47.0 + diff --git a/salt.changes b/salt.changes index c59cdfb..c05690c 100644 --- a/salt.changes +++ b/salt.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Wed Jan 22 13:11:21 UTC 2025 - Pablo Suárez Hernández + +- Fix virtual grains for VMs running on Nutanix AHV (bsc#1234022) +- Fix issues running on Python 3.12 and 3.13 + +- Added: + * fix-virtual-grains-for-vms-running-on-nutanix-ahv-bs.patch + * fix-issues-that-break-salt-in-python-3.12-and-3.13-6.patch + ------------------------------------------------------------------- Thu Jan 9 12:57:12 UTC 2025 - Pablo Suárez Hernández diff --git a/salt.spec b/salt.spec index 69f3f7f..cbcff33 100644 --- a/salt.spec +++ b/salt.spec @@ -498,6 +498,11 @@ Patch146: handle-logger-flushing-already-closed-file-686.patch Patch147: make-minion-reconnecting-on-changing-master-ip-bsc-1.patch # PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/690 Patch148: revert-setting-selinux-context-for-minion-service-bs.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/66899 +# PATCH-FIX_OPENSUSE: https://github.com/openSUSE/salt/pull/698 +Patch149: fix-issues-that-break-salt-in-python-3.12-and-3.13-6.patch +# PATCH-FIX_UPSTREAM: https://github.com/saltstack/salt/pull/67181 +Patch150: fix-virtual-grains-for-vms-running-on-nutanix-ahv-bs.patch ### IMPORTANT: The line below is used as a snippet marker. Do not touch it. ### SALT PATCHES LIST END