Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-sushy for openSUSE:Factory 
checked in at 2026-05-20 15:25:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sushy (Old)
 and      /work/SRC/openSUSE:Factory/.python-sushy.new.1966 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-sushy"

Wed May 20 15:25:11 2026 rev:23 rq:1354133 version:5.11.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-sushy/python-sushy.changes        
2026-04-12 17:52:26.291474012 +0200
+++ /work/SRC/openSUSE:Factory/.python-sushy.new.1966/python-sushy.changes      
2026-05-20 15:26:29.090993998 +0200
@@ -1,0 +2,19 @@
+Tue May 19 22:20:18 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 5.11.0:
+  * Update hacking to 7.0.0
+  * tls: Short circuit retries on hard tls errors
+  * Fix verify option usage with tls version settings
+  * Add TLS configuration support to sushy
+  * Prevent double-wrapping timeout tuple in Connector _op
+  * Revert "Skipping UsbCd workaround on Supermicro ARS-111GL-
+    NHR"
+  * Add missing __init__.py
+  * Fix docs lint issue in docstring
+  * Update master for stable/2026.1
+  * Handle missing RelatedProperties in TransferProtocolType
+    detection
+- drop Prevent-double-wrapping-timeout-tuple-in-Connector-_op.patch
+  (upstream)
+
+-------------------------------------------------------------------

Old:
----
  Prevent-double-wrapping-timeout-tuple-in-Connector-_op.patch
  sushy-5.10.0.tar.gz

New:
----
  sushy-5.11.0.tar.gz

----------(Old B)----------
  Old:    detection
- drop Prevent-double-wrapping-timeout-tuple-in-Connector-_op.patch
  (upstream)
----------(Old E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-sushy.spec ++++++
--- /var/tmp/diff_new_pack.AQ9x0n/_old  2026-05-20 15:26:30.043033227 +0200
+++ /var/tmp/diff_new_pack.AQ9x0n/_new  2026-05-20 15:26:30.043033227 +0200
@@ -17,22 +17,22 @@
 
 
 Name:           python-sushy
-Version:        5.10.0
+Version:        5.11.0
 Release:        0
 Summary:        Python library to communicate with Redfish based systems
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            https://docs.openstack.org/sushy
 Source0:        
https://files.pythonhosted.org/packages/source/s/sushy/sushy-%{version}.tar.gz
-# [PATCH] Prevent double-wrapping timeout tuple in Connector _op
-Patch0:         Prevent-double-wrapping-timeout-tuple-in-Connector-_op.patch
-BuildRequires:  %{python_module oslotest}
+BuildRequires:  %{python_module oslotest >= 3.2.0}
+BuildRequires:  %{python_module pbr >= 6.0.0}
 BuildRequires:  %{python_module pip}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module python-dateutil >= 2.7.0}
 BuildRequires:  %{python_module requests >= 2.14.2}
 BuildRequires:  %{python_module stevedore >= 1.29.0}
 BuildRequires:  %{python_module wheel}
+Requires:       python-pbr >= 6.0.0
 Requires:       python-python-dateutil >= 2.7.0
 Requires:       python-requests >= 2.14.2
 Requires:       python-stevedore >= 1.29.0
@@ -54,7 +54,7 @@
 This package contains the documentation.
 
 %prep
-%autosetup -p1 -n sushy-%{version}
+%autosetup -n sushy-%{version}
 
 %build
 %pyproject_wheel

++++++ sushy-5.10.0.tar.gz -> sushy-5.11.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/.pre-commit-config.yaml 
new/sushy-5.11.0/.pre-commit-config.yaml
--- old/sushy-5.10.0/.pre-commit-config.yaml    2026-02-23 11:14:11.000000000 
+0100
+++ new/sushy-5.11.0/.pre-commit-config.yaml    2026-05-05 14:01:27.000000000 
+0200
@@ -24,7 +24,7 @@
       - id: remove-tabs
         exclude: '.*\.(svg)$'
   - repo: https://opendev.org/openstack/hacking
-    rev: 6.1.0
+    rev: 7.0.0
     hooks:
       - id: hacking
         additional_dependencies:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/AUTHORS new/sushy-5.11.0/AUTHORS
--- old/sushy-5.10.0/AUTHORS    2026-02-23 11:14:54.000000000 +0100
+++ new/sushy-5.11.0/AUTHORS    2026-05-05 14:02:17.000000000 +0200
@@ -26,6 +26,7 @@
 Ilya Etingof <[email protected]>
 Iury Gregory Melo Ferreira <[email protected]>
 Iury Gregory Melo Ferreira <[email protected]>
+Jacob Anders <[email protected]>
 Jacob Anders <[email protected]>
 James E. Blair <[email protected]>
 Javier Pena <[email protected]>
@@ -37,6 +38,7 @@
 Kaifeng Wang <[email protected]>
 Kamil Gustab <[email protected]>
 Kamlesh Chauvhan <[email protected]>
+Lennart Jern <[email protected]>
 LiZekun <[email protected]>
 Lin Yang <[email protected]>
 Lucas Alvares Gomes <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/ChangeLog new/sushy-5.11.0/ChangeLog
--- old/sushy-5.10.0/ChangeLog  2026-02-23 11:14:54.000000000 +0100
+++ new/sushy-5.11.0/ChangeLog  2026-05-05 14:02:17.000000000 +0200
@@ -1,6 +1,20 @@
 CHANGES
 =======
 
+5.11.0
+------
+
+* Update hacking to 7.0.0
+* tls: Short circuit retries on hard tls errors
+* Fix verify option usage with tls version settings
+* Add TLS configuration support to sushy
+* Prevent double-wrapping timeout tuple in Connector \_op
+* Revert "Skipping UsbCd workaround on Supermicro ARS-111GL-NHR"
+* Add missing \_\_init\_\_.py
+* Fix docs lint issue in docstring
+* Update master for stable/2026.1
+* Handle missing RelatedProperties in TransferProtocolType detection
+
 5.10.0
 ------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/PKG-INFO new/sushy-5.11.0/PKG-INFO
--- old/sushy-5.10.0/PKG-INFO   2026-02-23 11:14:54.779126400 +0100
+++ new/sushy-5.11.0/PKG-INFO   2026-05-05 14:02:17.764028300 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: sushy
-Version: 5.10.0
+Version: 5.11.0
 Summary: Sushy is a small Python library to communicate with Redfish based 
systems
 Home-page: https://docs.openstack.org/sushy/latest/
 Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml 
new/sushy-5.11.0/releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml
--- 
old/sushy-5.10.0/releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml 
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-5.11.0/releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml 
    2026-05-05 14:01:27.000000000 +0200
@@ -0,0 +1,22 @@
+---
+features:
+  - |
+    Adds configurable TLS settings to the ``Sushy`` class constructor to
+    allow operators to specify minimum TLS protocol versions and cipher
+    suites for HTTPS connections to Redfish BMCs.
+
+    * ``tls_min_version``: Minimum TLS version to use for HTTPS
+      connections. Supported values are '1.1', '1.2', and '1.3'. If not
+      specified, the default TLS version negotiation is used. Note that TLS
+      1.1 is deprecated and should only be used for compatibility with
+      legacy BMC hardware.
+
+    * ``tls_ciphers``: Colon-separated list of allowed cipher suites in
+      OpenSSL format for HTTPS connections. If not specified, the default
+      cipher suites are used.
+
+    This change is fully backwards compatible. When TLS settings are
+    provided, a custom HTTPAdapter is mounted that configures an
+    ssl.SSLContext with the specified settings. This allows operators to
+    enforce security policies requiring specific TLS versions or cipher
+    suites when communicating with BMCs.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml
 
new/sushy-5.11.0/releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml
--- 
old/sushy-5.10.0/releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-5.11.0/releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml
 2026-05-05 14:01:27.000000000 +0200
@@ -0,0 +1,9 @@
+---
+fixes:
+  - |
+    Fixes virtual media insertion on BMCs (such as Cisco C845A M8 with
+    Redfish Base.1.18.1) that return ``ActionParameterMissing`` for the
+    missing ``TransferProtocolType`` parameter without including a
+    ``RelatedProperties`` field in the error response. The
+    ``is_transfer_protocol_required`` method now also checks for the
+    parameter name in ``MessageArgs`` as a fallback.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml
 
new/sushy-5.11.0/releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml
--- 
old/sushy-5.10.0/releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-5.11.0/releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml
   2026-05-05 14:01:27.000000000 +0200
@@ -0,0 +1,12 @@
+---
+fixes:
+  - |
+    Fixes a bug where the ``connect_timeout`` parameter caused an
+    ``Invalid timeout`` error on any HTTP retry inside ``Connector._op()``.
+    When ``connect_timeout`` is set, the timeout is wrapped into a
+    ``(connect, read)`` tuple, but on recursive retries (server-side errors,
+    re-authentication, or redirect following) the already-wrapped tuple was
+    wrapped again, producing a nested tuple like ``(30, (30, 60))`` that the
+    ``requests`` library rejects. The timeout tuple is now passed through
+    unchanged on retries.
+    See `LP#2146416 <https://bugs.launchpad.net/sushy/+bug/2146416>`_.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml
 
new/sushy-5.11.0/releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml
--- 
old/sushy-5.10.0/releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-5.11.0/releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml
  2026-05-05 14:01:27.000000000 +0200
@@ -0,0 +1,14 @@
+---
+fixes:
+  - |
+    Fixes virtual media boot failure on Supermicro ARS-111GL-NHR with newer
+    BMC firmware, where the virtual media device string has changed back to
+    'UsbCd' consistent with other Supermicro servers. The model-specific
+    exception that previously skipped the CD-to-UsbCd override for this model
+    has been reverted.
+upgrade:
+  - |
+    The CD-to-UsbCd boot source override is now applied unconditionally to all
+    Supermicro machines. Users running older ARS-111GL-NHR firmware where 'Cd'
+    was the correct virtual media device string will need to upgrade their BMC
+    firmware.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/releasenotes/source/2026.1.rst 
new/sushy-5.11.0/releasenotes/source/2026.1.rst
--- old/sushy-5.10.0/releasenotes/source/2026.1.rst     1970-01-01 
01:00:00.000000000 +0100
+++ new/sushy-5.11.0/releasenotes/source/2026.1.rst     2026-05-05 
14:01:27.000000000 +0200
@@ -0,0 +1,6 @@
+===========================
+2026.1 Series Release Notes
+===========================
+
+.. release-notes::
+   :branch: stable/2026.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/releasenotes/source/index.rst 
new/sushy-5.11.0/releasenotes/source/index.rst
--- old/sushy-5.10.0/releasenotes/source/index.rst      2026-02-23 
11:14:11.000000000 +0100
+++ new/sushy-5.11.0/releasenotes/source/index.rst      2026-05-05 
14:01:27.000000000 +0200
@@ -6,6 +6,7 @@
    :maxdepth: 1
 
    unreleased
+   2026.1
    2025.2
    2025.1
    2024.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/sushy/connector.py 
new/sushy-5.11.0/sushy/connector.py
--- old/sushy-5.10.0/sushy/connector.py 2026-02-23 11:14:11.000000000 +0100
+++ new/sushy-5.11.0/sushy/connector.py 2026-05-05 14:01:27.000000000 +0200
@@ -16,10 +16,12 @@
 from http import client as http_client
 import logging
 import re
+import ssl
 import time
 from urllib import parse as urlparse
 
 import requests
+from requests.adapters import HTTPAdapter
 from requests import exceptions as req_exc
 from urllib3.exceptions import InsecureRequestWarning
 
@@ -39,6 +41,59 @@
 )
 
 
+class TLSHttpAdapter(HTTPAdapter):
+    """HTTP adapter that configures TLS settings for HTTPS connections."""
+
+    def __init__(self, tls_min_version=None, tls_ciphers=None, verify=True,
+                 *args, **kwargs):
+        """Initialize the TLS adapter.
+
+        :param tls_min_version: Minimum TLS version ('1.1', '1.2', or '1.3').
+            Note: TLS 1.1 is deprecated and should only be used for
+            compatibility with legacy BMC hardware.
+        :param tls_ciphers: Colon-separated string of allowed cipher suites
+        :param verify: Whether to verify SSL certificates
+        """
+        self.tls_min_version = tls_min_version
+        self.tls_ciphers = tls_ciphers
+        self.verify = verify
+        super().__init__(*args, **kwargs)
+
+    def init_poolmanager(self, *args, **kwargs):
+        """Override to set up TLS configuration."""
+        if self.tls_min_version or self.tls_ciphers:
+            ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+
+            if self.tls_min_version == '1.3':
+                ctx.minimum_version = ssl.TLSVersion.TLSv1_3
+            elif self.tls_min_version == '1.2':
+                ctx.minimum_version = ssl.TLSVersion.TLSv1_2
+            elif self.tls_min_version == '1.1':
+                ctx.minimum_version = ssl.TLSVersion.TLSv1_1
+            elif self.tls_min_version is not None:
+                raise ValueError(
+                    f"tls_min_version must be '1.1', '1.2', or '1.3', "
+                    f"got: {self.tls_min_version}")
+
+            if self.tls_ciphers:
+                try:
+                    ctx.set_ciphers(self.tls_ciphers)
+                except ssl.SSLError as e:
+                    raise ValueError(
+                        f"Invalid cipher specification: {str(e)}")
+
+            if self.verify:
+                ctx.check_hostname = True
+                ctx.verify_mode = ssl.CERT_REQUIRED
+            else:
+                ctx.check_hostname = False
+                ctx.verify_mode = ssl.CERT_NONE
+
+            kwargs['ssl_context'] = ctx
+
+        return super().init_poolmanager(*args, **kwargs)
+
+
 class Connector:
 
     def __init__(
@@ -46,7 +101,9 @@
             response_callback=None, server_side_retries=0,
             server_side_retries_delay=0,
             default_request_timeout=60,
-            connect_timeout=None):
+            connect_timeout=None,
+            tls_min_version=None,
+            tls_ciphers=None):
         self._url = url
         self._verify = verify
         self._session = requests.Session()
@@ -60,6 +117,14 @@
         # unreachable while still allowing longer read timeouts for slow BMCs.
         self._connect_timeout = connect_timeout
 
+        # Mount TLS adapter for HTTPS connections if TLS settings are provided
+        if tls_min_version or tls_ciphers:
+            adapter = TLSHttpAdapter(
+                tls_min_version=tls_min_version,
+                tls_ciphers=tls_ciphers,
+                verify=self._verify)
+            self._session.mount('https://', adapter)
+
         # NOTE(TheJulia): In order to help prevent recursive post operations
         # by allowing us to understand that we should stop authentication.
         self._sessions_uri = None
@@ -147,7 +212,8 @@
         timeout = timeout or self._default_request_timeout
         # If connect_timeout is configured, use a tuple (connect, read) for
         # the requests timeout to allow faster failure on unreachable BMCs.
-        if self._connect_timeout is not None:
+        if (self._connect_timeout is not None
+                and not isinstance(timeout, tuple)):
             timeout = (self._connect_timeout, timeout)
 
         url = path if urlparse.urlparse(path).netloc else urlparse.urljoin(
@@ -195,6 +261,11 @@
                     **extra_session_req_kwargs
                 )
                 break
+            except req_exc.SSLError as e:
+                # SSL errors (handshake failures, certificate issues) are
+                # configuration problems, not transient errors. Do not retry.
+                LOG.error("SSL/TLS error connecting to %s: %s", url, e)
+                raise exceptions.ConnectionError(url=url, error=e)
             except _RETRYABLE_EXCEPTIONS as e:
                 if attempt < retries - 1:
                     LOG.warning(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/sushy/main.py 
new/sushy-5.11.0/sushy/main.py
--- old/sushy-5.10.0/sushy/main.py      2026-02-23 11:14:11.000000000 +0100
+++ new/sushy-5.11.0/sushy/main.py      2026-05-05 14:01:27.000000000 +0200
@@ -161,7 +161,9 @@
                  language='en', server_side_retries=10,
                  server_side_retries_delay=3,
                  read_timeout=60,
-                 connect_timeout=None):
+                 connect_timeout=None,
+                 tls_min_version=None,
+                 tls_ciphers=None):
         """A class representing a RootService
 
         :param base_url: The base URL to the Redfish controller. It
@@ -196,6 +198,14 @@
             BMC to be established. If not specified, read_timeout is used for
             both connect and read timeouts. Setting this to a lower value
             (e.g., 10) allows faster failure when a BMC is unreachable.
+        :param tls_min_version: Minimum TLS version to use for HTTPS
+            connections. Supported values are '1.1', '1.2', and '1.3'. If not
+            specified, the default TLS version negotiation is used. Note: TLS
+            1.1 is deprecated and should only be used for compatibility with
+            legacy BMC hardware.
+        :param tls_ciphers: Colon-separated list of allowed cipher suites
+            in OpenSSL format for HTTPS connections. If not specified, the
+            default cipher suites are used.
         """
         self._root_prefix = root_prefix
         if (auth is not None and (password is not None
@@ -214,7 +224,9 @@
                 server_side_retries=server_side_retries,
                 server_side_retries_delay=server_side_retries_delay,
                 default_request_timeout=read_timeout,
-                connect_timeout=connect_timeout),
+                connect_timeout=connect_timeout,
+                tls_min_version=tls_min_version,
+                tls_ciphers=tls_ciphers),
             path=self._root_prefix)
         self._public_connector = public_connector or requests
         self._language = language
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/sushy/oem/dell/resources/system/storage/controller.py 
new/sushy-5.11.0/sushy/oem/dell/resources/system/storage/controller.py
--- old/sushy-5.10.0/sushy/oem/dell/resources/system/storage/controller.py      
2026-02-23 11:14:11.000000000 +0100
+++ new/sushy-5.11.0/sushy/oem/dell/resources/system/storage/controller.py      
2026-05-05 14:01:27.000000000 +0200
@@ -34,8 +34,9 @@
         to RAID mode. No changes made for PERC 11 and above as they support
         only RAID mode, and BOSS controller as it does not have controller
         mode.
+
         :returns: TaskMonitor if controller mode changes applied and need to
-            reboot, otherwise None
+                  reboot, otherwise None
         """
         # Some controllers do not have controller_mode
         try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/sushy/resources/manager/virtual_media.py 
new/sushy-5.11.0/sushy/resources/manager/virtual_media.py
--- old/sushy-5.10.0/sushy/resources/manager/virtual_media.py   2026-02-23 
11:14:12.000000000 +0100
+++ new/sushy-5.11.0/sushy/resources/manager/virtual_media.py   2026-05-05 
14:01:27.000000000 +0200
@@ -118,12 +118,26 @@
            and 'TransferProtocolType' in error.detail):
             return True
 
-        return (
-            (error.code.endswith(".ActionParameterMissing")
-             or error.code.endswith(".PropertyMissing"))
-            and (("#/TransferProtocolType" in error.related_properties)
-                 or ("/TransferProtocolType" in error.related_properties))
-        )
+        if not (error.code.endswith(".ActionParameterMissing")
+                or error.code.endswith(".PropertyMissing")):
+            return False
+
+        if (("#/TransferProtocolType" in error.related_properties)
+                or ("/TransferProtocolType" in error.related_properties)):
+            return True
+
+        # NOTE(janders) Some BMCs (e.g. Cisco C845A M8 with Redfish
+        # Base.1.18.1) do not include RelatedProperties in the error
+        # response, but do include the missing parameter name in
+        # MessageArgs. Check for that as a fallback.
+        try:
+            args = error.extended_info[0].get('MessageArgs', [])
+            if 'TransferProtocolType' in args:
+                return True
+        except (IndexError, KeyError, TypeError):
+            pass
+
+        return False
 
     def is_transfer_method_required(self, error=None):
         """Check the response code and body and in case of failure
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/sushy/resources/system/system.py 
new/sushy-5.11.0/sushy/resources/system/system.py
--- old/sushy-5.10.0/sushy/resources/system/system.py   2026-02-23 
11:14:12.000000000 +0100
+++ new/sushy-5.11.0/sushy/resources/system/system.py   2026-05-05 
14:01:27.000000000 +0200
@@ -252,7 +252,6 @@
     of a Resource
     Ref: http://redfish.dmtf.org/schemas/DSP0266_1.7.0.html#settings-resource
     """
-    _supermicro_models_cd_vmedia = frozenset(['ars-111gl-nhr'])
 
     _actions = ActionsField('Actions')
 
@@ -379,20 +378,14 @@
 
             target = sys_cons.BootSource(target)
             # NOTE(janders) on SuperMicro X11 and X12 machines, virtual media
-            # is presented as an "USB CD" drive as opposed to a CD drive.
-            # On Supermicro ARS-111GL-NHR however, a more common "CD" device
-            # is used. On both "families" of hardware, both "USB CD" and "CD"
+            # is presented as an "USB CD" drive as opposed to a CD drive. Both
             # are present in the list of boot devices, however only selecting
-            # the appropriate one for the platform as the boot source results
-            # in a successful boot from vMedia. Unless the appropriate option
-            # for a given model is selected, boot fails even if vMedia is
+            # UsbCd as the boot source results in a successful boot from
+            # vMedia. If "CD" is selected, boot fails even if vMedia is
             # inserted. This code detects a case where a SuperMicro machine is
             # about to attempt boot from CD and overrides the boot device to
-            # UsbCd if required, depending on the model. This makes boot from
-            # vMedia work as expected on both variants.
+            # UsbCd instead which makes boot from vMedia work as expected.
             if (self.manufacturer and self.manufacturer.lower() == 'supermicro'
-                    and self.model.lower() not in
-                    self._supermicro_models_cd_vmedia
                     and target == sys_cons.BootSource.CD
                     and self.boot
                     and sys_cons.BootSource.USB_CD.value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/sushy/tests/unit/json_samples/transfer_proto_required_error4.json
 
new/sushy-5.11.0/sushy/tests/unit/json_samples/transfer_proto_required_error4.json
--- 
old/sushy-5.10.0/sushy/tests/unit/json_samples/transfer_proto_required_error4.json
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/sushy-5.11.0/sushy/tests/unit/json_samples/transfer_proto_required_error4.json
  2026-05-05 14:01:27.000000000 +0200
@@ -0,0 +1,19 @@
+{
+  "error": {
+    "@Message.ExtendedInfo": [
+      {
+        "@odata.type": "#Message.v1_1_1.Message",
+        "Message": "The action InsertMedia requires the parameter 
TransferProtocolType to be present in the request body.",
+        "MessageArgs": [
+          "InsertMedia",
+          "TransferProtocolType"
+        ],
+        "MessageId": "Base.1.18.1.ActionParameterMissing",
+        "MessageSeverity": "Critical",
+        "Resolution": "Supply the action with the required parameter in the 
request body when the request is resubmitted."
+      }
+    ],
+    "code": "Base.1.18.1.ActionParameterMissing",
+    "message": "The action InsertMedia requires the parameter 
TransferProtocolType to be present in the request body."
+  }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/sushy/tests/unit/resources/manager/test_virtual_media.py 
new/sushy-5.11.0/sushy/tests/unit/resources/manager/test_virtual_media.py
--- old/sushy-5.10.0/sushy/tests/unit/resources/manager/test_virtual_media.py   
2026-02-23 11:14:12.000000000 +0100
+++ new/sushy-5.11.0/sushy/tests/unit/resources/manager/test_virtual_media.py   
2026-05-05 14:01:27.000000000 +0200
@@ -254,6 +254,16 @@
         retval = self.sys_virtual_media.is_transfer_protocol_required(error)
         self.assertTrue(retval)
 
+    def test_is_transfer_protocol_required_no_related_properties(self):
+        with open('sushy/tests/unit/json_samples/'
+                  'transfer_proto_required_error4.json') as f:
+            response_obj = json.load(f)
+        response = mock.Mock(spec=['json', 'status_code'])
+        response.json.return_value = response_obj
+        error = exceptions.HTTPError('POST', 'VirtualMedia', response)
+        retval = self.sys_virtual_media.is_transfer_protocol_required(error)
+        self.assertTrue(retval)
+
     def test_is_transfer_method_required(self):
         with open('sushy/tests/unit/json_samples/'
                   'transfer_method_required_error.json') as f:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sushy-5.10.0/sushy/tests/unit/resources/system/test_system.py 
new/sushy-5.11.0/sushy/tests/unit/resources/system/test_system.py
--- old/sushy-5.10.0/sushy/tests/unit/resources/system/test_system.py   
2026-02-23 11:14:12.000000000 +0100
+++ new/sushy-5.11.0/sushy/tests/unit/resources/system/test_system.py   
2026-05-05 14:01:27.000000000 +0200
@@ -349,23 +349,6 @@
                            'BootSourceOverrideTarget': 'UsbCd'}},
             etag='81802dbf61beb0bd')
 
-    def test_set_system_boot_options_supermicro_usb_cd_boot_ars111glnhr(self):
-        (self.json_doc["Boot"]
-         ["[email protected]"]).append("UsbCd")
-        self.sys_inst._parse_attributes(self.json_doc)
-
-        self.sys_inst.manufacturer = "supermicro"
-        self.sys_inst.model = "ARS-111GL-NHR"
-        self.sys_inst.set_system_boot_options(
-            target=sushy.BootSource.CD,
-            enabled=sushy.BootSourceOverrideEnabled.ONCE)
-
-        self.sys_inst._conn.patch.assert_called_once_with(
-            '/redfish/v1/Systems/437XR1138R2',
-            data={'Boot': {'BootSourceOverrideEnabled': 'Once',
-                           'BootSourceOverrideTarget': 'Cd'}},
-            etag='81802dbf61beb0bd')
-
     def test_set_system_boot_options_supermicro_no_usb_cd_boot(self):
 
         self.sys_inst.manufacturer = "supermicro"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/sushy/tests/unit/test_connector.py 
new/sushy-5.11.0/sushy/tests/unit/test_connector.py
--- old/sushy-5.10.0/sushy/tests/unit/test_connector.py 2026-02-23 
11:14:12.000000000 +0100
+++ new/sushy-5.11.0/sushy/tests/unit/test_connector.py 2026-05-05 
14:01:27.000000000 +0200
@@ -203,6 +203,36 @@
             'GET', 'http://foo.bar:1234/fake/path',
             headers=self.headers, json=None, verify=True, timeout=(10, 60))
 
+    def test_connect_timeout_not_double_wrapped_on_retry(self):
+        """Test that timeout tuple is not double-wrapped on recursive retry.
+
+        When connect_timeout is set, _op() wraps timeout into a
+        (connect, read) tuple. On retry _op() calls itself recursively,
+        passing the already-wrapped tuple. Without the isinstance guard
+        this results in (connect, (connect, read)) which requests rejects.
+        Regression test for https://bugs.launchpad.net/sushy/+bug/2146416
+        """
+        self.conn._connect_timeout = 10
+        self.conn._default_request_timeout = 60
+        self.request.side_effect = [
+            mock.Mock(status_code=http_client.NOT_ACCEPTABLE),
+            mock.Mock(status_code=http_client.OK),
+        ]
+        self.conn._op('GET', 'http://foo.bar')
+
+        self.assertEqual(2, self.request.call_count)
+        headers_no_accept = self.headers.copy()
+        headers_no_accept.pop('Accept-Encoding')
+        # Both the original and the retried request must use the same
+        # (connect, read) timeout tuple - never a nested tuple.
+        self.request.assert_has_calls([
+            mock.call('GET', 'http://foo.bar', headers=self.headers,
+                      json=None, verify=True, timeout=(10, 60)),
+            mock.call('GET', 'http://foo.bar',
+                      headers=headers_no_accept,
+                      json=None, verify=True, timeout=(10, 60)),
+        ])
+
     def test_response_callback(self):
         mock_response_callback = mock.MagicMock()
         self.conn._response_callback = mock_response_callback
@@ -1016,3 +1046,122 @@
                           target_uri)
         self.assertEqual(self.request.call_count,
                          self.conn._server_side_retries)
+
+    @mock.patch.object(time, 'sleep', autospec=True)
+    def test_ssl_error_not_retried(self, mock_sleep):
+        """Test that SSL errors are not retried."""
+        target_uri = '/redfish/v1/Systems/1'
+        self.request.side_effect = requests.exceptions.SSLError(
+            "SSL handshake failed")
+        self.assertRaises(exceptions.ConnectionError, self.conn.get,
+                          target_uri)
+        # SSL errors should fail immediately without retries
+        self.assertEqual(self.request.call_count, 1)
+        # Sleep should not be called since there are no retries
+        mock_sleep.assert_not_called()
+
+
+class TLSHttpAdapterTestCase(base.TestCase):
+
+    def test_init_with_tls_settings(self):
+        adapter = connector.TLSHttpAdapter(
+            tls_min_version='1.3',
+            tls_ciphers='ECDHE-RSA-AES256-GCM-SHA384')
+        self.assertEqual(adapter.tls_min_version, '1.3')
+        self.assertEqual(adapter.tls_ciphers,
+                         'ECDHE-RSA-AES256-GCM-SHA384')
+
+    def test_init_without_tls_settings(self):
+        adapter = connector.TLSHttpAdapter()
+        self.assertIsNone(adapter.tls_min_version)
+        self.assertIsNone(adapter.tls_ciphers)
+
+
+class ConnectorTLSTestCase(base.TestCase):
+
+    @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True)
+    def test_connector_with_tls_min_version_1_3(self, mock_auth):
+        mock_auth.get_session_key.return_value = None
+        conn = connector.Connector(
+            'https://foo.bar:1234',
+            tls_min_version='1.3',
+            verify=True)
+        # Verify adapter is mounted
+        adapter = conn._session.get_adapter('https://foo.bar:1234')
+        self.assertIsInstance(adapter, connector.TLSHttpAdapter)
+        self.assertEqual(adapter.tls_min_version, '1.3')
+
+    @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True)
+    def test_connector_with_tls_min_version_1_2(self, mock_auth):
+        mock_auth.get_session_key.return_value = None
+        conn = connector.Connector(
+            'https://foo.bar:1234',
+            tls_min_version='1.2',
+            verify=True)
+        # Verify adapter is mounted
+        adapter = conn._session.get_adapter('https://foo.bar:1234')
+        self.assertIsInstance(adapter, connector.TLSHttpAdapter)
+        self.assertEqual(adapter.tls_min_version, '1.2')
+
+    @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True)
+    def test_connector_with_tls_min_version_1_1(self, mock_auth):
+        mock_auth.get_session_key.return_value = None
+        conn = connector.Connector(
+            'https://foo.bar:1234',
+            tls_min_version='1.1',
+            verify=True)
+        # Verify adapter is mounted
+        adapter = conn._session.get_adapter('https://foo.bar:1234')
+        self.assertIsInstance(adapter, connector.TLSHttpAdapter)
+        self.assertEqual(adapter.tls_min_version, '1.1')
+
+    @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True)
+    def test_connector_with_tls_ciphers(self, mock_auth):
+        mock_auth.get_session_key.return_value = None
+        conn = connector.Connector(
+            'https://foo.bar:1234',
+            tls_ciphers='ECDHE-RSA-AES256-GCM-SHA384',
+            verify=True)
+        # Verify adapter is mounted
+        adapter = conn._session.get_adapter('https://foo.bar:1234')
+        self.assertIsInstance(adapter, connector.TLSHttpAdapter)
+        self.assertEqual(adapter.tls_ciphers,
+                         'ECDHE-RSA-AES256-GCM-SHA384')
+
+    @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True)
+    def test_connector_without_tls_settings(self, mock_auth):
+        mock_auth.get_session_key.return_value = None
+        conn = connector.Connector(
+            'https://foo.bar:1234',
+            verify=True)
+        # Default adapter should not be TLSHttpAdapter
+        adapter = conn._session.get_adapter('https://foo.bar:1234')
+        self.assertNotIsInstance(adapter, connector.TLSHttpAdapter)
+
+    def test_adapter_with_invalid_tls_version(self):
+        self.assertRaisesRegex(
+            ValueError,
+            "tls_min_version must be '1.1', '1.2', or '1.3'",
+            connector.TLSHttpAdapter,
+            tls_min_version='1.0')
+
+    def test_adapter_with_invalid_ciphers(self):
+        self.assertRaisesRegex(
+            ValueError,
+            "Invalid cipher specification",
+            connector.TLSHttpAdapter,
+            tls_ciphers='INVALID_CIPHER')
+
+    @mock.patch.object(sushy_auth, 'SessionOrBasicAuth', autospec=True)
+    def test_connector_with_tls_and_verify_false(self, mock_auth):
+        mock_auth.get_session_key.return_value = None
+        # This should not raise an error
+        conn = connector.Connector(
+            'https://foo.bar:1234',
+            tls_min_version='1.1',
+            verify=False)
+        # Verify adapter is mounted and has verify=False
+        adapter = conn._session.get_adapter('https://foo.bar:1234')
+        self.assertIsInstance(adapter, connector.TLSHttpAdapter)
+        self.assertEqual(adapter.tls_min_version, '1.1')
+        self.assertFalse(adapter.verify)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/sushy/tests/unit/test_main.py 
new/sushy-5.11.0/sushy/tests/unit/test_main.py
--- old/sushy-5.10.0/sushy/tests/unit/test_main.py      2026-02-23 
11:14:12.000000000 +0100
+++ new/sushy-5.11.0/sushy/tests/unit/test_main.py      2026-05-05 
14:01:27.000000000 +0200
@@ -55,7 +55,7 @@
         mock_connector.assert_called_once_with(
             'http://foo.bar:1234', verify=True, server_side_retries=10,
             server_side_retries_delay=3, default_request_timeout=60,
-            connect_timeout=None)
+            connect_timeout=None, tls_min_version=None, tls_ciphers=None)
 
     def test__parse_attributes(self):
         self.root._parse_attributes(self.json_doc)
@@ -99,7 +99,7 @@
         mock_connector.assert_called_once_with(
             'http://foo.bar:1234', verify=True, server_side_retries=10,
             server_side_retries_delay=3, default_request_timeout=30,
-            connect_timeout=None)
+            connect_timeout=None, tls_min_version=None, tls_ciphers=None)
 
     @mock.patch.object(auth, 'SessionOrBasicAuth', autospec=True)
     @mock.patch.object(connector, 'Connector', autospec=True)
@@ -112,7 +112,7 @@
         mock_connector.assert_called_once_with(
             'http://foo.bar:1234', verify=True, server_side_retries=10,
             server_side_retries_delay=3, default_request_timeout=60,
-            connect_timeout=10)
+            connect_timeout=10, tls_min_version=None, tls_ciphers=None)
 
     @mock.patch.object(connector, 'Connector', autospec=True)
     def test_custom_connector(self, mock_Sushy_Connector):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/sushy.egg-info/PKG-INFO 
new/sushy-5.11.0/sushy.egg-info/PKG-INFO
--- old/sushy-5.10.0/sushy.egg-info/PKG-INFO    2026-02-23 11:14:54.000000000 
+0100
+++ new/sushy-5.11.0/sushy.egg-info/PKG-INFO    2026-05-05 14:02:17.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: sushy
-Version: 5.10.0
+Version: 5.11.0
 Summary: Sushy is a small Python library to communicate with Redfish based 
systems
 Home-page: https://docs.openstack.org/sushy/latest/
 Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/sushy.egg-info/SOURCES.txt 
new/sushy-5.11.0/sushy.egg-info/SOURCES.txt
--- old/sushy-5.10.0/sushy.egg-info/SOURCES.txt 2026-02-23 11:14:54.000000000 
+0100
+++ new/sushy-5.11.0/sushy.egg-info/SOURCES.txt 2026-05-05 14:02:17.000000000 
+0200
@@ -66,6 +66,7 @@
 releasenotes/notes/add-task-monitor-support-21f711927ad6ec91.yaml
 releasenotes/notes/add-task-service-c751ce51e0b8dc11.yaml
 releasenotes/notes/add-thermal-resource-5c965a3c940f9028.yaml
+releasenotes/notes/add-tls-configuration-8a94bb1bbeb79e6a.yaml
 releasenotes/notes/add-virtual-media-support-f522fbec4420341c.yaml
 releasenotes/notes/add_composition_service-84750d8d1d96474a.yaml
 releasenotes/notes/add_ethernet_interface-df308f814f0e4bce.yaml
@@ -83,6 +84,7 @@
 releasenotes/notes/change-bootdev-smc-ab30317eaf5c37d9.yaml
 releasenotes/notes/change-vmedia-write-protected-attr-586370a552288801.yaml
 releasenotes/notes/check-for-boot-attrs-in-settingsuri-1cad07b6eb1c81b3.yaml
+releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml
 releasenotes/notes/config-server-side-retries-d16824019bd709a2.yaml
 releasenotes/notes/decouple-boot-params-c75e80f5951abb12.yaml
 releasenotes/notes/deprecate-system-leds-f1a72422c53d281e.yaml
@@ -97,6 +99,7 @@
 releasenotes/notes/event-service-d6607420effc3df8.yaml
 releasenotes/notes/expand-drive-schema-042901f919be646c.yaml
 
releasenotes/notes/fix-2008198-bios-factory-reset-400-bad-request-3f4a7a2aada0835b.yaml
+releasenotes/notes/fix-connect-timeout-double-wrap-72ed19391dc0b470.yaml
 releasenotes/notes/fix-dell-bmc-404-race-condition-6000e47436cd4d6e.yaml
 releasenotes/notes/fix-eject-media-empty-dict-573b4c9e06f52ce7.yaml
 releasenotes/notes/fix-exceeding-retries-663ab543cc14f261.yaml
@@ -155,6 +158,7 @@
 releasenotes/notes/retry-ilo-not-ready-error-0b4dce882282eaac.yaml
 releasenotes/notes/retry-on-missing-managedby-b2a5240eab8b4262.yaml
 releasenotes/notes/retry-transient-connection-failures-5d3217a9166bb0d2.yaml
+releasenotes/notes/revert-supermicro-ars111gl-cd-workaround-e59d74a33b6ce10f.yaml
 releasenotes/notes/secure-boot-76c5b80371ea85d1.yaml
 releasenotes/notes/secure-boot-database-7fae673722d7cf4f.yaml
 releasenotes/notes/sessions.yml
@@ -184,6 +188,7 @@
 releasenotes/source/2024.2.rst
 releasenotes/source/2025.1.rst
 releasenotes/source/2025.2.rst
+releasenotes/source/2026.1.rst
 releasenotes/source/conf.py
 releasenotes/source/index.rst
 releasenotes/source/pike.rst
@@ -229,11 +234,14 @@
 sushy/oem/dell/resources/manager/job_service.py
 sushy/oem/dell/resources/manager/lifecycle_service.py
 sushy/oem/dell/resources/manager/manager.py
+sushy/oem/dell/resources/system/__init__.py
 sushy/oem/dell/resources/system/constants.py
 sushy/oem/dell/resources/system/raid_service.py
 sushy/oem/dell/resources/system/system.py
+sushy/oem/dell/resources/system/storage/__init__.py
 sushy/oem/dell/resources/system/storage/constants.py
 sushy/oem/dell/resources/system/storage/controller.py
+sushy/oem/dell/resources/taskservice/__init__.py
 sushy/oem/dell/resources/taskservice/constants.py
 sushy/oem/dell/resources/taskservice/task.py
 sushy/resources/__init__.py
@@ -471,6 +479,7 @@
 sushy/tests/unit/json_samples/transfer_proto_required_error.json
 sushy/tests/unit/json_samples/transfer_proto_required_error2.json
 sushy/tests/unit/json_samples/transfer_proto_required_error3.json
+sushy/tests/unit/json_samples/transfer_proto_required_error4.json
 sushy/tests/unit/json_samples/updateservice.json
 sushy/tests/unit/json_samples/updateservice_no_inv.json
 sushy/tests/unit/json_samples/virtual_media.json
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sushy-5.10.0/sushy.egg-info/pbr.json 
new/sushy-5.11.0/sushy.egg-info/pbr.json
--- old/sushy-5.10.0/sushy.egg-info/pbr.json    2026-02-23 11:14:54.000000000 
+0100
+++ new/sushy-5.11.0/sushy.egg-info/pbr.json    2026-05-05 14:02:17.000000000 
+0200
@@ -1 +1 @@
-{"git_version": "4db9fc0", "is_release": true}
\ No newline at end of file
+{"git_version": "1909826", "is_release": true}
\ No newline at end of file

Reply via email to