diff --git a/.fence-agents.metadata b/.fence-agents.metadata index 56c2199..2f9df42 100644 --- a/.fence-agents.metadata +++ b/.fence-agents.metadata @@ -1,31 +1,24 @@ e1b766b2b1601fde67b3b19ed2f13b9746bb1cca SOURCES/MarkupSafe-2.0.1.tar.gz -e1fb5dc6f95a85e7d1f93c6701b331201e8b5479 SOURCES/PyJWT-2.1.0-py3-none-any.whl 53fc16036940089ceadd4127381e40fd6106a7ed SOURCES/PyYAML-5.1.tar.gz 0c47ce98be5a519023c16e10027ed1268c489fcc SOURCES/adal-1.2.7.tar.gz f524069cc0d499c78034b66cf0e8e45344e89791 SOURCES/aliyun-cli-3.0.198.tar.gz c6a6dd2c97adb5a22856ce78ad9e3fdc1cbb9760 SOURCES/aliyun-cli-go-vendor.tar.gz 87ad43ef7b7e1cbcba1d743541b3118cffda63f8 SOURCES/aliyun-openapi-meta-5cf98b660.tar.gz -bda476965c380701795849179ed91e9d8134ec7c SOURCES/aliyun-python-sdk-core-2.11.5.tar.gz -2a3e6ee5713a3cfb47e63a739cc9a05580d95dd6 SOURCES/aliyun_python_sdk_ecs-4.24.7-py2.py3-none-any.whl +584e4d5168530be0ed3dca85ab9d7edcb3dfba54 SOURCES/aliyun-python-sdk-core-2.16.0.tar.gz +144b4ff0e62ac4d59a93c1a2e1053489de792f95 SOURCES/aliyun-python-sdk-ecs-4.24.82.tar.gz 1f493a02d15374027ae2bcb2ea4daf5b907c528b SOURCES/azure-common-1.1.28.zip 8f9ddd1b38ad9c712b17b4eb47f79faf92ab8fb6 SOURCES/azure_core-1.32.0.tar.gz -5f357dc1a8a3794a9aa2c7ffbedbce73e0c84f26 SOURCES/azure_identity-1.19.0.tar.gz +9049a68ce201ad0380a02368e7e19611b6b64632 SOURCES/azure_identity-1.25.3.tar.gz 838eaf93a9cd4dfd3c87a342ee7691cf799b2df2 SOURCES/azure_mgmt_compute-34.0.0.tar.gz adc0e3e2d5b126174273efcc40a5e6fc8fe8a8ff SOURCES/azure_mgmt_core-1.5.0.tar.gz f70832bb6367a31808c22849ae2932dae9b17df0 SOURCES/azure_mgmt_network-28.1.0.tar.gz 18167d84640a4522ee23f6c115c208e09c852bb0 SOURCES/boto3-1.40.13.tar.gz 0d393b17c1d023ab145ba0d06c7a292710291213 SOURCES/botocore-1.40.13.tar.gz -c953dcd6e69587e5b182d77255ed836172fea70a SOURCES/cachetools-4.2.2-py3-none-any.whl 0d12f48faa727f0979e9ad5c4c80dfa32b73caff SOURCES/cachetools-4.2.4.tar.gz ec7e8dd8ef95edfdb83a1ea040b8b88507b47615 SOURCES/certifi-2023.7.22.tar.gz -17953cc85717e0f4501dbc7b5fb8e75d67dcdcd3 SOURCES/cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl -96faab7de7e9a71b37f22adb64daf2898e967e3e SOURCES/chardet-3.0.4-py2.py3-none-any.whl -e9eb83c71c09b3c8249bd7d6d2619b65fff03874 SOURCES/chardet-4.0.0-py2.py3-none-any.whl -865df92e66e5dc7b940144cbad8115c07dc8784f SOURCES/charset-normalizer-2.0.7.tar.gz a8ee91adf4644bbdccfc73ead88f4cd0df7e3552 SOURCES/colorama-0.3.3.tar.gz -536a57d70d505e4de8595650603d7e2ecc58b34b SOURCES/cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl 1ec823f807b73a377cdd47d12e2e34f046bfc889 SOURCES/fence-agents-4.10.0.tar.gz -05d6d7a3df5bdbd9df1b37a65662e5dbe94f23fd SOURCES/flit_core-3.9.0.tar.gz +9cccb7a915ef6019c9be30aed53c85361fc24d5e SOURCES/flit_core-3.12.0.tar.gz f4e578dc0ed68d6667d7b36cdfc2647d55e9858f SOURCES/google-auth-2.3.0.tar.gz ac160113ba8b78b0688edda9f9a088c0b4b5ded2 SOURCES/google_api_core-1.30.0-py2.py3-none-any.whl 4fd1eb2b927767158e91e369de441fd9221a82d9 SOURCES/google_api_python_client-1.12.8-py2.py3-none-any.whl @@ -33,58 +26,40 @@ ac160113ba8b78b0688edda9f9a088c0b4b5ded2 SOURCES/google_api_core-1.30.0-py2.py3- 9e513ce4e7b36b8e81c607be440e0d6e6afe9833 SOURCES/google_auth_httplib2-0.1.0-py2.py3-none-any.whl dc553afa7a3f23b92ee9ecd27d0b15153c0e9f75 SOURCES/googleapis_common_protos-1.53.0-py2.py3-none-any.whl 74ec77d2e2ef6b2ef8503e6e398faa6f3ba298ae SOURCES/httplib2-0.19.1-py3-none-any.whl -08c0449533fc94462f78652dea209099754d9ee4 SOURCES/idna-3.3.tar.gz ea36ce1c780dd44f01225dca7f9995a6685a60cc SOURCES/isodate-0.6.1.tar.gz 41fdca818f95b8f0d35298eaab42f4e714dedf19 SOURCES/jinja2-3.1.6.tar.gz -68904717c48e95adb47d815178fff8d80f39b2ab SOURCES/jmespath-0.7.1-py2.py3-none-any.whl +356c48dfea2214dd9e7e2b222a99dddfe9c0d05c SOURCES/jmespath-0.10.0.tar.gz d06a9547b1a87e9c51b0a7c708189d993f2e3d89 SOURCES/kubernetes-12.0.1.tar.gz -346d0213ff6527435a2a04c07c21a80accd7fdf7 SOURCES/msal-1.31.1.tar.gz -e7db7d42807fb756777b01b1569075343c6122e9 SOURCES/msal_extensions-1.2.0.tar.gz +09aa7bbe46dc1137e9dca1afee41ac12f6c3f110 SOURCES/msal-1.36.0.tar.gz +a0fc5e3fb41191e0baa2166adbb07adea738b9af SOURCES/msal_extensions-1.3.1.tar.gz 00c5509205e59ebae09e5d3fe068ab61588e9b4a SOURCES/msrest-0.7.1.zip b21ec03f79d2a7ef4396d909f78130a92455c3c9 SOURCES/msrestazure-0.6.4.post1.tar.gz 7e2f8f4cebf309ef6aaf740ee9073276d6937802 SOURCES/oauthlib-3.2.2.tar.gz 570d69d8c108ebb8aee562389d13b07dfb61ce25 SOURCES/openshift-0.12.1.tar.gz -2b10cb7681bc678ba4ff3be524b28d783e4095ce SOURCES/packaging-20.9-py2.py3-none-any.whl -bccbc1bf76a9db46998eb8e1ffa2f2a2baf9237a SOURCES/packaging-21.2-py3-none-any.whl +16021db61cb341a67194df47d4def1b1d623c449 SOURCES/packaging-26.0.tar.gz 0c3fc83ca045abeec9ce82bb7ee3e77f0390bca4 SOURCES/pexpect-4.8.0-py2.py3-none-any.whl -18659a0dea5600df33eab90dec1b597e2437aebd SOURCES/poetry-core-1.0.7.tar.gz +439894a5b8b430a3f9f837f2ec798e43d598945c SOURCES/pip-26.0.1.tar.gz 8fd43e96c5d0ad701cf3e332fb80c7e92e9ab883 SOURCES/portalocker-2.5.1.tar.gz 5a90b79a9630873c7f2db79544c46146bb6af5e8 SOURCES/protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl 0827aaa6fdc3dc4256e06fa1c3991fb4ed20a693 SOURCES/ptyprocess-0.7.0-py2.py3-none-any.whl -c3c9f195dc89eb6d04828b881314743b548318d0 SOURCES/pyasn1-0.4.8-py2.py3-none-any.whl e0fa19f8fda46a1fa2253477499b116b33f67175 SOURCES/pyasn1-0.4.8.tar.gz 43b89feb6864fe359aae89120627165219de313b SOURCES/pyasn1-modules-0.2.8.tar.gz -d77aa46abbcaccc4054a0777a191e427c785c65a SOURCES/pyasn1_modules-0.2.8-py2.py3-none-any.whl -a0df3ebc552b551f8e99a05cf0a29ce30bef62ee SOURCES/pycparser-2.20-py2.py3-none-any.whl -c55d177e9484d974c95078d4ae945f89ba2c7251 SOURCES/pycryptodome-3.20.0.tar.gz -c8307f47e3b75a2d02af72982a2dfefa3f56e407 SOURCES/pyparsing-2.4.7-py2.py3-none-any.whl -6082312a090f5be5e796e0854294da0738ec0379 SOURCES/pyparsing-3.0.1.tar.gz +ec0a327d767f89b25f6797c50c60030103c3b821 SOURCES/pyjwt-2.12.1.tar.gz 770968018322c2b3fde684aebe964663c6f5d8c5 SOURCES/pyroute2-0.7.12.tar.gz -086fd01f5d989a69eeda46b8a41a53ced5bb402b SOURCES/pyroute2.core-0.6.13.tar.gz -9575a9b38119670705b0a6c2648455d97b22ddc6 SOURCES/pyroute2.ethtool-0.6.13.tar.gz -751cb7dc70e3c1780a670c26ca5721de7caef5e7 SOURCES/pyroute2.ipdb-0.6.13.tar.gz -c204fa61b905fe7b65e250e9204a642bbf3bb84c SOURCES/pyroute2.ipset-0.6.13.tar.gz -d5cba2a4501ffcaf7dcf3df9e9072c4fe343fc02 SOURCES/pyroute2.ndb-0.6.13.tar.gz -4939a1807c414682446d836307543928146bda25 SOURCES/pyroute2.nftables-0.6.13.tar.gz -9ea5167f48860ac18a969b8830925852830297cc SOURCES/pyroute2.nslink-0.6.13.tar.gz 1dc2fa004aa6517f1620e55d8a7b8e68a9cf2a47 SOURCES/python-string-utils-1.0.0.tar.gz 3005ff67df93ee276fb8631e17c677df852254ad SOURCES/python_dateutil-2.8.1-py2.py3-none-any.whl b97c6966fb8fd273f0bc8533cf0dee4978b9f373 SOURCES/pytz-2021.1-py2.py3-none-any.whl -8c7a89d183d3e9b70bf91ba5b75eccf7111b9d8d SOURCES/requests-2.26.0.tar.gz f139aed770519b6a095b8fdc888d03955cbe9d8e SOURCES/requests-oauthlib-1.3.0.tar.gz 25d5667d7a61586f5ddaac7e08cc3053db3d8661 SOURCES/requests_oauthlib-1.3.0-py2.py3-none-any.whl c0d5be2edf538122d35fe06c29d2d7a5f22f3117 SOURCES/rsa-4.7.2-py3-none-any.whl -e8a53067e03fe1b6682fd99a40a7359396a06daa SOURCES/rsa-4.7.2.tar.gz d1011ff44cd5a045de0460c1b79ec65592e86860 SOURCES/ruamel.yaml-0.17.16.tar.gz 27de97227bbbde5a9f571f9fad223578d7bdf7cc SOURCES/ruamel.yaml.clib-0.2.6.tar.gz cba8cc24b8a0dc50f1ef763ad029fa95bfbb3f88 SOURCES/s3transfer-0.13.1.tar.gz -fc3caa7370e18be4c0ca4703f813df1ca4a6b7ad SOURCES/setuptools-80.9.0.tar.gz +8c02ceb7cbb28f69fee84d7201967412d80d3109 SOURCES/setuptools-82.0.1.tar.gz 749fa3bff5be78c80ac6d6d313c38c73d679542c SOURCES/setuptools_scm-8.1.0.tar.gz -06fa0bb50f2a4e2917fd14c21e9d2d5508ce0163 SOURCES/six-1.16.0.tar.gz 47a980b20875d1a1714e921552b5bb0eda190f37 SOURCES/suds_community-0.8.5-py3-none-any.whl 3eae299137c59d6d6d30be01417366c57dd1adf5 SOURCES/tomli-2.0.1.tar.gz 1389615a3f0bd216e7db4440985d51fb3f2ea2c6 SOURCES/typing_extensions-4.12.2.tar.gz 83be56610e5f824bb05ff7a5618d6d4df9b6cc08 SOURCES/uritemplate-3.0.1-py2.py3-none-any.whl -84e2852d8da1655373f7ce5e7d5d3e256b62b4e4 SOURCES/urllib3-1.26.18.tar.gz -540f083782c584989c1a0f69ffd69ba7aae07db6 SOURCES/websocket-client-1.2.1.tar.gz -b6c48d8714e043524be7a869d1db0adcd8441cd4 SOURCES/wheel-0.37.0-py2.py3-none-any.whl +47827db2713bac43c5f9af498b9c48b110aa4869 SOURCES/websocket_client-1.9.0.tar.gz +24aa3cf121e5d807e77e01b0dd3567e13d792ff5 SOURCES/wheel-0.46.3.tar.gz diff --git a/.gitignore b/.gitignore index dae6134..7e29f5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,31 +1,24 @@ SOURCES/MarkupSafe-2.0.1.tar.gz -SOURCES/PyJWT-2.1.0-py3-none-any.whl SOURCES/PyYAML-5.1.tar.gz SOURCES/adal-1.2.7.tar.gz SOURCES/aliyun-cli-3.0.198.tar.gz SOURCES/aliyun-cli-go-vendor.tar.gz SOURCES/aliyun-openapi-meta-5cf98b660.tar.gz -SOURCES/aliyun-python-sdk-core-2.11.5.tar.gz -SOURCES/aliyun_python_sdk_ecs-4.24.7-py2.py3-none-any.whl +SOURCES/aliyun-python-sdk-core-2.16.0.tar.gz +SOURCES/aliyun-python-sdk-ecs-4.24.82.tar.gz SOURCES/azure-common-1.1.28.zip SOURCES/azure_core-1.32.0.tar.gz -SOURCES/azure_identity-1.19.0.tar.gz +SOURCES/azure_identity-1.25.3.tar.gz SOURCES/azure_mgmt_compute-34.0.0.tar.gz SOURCES/azure_mgmt_core-1.5.0.tar.gz SOURCES/azure_mgmt_network-28.1.0.tar.gz SOURCES/boto3-1.40.13.tar.gz SOURCES/botocore-1.40.13.tar.gz -SOURCES/cachetools-4.2.2-py3-none-any.whl SOURCES/cachetools-4.2.4.tar.gz SOURCES/certifi-2023.7.22.tar.gz -SOURCES/cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl -SOURCES/chardet-3.0.4-py2.py3-none-any.whl -SOURCES/chardet-4.0.0-py2.py3-none-any.whl -SOURCES/charset-normalizer-2.0.7.tar.gz SOURCES/colorama-0.3.3.tar.gz -SOURCES/cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl SOURCES/fence-agents-4.10.0.tar.gz -SOURCES/flit_core-3.9.0.tar.gz +SOURCES/flit_core-3.12.0.tar.gz SOURCES/google-auth-2.3.0.tar.gz SOURCES/google_api_core-1.30.0-py2.py3-none-any.whl SOURCES/google_api_python_client-1.12.8-py2.py3-none-any.whl @@ -33,58 +26,40 @@ SOURCES/google_auth-1.32.0-py2.py3-none-any.whl SOURCES/google_auth_httplib2-0.1.0-py2.py3-none-any.whl SOURCES/googleapis_common_protos-1.53.0-py2.py3-none-any.whl SOURCES/httplib2-0.19.1-py3-none-any.whl -SOURCES/idna-3.3.tar.gz SOURCES/isodate-0.6.1.tar.gz SOURCES/jinja2-3.1.6.tar.gz -SOURCES/jmespath-0.7.1-py2.py3-none-any.whl +SOURCES/jmespath-0.10.0.tar.gz SOURCES/kubernetes-12.0.1.tar.gz -SOURCES/msal-1.31.1.tar.gz -SOURCES/msal_extensions-1.2.0.tar.gz +SOURCES/msal-1.36.0.tar.gz +SOURCES/msal_extensions-1.3.1.tar.gz SOURCES/msrest-0.7.1.zip SOURCES/msrestazure-0.6.4.post1.tar.gz SOURCES/oauthlib-3.2.2.tar.gz SOURCES/openshift-0.12.1.tar.gz -SOURCES/packaging-20.9-py2.py3-none-any.whl -SOURCES/packaging-21.2-py3-none-any.whl +SOURCES/packaging-26.0.tar.gz SOURCES/pexpect-4.8.0-py2.py3-none-any.whl -SOURCES/poetry-core-1.0.7.tar.gz +SOURCES/pip-26.0.1.tar.gz SOURCES/portalocker-2.5.1.tar.gz SOURCES/protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl SOURCES/ptyprocess-0.7.0-py2.py3-none-any.whl -SOURCES/pyasn1-0.4.8-py2.py3-none-any.whl SOURCES/pyasn1-0.4.8.tar.gz SOURCES/pyasn1-modules-0.2.8.tar.gz -SOURCES/pyasn1_modules-0.2.8-py2.py3-none-any.whl -SOURCES/pycparser-2.20-py2.py3-none-any.whl -SOURCES/pycryptodome-3.20.0.tar.gz -SOURCES/pyparsing-2.4.7-py2.py3-none-any.whl -SOURCES/pyparsing-3.0.1.tar.gz +SOURCES/pyjwt-2.12.1.tar.gz SOURCES/pyroute2-0.7.12.tar.gz -SOURCES/pyroute2.core-0.6.13.tar.gz -SOURCES/pyroute2.ethtool-0.6.13.tar.gz -SOURCES/pyroute2.ipdb-0.6.13.tar.gz -SOURCES/pyroute2.ipset-0.6.13.tar.gz -SOURCES/pyroute2.ndb-0.6.13.tar.gz -SOURCES/pyroute2.nftables-0.6.13.tar.gz -SOURCES/pyroute2.nslink-0.6.13.tar.gz SOURCES/python-string-utils-1.0.0.tar.gz SOURCES/python_dateutil-2.8.1-py2.py3-none-any.whl SOURCES/pytz-2021.1-py2.py3-none-any.whl -SOURCES/requests-2.26.0.tar.gz SOURCES/requests-oauthlib-1.3.0.tar.gz SOURCES/requests_oauthlib-1.3.0-py2.py3-none-any.whl SOURCES/rsa-4.7.2-py3-none-any.whl -SOURCES/rsa-4.7.2.tar.gz SOURCES/ruamel.yaml-0.17.16.tar.gz SOURCES/ruamel.yaml.clib-0.2.6.tar.gz SOURCES/s3transfer-0.13.1.tar.gz -SOURCES/setuptools-80.9.0.tar.gz +SOURCES/setuptools-82.0.1.tar.gz SOURCES/setuptools_scm-8.1.0.tar.gz -SOURCES/six-1.16.0.tar.gz SOURCES/suds_community-0.8.5-py3-none-any.whl SOURCES/tomli-2.0.1.tar.gz SOURCES/typing_extensions-4.12.2.tar.gz SOURCES/uritemplate-3.0.1-py2.py3-none-any.whl -SOURCES/urllib3-1.26.18.tar.gz -SOURCES/websocket-client-1.2.1.tar.gz -SOURCES/wheel-0.37.0-py2.py3-none-any.whl +SOURCES/websocket_client-1.9.0.tar.gz +SOURCES/wheel-0.46.3.tar.gz diff --git a/SOURCES/RHEL-136061-fix-bundled-urllib3-CVE-2025-66418.patch b/SOURCES/RHEL-136061-fix-bundled-urllib3-CVE-2025-66418.patch deleted file mode 100644 index ece497b..0000000 --- a/SOURCES/RHEL-136061-fix-bundled-urllib3-CVE-2025-66418.patch +++ /dev/null @@ -1,68 +0,0 @@ ---- a/aws/urllib3/response.py 2023-10-17 19:42:56.000000000 +0200 -+++ b/aws/urllib3/response.py 2026-01-02 11:19:25.583808492 +0100 -@@ -135,8 +135,18 @@ - they were applied. - """ - -+ # Maximum allowed number of chained HTTP encodings in the -+ # Content-Encoding header. -+ max_decode_links = 5 -+ - def __init__(self, modes): -- self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")] -+ encodings = [m.strip() for m in modes.split(",")] -+ if len(encodings) > self.max_decode_links: -+ raise DecodeError( -+ "Too many content encodings in the chain: " -+ f"{len(encodings)} > {self.max_decode_links}" -+ ) -+ self._decoders = [_get_decoder(e) for e in encodings] - - def flush(self): - return self._decoders[0].flush() - ---- a/azure/urllib3/response.py 2023-10-17 19:42:56.000000000 +0200 -+++ b/azure/urllib3/response.py 2026-01-02 11:19:25.583808492 +0100 -@@ -135,8 +135,18 @@ - they were applied. - """ - -+ # Maximum allowed number of chained HTTP encodings in the -+ # Content-Encoding header. -+ max_decode_links = 5 -+ - def __init__(self, modes): -- self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")] -+ encodings = [m.strip() for m in modes.split(",")] -+ if len(encodings) > self.max_decode_links: -+ raise DecodeError( -+ "Too many content encodings in the chain: " -+ f"{len(encodings)} > {self.max_decode_links}" -+ ) -+ self._decoders = [_get_decoder(e) for e in encodings] - - def flush(self): - return self._decoders[0].flush() - ---- a/google/urllib3/response.py 2023-10-17 19:42:56.000000000 +0200 -+++ b/google/urllib3/response.py 2026-01-02 11:19:25.583808492 +0100 -@@ -135,8 +135,18 @@ - they were applied. - """ - -+ # Maximum allowed number of chained HTTP encodings in the -+ # Content-Encoding header. -+ max_decode_links = 5 -+ - def __init__(self, modes): -- self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")] -+ encodings = [m.strip() for m in modes.split(",")] -+ if len(encodings) > self.max_decode_links: -+ raise DecodeError( -+ "Too many content encodings in the chain: " -+ f"{len(encodings)} > {self.max_decode_links}" -+ ) -+ self._decoders = [_get_decoder(e) for e in encodings] - - def flush(self): - return self._decoders[0].flush() diff --git a/SOURCES/RHEL-139793-fix-bundled-urllib3-CVE-2025-66471.patch b/SOURCES/RHEL-139793-fix-bundled-urllib3-CVE-2025-66471.patch deleted file mode 100644 index 7363272..0000000 --- a/SOURCES/RHEL-139793-fix-bundled-urllib3-CVE-2025-66471.patch +++ /dev/null @@ -1,845 +0,0 @@ ---- a/aws/urllib3/response.py 2026-01-20 10:46:57.006470161 +0100 -+++ b/aws/urllib3/response.py 2026-01-20 10:55:44.090084896 +0100 -@@ -23,6 +23,7 @@ - from .exceptions import ( - BodyNotHttplibCompatible, - DecodeError, -+ DependencyWarning, - HTTPError, - IncompleteRead, - InvalidChunkLength, -@@ -41,34 +42,60 @@ - class DeflateDecoder(object): - def __init__(self): - self._first_try = True -- self._data = b"" -+ self._first_try_data = b"" -+ self._unfed_data = b"" - self._obj = zlib.decompressobj() - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -- if not data: -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ data = self._unfed_data + data -+ self._unfed_data = b"" -+ if not data and not self._obj.unconsumed_tail: - return data -+ original_max_length = max_length -+ if original_max_length < 0: -+ max_length = 0 -+ elif original_max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unfed_data = data -+ return b"" - -+ # Subsequent calls always reuse `self._obj`. zlib requires -+ # passing the unconsumed tail if decompression is to continue. - if not self._first_try: -- return self._obj.decompress(data) -+ return self._obj.decompress( -+ self._obj.unconsumed_tail + data, max_length=max_length -+ ) - -- self._data += data -+ # First call tries with RFC 1950 ZLIB format. -+ self._first_try_data += data - try: -- decompressed = self._obj.decompress(data) -+ decompressed = self._obj.decompress(data, max_length=max_length) - if decompressed: - self._first_try = False -- self._data = None -+ self._first_try_data = b"" - return decompressed -+ # On failure, it falls back to RFC 1951 DEFLATE format. - except zlib.error: - self._first_try = False - self._obj = zlib.decompressobj(-zlib.MAX_WBITS) - try: -- return self.decompress(self._data) -+ return self.decompress( -+ self._first_try_data, max_length=original_max_length -+ ) - finally: -- self._data = None -+ self._first_try_data = b"" - -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unfed_data) or ( -+ bool(self._obj.unconsumed_tail) and not self._first_try -+ ) - - class GzipDecoderState(object): - -@@ -81,30 +108,64 @@ - def __init__(self): - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - self._state = GzipDecoderState.FIRST_MEMBER -+ self._unconsumed_tail = b"" - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: - ret = bytearray() -- if self._state == GzipDecoderState.SWALLOW_DATA or not data: -+ if self._state == GzipDecoderState.SWALLOW_DATA: -+ return bytes(ret) -+ -+ if max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unconsumed_tail += data -+ return b"" -+ -+ # zlib requires passing the unconsumed tail to the subsequent -+ # call if decompression is to continue. -+ data = self._unconsumed_tail + data -+ if not data and self._obj.eof: - return bytes(ret) -+ - while True: - try: -- ret += self._obj.decompress(data) -+ ret += self._obj.decompress( -+ data, max_length=max(max_length - len(ret), 0) -+ ) - except zlib.error: - previous_state = self._state - # Ignore data after the first error - self._state = GzipDecoderState.SWALLOW_DATA -+ self._unconsumed_tail = b"" - if previous_state == GzipDecoderState.OTHER_MEMBERS: - # Allow trailing garbage acceptable in other gzip clients - return bytes(ret) - raise -- data = self._obj.unused_data -+ -+ self._unconsumed_tail = data = ( -+ self._obj.unconsumed_tail or self._obj.unused_data -+ ) -+ if max_length > 0 and len(ret) >= max_length: -+ break -+ - if not data: - return bytes(ret) -- self._state = GzipDecoderState.OTHER_MEMBERS -- self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ # When the end of a gzip member is reached, a new decompressor -+ # must be created for unused (possibly future) data. -+ if self._obj.eof: -+ self._state = GzipDecoderState.OTHER_MEMBERS -+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ -+ return bytes(ret) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unconsumed_tail) - - - if brotli is not None: -@@ -116,9 +177,35 @@ - def __init__(self): - self._obj = brotli.Decompressor() - if hasattr(self._obj, "decompress"): -- self.decompress = self._obj.decompress -+ setattr(self, "_decompress", self._obj.decompress) - else: -- self.decompress = self._obj.process -+ setattr(self, "_decompress", self._obj.process) -+ -+ # Requires Brotli >= 1.2.0 for `output_buffer_limit`. -+ def _decompress(self, data: bytes, output_buffer_limit: int = -1) -> bytes: -+ raise NotImplementedError() -+ -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ try: -+ if max_length > 0: -+ return self._decompress(data, output_buffer_limit=max_length) -+ else: -+ return self._decompress(data) -+ except TypeError: -+ # Fallback for Brotli/brotlicffi/brotlipy versions without -+ # the `output_buffer_limit` parameter. -+ warnings.warn( -+ "Brotli >= 1.2.0 is required to prevent decompression bombs.", -+ DependencyWarning, -+ ) -+ return self._decompress(data) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ try: -+ return not self._obj.can_accept_more_data() -+ except AttributeError: -+ return False - - def flush(self): - if hasattr(self._obj, "flush"): -@@ -151,10 +238,35 @@ - def flush(self): - return self._decoders[0].flush() - -- def decompress(self, data): -- for d in reversed(self._decoders): -- data = d.decompress(data) -- return data -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ if max_length <= 0: -+ for d in reversed(self._decoders): -+ data = d.decompress(data) -+ return data -+ -+ ret = bytearray() -+ # Every while loop iteration goes through all decoders once. -+ # It exits when enough data is read or no more data can be read. -+ # It is possible that the while loop iteration does not produce -+ # any data because we retrieve up to `max_length` from every -+ # decoder, and the amount of bytes may be insufficient for the -+ # next decoder to produce enough/any output. -+ while True: -+ any_data = False -+ for d in reversed(self._decoders): -+ data = d.decompress(data, max_length=max_length - len(ret)) -+ if data: -+ any_data = True -+ # We should not break when no data is returned because -+ # next decoders may produce data even with empty input. -+ ret += data -+ if not any_data or len(ret) >= max_length: -+ return bytes(ret) -+ data = b"" -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return any(d.has_unconsumed_tail for d in self._decoders) - - - def _get_decoder(mode): -@@ -405,16 +517,25 @@ - if brotli is not None: - DECODER_ERROR_CLASSES += (brotli.error,) - -- def _decode(self, data, decode_content, flush_decoder): -+ def _decode( -+ self, -+ data: bytes, -+ decode_content: bool, -+ flush_decoder: bool, -+ max_length: int = None, -+ ) -> bytes: - """ - Decode the data passed in and potentially flush the decoder. - """ - if not decode_content: - return data - -+ if max_length is None or flush_decoder: -+ max_length = -1 -+ - try: - if self._decoder: -- data = self._decoder.decompress(data) -+ data = self._decoder.decompress(data, max_length=max_length) - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( -@@ -634,7 +755,10 @@ - for line in self.read_chunked(amt, decode_content=decode_content): - yield line - else: -- while not is_fp_closed(self._fp): -+ while ( -+ not is_fp_closed(self._fp) -+ or (self._decoder and self._decoder.has_unconsumed_tail) -+ ): - data = self.read(amt=amt, decode_content=decode_content) - - if data: -@@ -840,7 +964,10 @@ - break - chunk = self._handle_chunk(amt) - decoded = self._decode( -- chunk, decode_content=decode_content, flush_decoder=False -+ chunk, -+ decode_content=decode_content, -+ flush_decoder=False, -+ max_length=amt, - ) - if decoded: - yield decoded - ---- a/azure/urllib3/response.py 2026-01-20 10:46:57.006470161 +0100 -+++ b/azure/urllib3/response.py 2026-01-20 10:55:44.090084896 +0100 -@@ -23,6 +23,7 @@ - from .exceptions import ( - BodyNotHttplibCompatible, - DecodeError, -+ DependencyWarning, - HTTPError, - IncompleteRead, - InvalidChunkLength, -@@ -41,34 +42,60 @@ - class DeflateDecoder(object): - def __init__(self): - self._first_try = True -- self._data = b"" -+ self._first_try_data = b"" -+ self._unfed_data = b"" - self._obj = zlib.decompressobj() - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -- if not data: -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ data = self._unfed_data + data -+ self._unfed_data = b"" -+ if not data and not self._obj.unconsumed_tail: - return data -+ original_max_length = max_length -+ if original_max_length < 0: -+ max_length = 0 -+ elif original_max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unfed_data = data -+ return b"" - -+ # Subsequent calls always reuse `self._obj`. zlib requires -+ # passing the unconsumed tail if decompression is to continue. - if not self._first_try: -- return self._obj.decompress(data) -+ return self._obj.decompress( -+ self._obj.unconsumed_tail + data, max_length=max_length -+ ) - -- self._data += data -+ # First call tries with RFC 1950 ZLIB format. -+ self._first_try_data += data - try: -- decompressed = self._obj.decompress(data) -+ decompressed = self._obj.decompress(data, max_length=max_length) - if decompressed: - self._first_try = False -- self._data = None -+ self._first_try_data = b"" - return decompressed -+ # On failure, it falls back to RFC 1951 DEFLATE format. - except zlib.error: - self._first_try = False - self._obj = zlib.decompressobj(-zlib.MAX_WBITS) - try: -- return self.decompress(self._data) -+ return self.decompress( -+ self._first_try_data, max_length=original_max_length -+ ) - finally: -- self._data = None -+ self._first_try_data = b"" - -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unfed_data) or ( -+ bool(self._obj.unconsumed_tail) and not self._first_try -+ ) - - class GzipDecoderState(object): - -@@ -81,30 +108,64 @@ - def __init__(self): - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - self._state = GzipDecoderState.FIRST_MEMBER -+ self._unconsumed_tail = b"" - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: - ret = bytearray() -- if self._state == GzipDecoderState.SWALLOW_DATA or not data: -+ if self._state == GzipDecoderState.SWALLOW_DATA: -+ return bytes(ret) -+ -+ if max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unconsumed_tail += data -+ return b"" -+ -+ # zlib requires passing the unconsumed tail to the subsequent -+ # call if decompression is to continue. -+ data = self._unconsumed_tail + data -+ if not data and self._obj.eof: - return bytes(ret) -+ - while True: - try: -- ret += self._obj.decompress(data) -+ ret += self._obj.decompress( -+ data, max_length=max(max_length - len(ret), 0) -+ ) - except zlib.error: - previous_state = self._state - # Ignore data after the first error - self._state = GzipDecoderState.SWALLOW_DATA -+ self._unconsumed_tail = b"" - if previous_state == GzipDecoderState.OTHER_MEMBERS: - # Allow trailing garbage acceptable in other gzip clients - return bytes(ret) - raise -- data = self._obj.unused_data -+ -+ self._unconsumed_tail = data = ( -+ self._obj.unconsumed_tail or self._obj.unused_data -+ ) -+ if max_length > 0 and len(ret) >= max_length: -+ break -+ - if not data: - return bytes(ret) -- self._state = GzipDecoderState.OTHER_MEMBERS -- self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ # When the end of a gzip member is reached, a new decompressor -+ # must be created for unused (possibly future) data. -+ if self._obj.eof: -+ self._state = GzipDecoderState.OTHER_MEMBERS -+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ -+ return bytes(ret) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unconsumed_tail) - - - if brotli is not None: -@@ -116,9 +177,35 @@ - def __init__(self): - self._obj = brotli.Decompressor() - if hasattr(self._obj, "decompress"): -- self.decompress = self._obj.decompress -+ setattr(self, "_decompress", self._obj.decompress) - else: -- self.decompress = self._obj.process -+ setattr(self, "_decompress", self._obj.process) -+ -+ # Requires Brotli >= 1.2.0 for `output_buffer_limit`. -+ def _decompress(self, data: bytes, output_buffer_limit: int = -1) -> bytes: -+ raise NotImplementedError() -+ -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ try: -+ if max_length > 0: -+ return self._decompress(data, output_buffer_limit=max_length) -+ else: -+ return self._decompress(data) -+ except TypeError: -+ # Fallback for Brotli/brotlicffi/brotlipy versions without -+ # the `output_buffer_limit` parameter. -+ warnings.warn( -+ "Brotli >= 1.2.0 is required to prevent decompression bombs.", -+ DependencyWarning, -+ ) -+ return self._decompress(data) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ try: -+ return not self._obj.can_accept_more_data() -+ except AttributeError: -+ return False - - def flush(self): - if hasattr(self._obj, "flush"): -@@ -151,10 +238,35 @@ - def flush(self): - return self._decoders[0].flush() - -- def decompress(self, data): -- for d in reversed(self._decoders): -- data = d.decompress(data) -- return data -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ if max_length <= 0: -+ for d in reversed(self._decoders): -+ data = d.decompress(data) -+ return data -+ -+ ret = bytearray() -+ # Every while loop iteration goes through all decoders once. -+ # It exits when enough data is read or no more data can be read. -+ # It is possible that the while loop iteration does not produce -+ # any data because we retrieve up to `max_length` from every -+ # decoder, and the amount of bytes may be insufficient for the -+ # next decoder to produce enough/any output. -+ while True: -+ any_data = False -+ for d in reversed(self._decoders): -+ data = d.decompress(data, max_length=max_length - len(ret)) -+ if data: -+ any_data = True -+ # We should not break when no data is returned because -+ # next decoders may produce data even with empty input. -+ ret += data -+ if not any_data or len(ret) >= max_length: -+ return bytes(ret) -+ data = b"" -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return any(d.has_unconsumed_tail for d in self._decoders) - - - def _get_decoder(mode): -@@ -405,16 +517,25 @@ - if brotli is not None: - DECODER_ERROR_CLASSES += (brotli.error,) - -- def _decode(self, data, decode_content, flush_decoder): -+ def _decode( -+ self, -+ data: bytes, -+ decode_content: bool, -+ flush_decoder: bool, -+ max_length: int = None, -+ ) -> bytes: - """ - Decode the data passed in and potentially flush the decoder. - """ - if not decode_content: - return data - -+ if max_length is None or flush_decoder: -+ max_length = -1 -+ - try: - if self._decoder: -- data = self._decoder.decompress(data) -+ data = self._decoder.decompress(data, max_length=max_length) - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( -@@ -634,7 +755,10 @@ - for line in self.read_chunked(amt, decode_content=decode_content): - yield line - else: -- while not is_fp_closed(self._fp): -+ while ( -+ not is_fp_closed(self._fp) -+ or (self._decoder and self._decoder.has_unconsumed_tail) -+ ): - data = self.read(amt=amt, decode_content=decode_content) - - if data: -@@ -840,7 +964,10 @@ - break - chunk = self._handle_chunk(amt) - decoded = self._decode( -- chunk, decode_content=decode_content, flush_decoder=False -+ chunk, -+ decode_content=decode_content, -+ flush_decoder=False, -+ max_length=amt, - ) - if decoded: - yield decoded - ---- a/google/urllib3/response.py 2026-01-20 10:46:57.006470161 +0100 -+++ b/google/urllib3/response.py 2026-01-20 10:55:44.090084896 +0100 -@@ -23,6 +23,7 @@ - from .exceptions import ( - BodyNotHttplibCompatible, - DecodeError, -+ DependencyWarning, - HTTPError, - IncompleteRead, - InvalidChunkLength, -@@ -41,34 +42,60 @@ - class DeflateDecoder(object): - def __init__(self): - self._first_try = True -- self._data = b"" -+ self._first_try_data = b"" -+ self._unfed_data = b"" - self._obj = zlib.decompressobj() - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -- if not data: -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ data = self._unfed_data + data -+ self._unfed_data = b"" -+ if not data and not self._obj.unconsumed_tail: - return data -+ original_max_length = max_length -+ if original_max_length < 0: -+ max_length = 0 -+ elif original_max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unfed_data = data -+ return b"" - -+ # Subsequent calls always reuse `self._obj`. zlib requires -+ # passing the unconsumed tail if decompression is to continue. - if not self._first_try: -- return self._obj.decompress(data) -+ return self._obj.decompress( -+ self._obj.unconsumed_tail + data, max_length=max_length -+ ) - -- self._data += data -+ # First call tries with RFC 1950 ZLIB format. -+ self._first_try_data += data - try: -- decompressed = self._obj.decompress(data) -+ decompressed = self._obj.decompress(data, max_length=max_length) - if decompressed: - self._first_try = False -- self._data = None -+ self._first_try_data = b"" - return decompressed -+ # On failure, it falls back to RFC 1951 DEFLATE format. - except zlib.error: - self._first_try = False - self._obj = zlib.decompressobj(-zlib.MAX_WBITS) - try: -- return self.decompress(self._data) -+ return self.decompress( -+ self._first_try_data, max_length=original_max_length -+ ) - finally: -- self._data = None -+ self._first_try_data = b"" - -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unfed_data) or ( -+ bool(self._obj.unconsumed_tail) and not self._first_try -+ ) - - class GzipDecoderState(object): - -@@ -81,30 +108,64 @@ - def __init__(self): - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - self._state = GzipDecoderState.FIRST_MEMBER -+ self._unconsumed_tail = b"" - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: - ret = bytearray() -- if self._state == GzipDecoderState.SWALLOW_DATA or not data: -+ if self._state == GzipDecoderState.SWALLOW_DATA: -+ return bytes(ret) -+ -+ if max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unconsumed_tail += data -+ return b"" -+ -+ # zlib requires passing the unconsumed tail to the subsequent -+ # call if decompression is to continue. -+ data = self._unconsumed_tail + data -+ if not data and self._obj.eof: - return bytes(ret) -+ - while True: - try: -- ret += self._obj.decompress(data) -+ ret += self._obj.decompress( -+ data, max_length=max(max_length - len(ret), 0) -+ ) - except zlib.error: - previous_state = self._state - # Ignore data after the first error - self._state = GzipDecoderState.SWALLOW_DATA -+ self._unconsumed_tail = b"" - if previous_state == GzipDecoderState.OTHER_MEMBERS: - # Allow trailing garbage acceptable in other gzip clients - return bytes(ret) - raise -- data = self._obj.unused_data -+ -+ self._unconsumed_tail = data = ( -+ self._obj.unconsumed_tail or self._obj.unused_data -+ ) -+ if max_length > 0 and len(ret) >= max_length: -+ break -+ - if not data: - return bytes(ret) -- self._state = GzipDecoderState.OTHER_MEMBERS -- self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ # When the end of a gzip member is reached, a new decompressor -+ # must be created for unused (possibly future) data. -+ if self._obj.eof: -+ self._state = GzipDecoderState.OTHER_MEMBERS -+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ -+ return bytes(ret) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unconsumed_tail) - - - if brotli is not None: -@@ -116,9 +177,35 @@ - def __init__(self): - self._obj = brotli.Decompressor() - if hasattr(self._obj, "decompress"): -- self.decompress = self._obj.decompress -+ setattr(self, "_decompress", self._obj.decompress) - else: -- self.decompress = self._obj.process -+ setattr(self, "_decompress", self._obj.process) -+ -+ # Requires Brotli >= 1.2.0 for `output_buffer_limit`. -+ def _decompress(self, data: bytes, output_buffer_limit: int = -1) -> bytes: -+ raise NotImplementedError() -+ -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ try: -+ if max_length > 0: -+ return self._decompress(data, output_buffer_limit=max_length) -+ else: -+ return self._decompress(data) -+ except TypeError: -+ # Fallback for Brotli/brotlicffi/brotlipy versions without -+ # the `output_buffer_limit` parameter. -+ warnings.warn( -+ "Brotli >= 1.2.0 is required to prevent decompression bombs.", -+ DependencyWarning, -+ ) -+ return self._decompress(data) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ try: -+ return not self._obj.can_accept_more_data() -+ except AttributeError: -+ return False - - def flush(self): - if hasattr(self._obj, "flush"): -@@ -151,10 +238,35 @@ - def flush(self): - return self._decoders[0].flush() - -- def decompress(self, data): -- for d in reversed(self._decoders): -- data = d.decompress(data) -- return data -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ if max_length <= 0: -+ for d in reversed(self._decoders): -+ data = d.decompress(data) -+ return data -+ -+ ret = bytearray() -+ # Every while loop iteration goes through all decoders once. -+ # It exits when enough data is read or no more data can be read. -+ # It is possible that the while loop iteration does not produce -+ # any data because we retrieve up to `max_length` from every -+ # decoder, and the amount of bytes may be insufficient for the -+ # next decoder to produce enough/any output. -+ while True: -+ any_data = False -+ for d in reversed(self._decoders): -+ data = d.decompress(data, max_length=max_length - len(ret)) -+ if data: -+ any_data = True -+ # We should not break when no data is returned because -+ # next decoders may produce data even with empty input. -+ ret += data -+ if not any_data or len(ret) >= max_length: -+ return bytes(ret) -+ data = b"" -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return any(d.has_unconsumed_tail for d in self._decoders) - - - def _get_decoder(mode): -@@ -405,16 +517,25 @@ - if brotli is not None: - DECODER_ERROR_CLASSES += (brotli.error,) - -- def _decode(self, data, decode_content, flush_decoder): -+ def _decode( -+ self, -+ data: bytes, -+ decode_content: bool, -+ flush_decoder: bool, -+ max_length: int = None, -+ ) -> bytes: - """ - Decode the data passed in and potentially flush the decoder. - """ - if not decode_content: - return data - -+ if max_length is None or flush_decoder: -+ max_length = -1 -+ - try: - if self._decoder: -- data = self._decoder.decompress(data) -+ data = self._decoder.decompress(data, max_length=max_length) - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( -@@ -634,7 +755,10 @@ - for line in self.read_chunked(amt, decode_content=decode_content): - yield line - else: -- while not is_fp_closed(self._fp): -+ while ( -+ not is_fp_closed(self._fp) -+ or (self._decoder and self._decoder.has_unconsumed_tail) -+ ): - data = self.read(amt=amt, decode_content=decode_content) - - if data: -@@ -840,7 +964,10 @@ - break - chunk = self._handle_chunk(amt) - decoded = self._decode( -- chunk, decode_content=decode_content, flush_decoder=False -+ chunk, -+ decode_content=decode_content, -+ flush_decoder=False, -+ max_length=amt, - ) - if decoded: - yield decoded diff --git a/SOURCES/RHEL-14030-1-all-agents-metadata-update-IO-Power-Network.patch b/SOURCES/RHEL-14030-1-all-agents-metadata-update-IO-Power-Network.patch index 79c5885..741ad01 100644 --- a/SOURCES/RHEL-14030-1-all-agents-metadata-update-IO-Power-Network.patch +++ b/SOURCES/RHEL-14030-1-all-agents-metadata-update-IO-Power-Network.patch @@ -503,7 +503,7 @@ index 612450568..f30a1da28 100644 -import sys, re +import sys, os, re - sys.path.insert(0, '/usr/lib/fence-agents/support/common') + sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') try: import pexpect @@ -73,11 +73,11 @@ def main(): diff --git a/SOURCES/RHEL-140795-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch b/SOURCES/RHEL-140795-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch deleted file mode 100644 index ce3acbc..0000000 --- a/SOURCES/RHEL-140795-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch +++ /dev/null @@ -1,95 +0,0 @@ ---- a/aws/urllib3/response.py 2026-02-03 08:20:11.000000000 +0100 -+++ b/aws/urllib3/response.py 2026-02-03 09:11:38.017998476 +0100 -@@ -350,6 +350,7 @@ - self.reason = reason - self.strict = strict - self.decode_content = decode_content -+ self._has_decoded_content = False - self.retries = retries - self.enforce_content_length = enforce_content_length - self.auto_close = auto_close -@@ -414,7 +415,11 @@ - Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. - """ - try: -- self.read() -+ self.read( -+ # Do not spend resources decoding the content unless -+ # decoding has already been initiated. -+ decode_content=self._has_decoded_content, -+ ) - except (HTTPError, SocketError, BaseSSLError, HTTPException): - pass - -@@ -536,6 +541,7 @@ - try: - if self._decoder: - data = self._decoder.decompress(data, max_length=max_length) -+ self._has_decoded_content = True - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( - ---- a/azure/urllib3/response.py 2026-02-03 08:20:11.000000000 +0100 -+++ b/azure/urllib3/response.py 2026-02-03 09:11:38.017998476 +0100 -@@ -350,6 +350,7 @@ - self.reason = reason - self.strict = strict - self.decode_content = decode_content -+ self._has_decoded_content = False - self.retries = retries - self.enforce_content_length = enforce_content_length - self.auto_close = auto_close -@@ -414,7 +415,11 @@ - Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. - """ - try: -- self.read() -+ self.read( -+ # Do not spend resources decoding the content unless -+ # decoding has already been initiated. -+ decode_content=self._has_decoded_content, -+ ) - except (HTTPError, SocketError, BaseSSLError, HTTPException): - pass - -@@ -536,6 +541,7 @@ - try: - if self._decoder: - data = self._decoder.decompress(data, max_length=max_length) -+ self._has_decoded_content = True - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( - ---- a/google/urllib3/response.py 2026-02-03 08:20:11.000000000 +0100 -+++ b/google/urllib3/response.py 2026-02-03 09:11:38.017998476 +0100 -@@ -350,6 +350,7 @@ - self.reason = reason - self.strict = strict - self.decode_content = decode_content -+ self._has_decoded_content = False - self.retries = retries - self.enforce_content_length = enforce_content_length - self.auto_close = auto_close -@@ -414,7 +415,11 @@ - Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. - """ - try: -- self.read() -+ self.read( -+ # Do not spend resources decoding the content unless -+ # decoding has already been initiated. -+ decode_content=self._has_decoded_content, -+ ) - except (HTTPError, SocketError, BaseSSLError, HTTPException): - pass - -@@ -536,6 +541,7 @@ - try: - if self._decoder: - data = self._decoder.decompress(data, max_length=max_length) -+ self._has_decoded_content = True - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( diff --git a/SOURCES/RHEL-142459-fix-bundled-pyasn1-CVE-2026-23490.patch b/SOURCES/RHEL-142459-fix-bundled-pyasn1-CVE-2026-23490.patch index 4f73e78..cb6adac 100644 --- a/SOURCES/RHEL-142459-fix-bundled-pyasn1-CVE-2026-23490.patch +++ b/SOURCES/RHEL-142459-fix-bundled-pyasn1-CVE-2026-23490.patch @@ -1,5 +1,5 @@ ---- a/google/pyasn1/codec/ber/decoder.py 2019-10-17 07:00:19.000000000 +0200 -+++ b/google/pyasn1/codec/ber/decoder.py 2026-01-27 10:43:12.757563432 +0100 +--- a/google/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py 2019-10-17 07:00:19.000000000 +0200 ++++ b/google/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py 2026-01-27 10:43:12.757563432 +0100 @@ -22,6 +22,10 @@ noValue = base.noValue diff --git a/SOURCES/RHEL-146351-ibm-1-fix-bundled-urllib3-CVE-2024-37891.patch b/SOURCES/RHEL-146351-ibm-1-fix-bundled-urllib3-CVE-2024-37891.patch deleted file mode 100644 index dd7abb5..0000000 --- a/SOURCES/RHEL-146351-ibm-1-fix-bundled-urllib3-CVE-2024-37891.patch +++ /dev/null @@ -1,32 +0,0 @@ -From accff72ecc2f6cf5a76d9570198a93ac7c90270e Mon Sep 17 00:00:00 2001 -From: Quentin Pradet -Date: Mon, 17 Jun 2024 11:09:06 +0400 -Subject: [PATCH] Merge pull request from GHSA-34jh-p97f-mpxf - -* Strip Proxy-Authorization header on redirects - -* Fix test_retry_default_remove_headers_on_redirect - -* Set release date ---- - CHANGES.rst | 5 +++++ - src/urllib3/util/retry.py | 4 +++- - test/test_retry.py | 6 ++++- - test/with_dummyserver/test_poolmanager.py | 27 ++++++++++++++++++++--- - 4 files changed, 37 insertions(+), 5 deletions(-) - -diff --git a/ibm/urllib3/util/retry.py b/ibm/urllib3/util/retry.py -index 7a76a4a6ad..0456cceba4 100644 ---- a/ibm/urllib3/util/retry.py -+++ b/ibm/urllib3/util/retry.py -@@ -189,7 +189,9 @@ class Retry: - RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - - #: Default headers to be used for ``remove_headers_on_redirect`` -- DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"]) -+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset( -+ ["Cookie", "Authorization", "Proxy-Authorization"] -+ ) - - #: Default maximum backoff time. - DEFAULT_BACKOFF_MAX = 120 diff --git a/SOURCES/RHEL-146351-ibm-2-fix-bundled-urllib3-CVE-2025-66418.patch b/SOURCES/RHEL-146351-ibm-2-fix-bundled-urllib3-CVE-2025-66418.patch deleted file mode 100644 index 8592d81..0000000 --- a/SOURCES/RHEL-146351-ibm-2-fix-bundled-urllib3-CVE-2025-66418.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/ibm/urllib3/response.py 2023-10-17 19:42:56.000000000 +0200 -+++ b/ibm/urllib3/response.py 2026-01-02 11:19:25.583808492 +0100 -@@ -135,8 +135,18 @@ - they were applied. - """ - -+ # Maximum allowed number of chained HTTP encodings in the -+ # Content-Encoding header. -+ max_decode_links = 5 -+ - def __init__(self, modes): -- self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")] -+ encodings = [m.strip() for m in modes.split(",")] -+ if len(encodings) > self.max_decode_links: -+ raise DecodeError( -+ "Too many content encodings in the chain: " -+ f"{len(encodings)} > {self.max_decode_links}" -+ ) -+ self._decoders = [_get_decoder(e) for e in encodings] - - def flush(self): - return self._decoders[0].flush() diff --git a/SOURCES/RHEL-146351-ibm-3-fix-bundled-urllib3-CVE-2025-66471.patch b/SOURCES/RHEL-146351-ibm-3-fix-bundled-urllib3-CVE-2025-66471.patch deleted file mode 100644 index 761b186..0000000 --- a/SOURCES/RHEL-146351-ibm-3-fix-bundled-urllib3-CVE-2025-66471.patch +++ /dev/null @@ -1,281 +0,0 @@ ---- a/ibm/urllib3/response.py 2026-01-20 10:46:57.006470161 +0100 -+++ b/ibm/urllib3/response.py 2026-01-20 10:55:44.090084896 +0100 -@@ -23,6 +23,7 @@ - from .exceptions import ( - BodyNotHttplibCompatible, - DecodeError, -+ DependencyWarning, - HTTPError, - IncompleteRead, - InvalidChunkLength, -@@ -41,34 +42,60 @@ - class DeflateDecoder(object): - def __init__(self): - self._first_try = True -- self._data = b"" -+ self._first_try_data = b"" -+ self._unfed_data = b"" - self._obj = zlib.decompressobj() - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -- if not data: -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ data = self._unfed_data + data -+ self._unfed_data = b"" -+ if not data and not self._obj.unconsumed_tail: - return data -+ original_max_length = max_length -+ if original_max_length < 0: -+ max_length = 0 -+ elif original_max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unfed_data = data -+ return b"" - -+ # Subsequent calls always reuse `self._obj`. zlib requires -+ # passing the unconsumed tail if decompression is to continue. - if not self._first_try: -- return self._obj.decompress(data) -+ return self._obj.decompress( -+ self._obj.unconsumed_tail + data, max_length=max_length -+ ) - -- self._data += data -+ # First call tries with RFC 1950 ZLIB format. -+ self._first_try_data += data - try: -- decompressed = self._obj.decompress(data) -+ decompressed = self._obj.decompress(data, max_length=max_length) - if decompressed: - self._first_try = False -- self._data = None -+ self._first_try_data = b"" - return decompressed -+ # On failure, it falls back to RFC 1951 DEFLATE format. - except zlib.error: - self._first_try = False - self._obj = zlib.decompressobj(-zlib.MAX_WBITS) - try: -- return self.decompress(self._data) -+ return self.decompress( -+ self._first_try_data, max_length=original_max_length -+ ) - finally: -- self._data = None -+ self._first_try_data = b"" - -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unfed_data) or ( -+ bool(self._obj.unconsumed_tail) and not self._first_try -+ ) - - class GzipDecoderState(object): - -@@ -81,30 +108,64 @@ - def __init__(self): - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - self._state = GzipDecoderState.FIRST_MEMBER -+ self._unconsumed_tail = b"" - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: - ret = bytearray() -- if self._state == GzipDecoderState.SWALLOW_DATA or not data: -+ if self._state == GzipDecoderState.SWALLOW_DATA: -+ return bytes(ret) -+ -+ if max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unconsumed_tail += data -+ return b"" -+ -+ # zlib requires passing the unconsumed tail to the subsequent -+ # call if decompression is to continue. -+ data = self._unconsumed_tail + data -+ if not data and self._obj.eof: - return bytes(ret) -+ - while True: - try: -- ret += self._obj.decompress(data) -+ ret += self._obj.decompress( -+ data, max_length=max(max_length - len(ret), 0) -+ ) - except zlib.error: - previous_state = self._state - # Ignore data after the first error - self._state = GzipDecoderState.SWALLOW_DATA -+ self._unconsumed_tail = b"" - if previous_state == GzipDecoderState.OTHER_MEMBERS: - # Allow trailing garbage acceptable in other gzip clients - return bytes(ret) - raise -- data = self._obj.unused_data -+ -+ self._unconsumed_tail = data = ( -+ self._obj.unconsumed_tail or self._obj.unused_data -+ ) -+ if max_length > 0 and len(ret) >= max_length: -+ break -+ - if not data: - return bytes(ret) -- self._state = GzipDecoderState.OTHER_MEMBERS -- self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ # When the end of a gzip member is reached, a new decompressor -+ # must be created for unused (possibly future) data. -+ if self._obj.eof: -+ self._state = GzipDecoderState.OTHER_MEMBERS -+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ -+ return bytes(ret) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unconsumed_tail) - - - if brotli is not None: -@@ -116,9 +177,35 @@ - def __init__(self): - self._obj = brotli.Decompressor() - if hasattr(self._obj, "decompress"): -- self.decompress = self._obj.decompress -+ setattr(self, "_decompress", self._obj.decompress) - else: -- self.decompress = self._obj.process -+ setattr(self, "_decompress", self._obj.process) -+ -+ # Requires Brotli >= 1.2.0 for `output_buffer_limit`. -+ def _decompress(self, data: bytes, output_buffer_limit: int = -1) -> bytes: -+ raise NotImplementedError() -+ -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ try: -+ if max_length > 0: -+ return self._decompress(data, output_buffer_limit=max_length) -+ else: -+ return self._decompress(data) -+ except TypeError: -+ # Fallback for Brotli/brotlicffi/brotlipy versions without -+ # the `output_buffer_limit` parameter. -+ warnings.warn( -+ "Brotli >= 1.2.0 is required to prevent decompression bombs.", -+ DependencyWarning, -+ ) -+ return self._decompress(data) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ try: -+ return not self._obj.can_accept_more_data() -+ except AttributeError: -+ return False - - def flush(self): - if hasattr(self._obj, "flush"): -@@ -151,10 +238,35 @@ - def flush(self): - return self._decoders[0].flush() - -- def decompress(self, data): -- for d in reversed(self._decoders): -- data = d.decompress(data) -- return data -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ if max_length <= 0: -+ for d in reversed(self._decoders): -+ data = d.decompress(data) -+ return data -+ -+ ret = bytearray() -+ # Every while loop iteration goes through all decoders once. -+ # It exits when enough data is read or no more data can be read. -+ # It is possible that the while loop iteration does not produce -+ # any data because we retrieve up to `max_length` from every -+ # decoder, and the amount of bytes may be insufficient for the -+ # next decoder to produce enough/any output. -+ while True: -+ any_data = False -+ for d in reversed(self._decoders): -+ data = d.decompress(data, max_length=max_length - len(ret)) -+ if data: -+ any_data = True -+ # We should not break when no data is returned because -+ # next decoders may produce data even with empty input. -+ ret += data -+ if not any_data or len(ret) >= max_length: -+ return bytes(ret) -+ data = b"" -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return any(d.has_unconsumed_tail for d in self._decoders) - - - def _get_decoder(mode): -@@ -405,16 +517,25 @@ - if brotli is not None: - DECODER_ERROR_CLASSES += (brotli.error,) - -- def _decode(self, data, decode_content, flush_decoder): -+ def _decode( -+ self, -+ data: bytes, -+ decode_content: bool, -+ flush_decoder: bool, -+ max_length: int = None, -+ ) -> bytes: - """ - Decode the data passed in and potentially flush the decoder. - """ - if not decode_content: - return data - -+ if max_length is None or flush_decoder: -+ max_length = -1 -+ - try: - if self._decoder: -- data = self._decoder.decompress(data) -+ data = self._decoder.decompress(data, max_length=max_length) - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( -@@ -634,7 +755,10 @@ - for line in self.read_chunked(amt, decode_content=decode_content): - yield line - else: -- while not is_fp_closed(self._fp): -+ while ( -+ not is_fp_closed(self._fp) -+ or (self._decoder and self._decoder.has_unconsumed_tail) -+ ): - data = self.read(amt=amt, decode_content=decode_content) - - if data: -@@ -840,7 +964,10 @@ - break - chunk = self._handle_chunk(amt) - decoded = self._decode( -- chunk, decode_content=decode_content, flush_decoder=False -+ chunk, -+ decode_content=decode_content, -+ flush_decoder=False, -+ max_length=amt, - ) - if decoded: - yield decoded diff --git a/SOURCES/RHEL-146351-ibm-4-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch b/SOURCES/RHEL-146351-ibm-4-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch deleted file mode 100644 index 99ee1ca..0000000 --- a/SOURCES/RHEL-146351-ibm-4-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/ibm/urllib3/response.py 2026-02-03 08:20:11.000000000 +0100 -+++ b/ibm/urllib3/response.py 2026-02-03 09:11:38.017998476 +0100 -@@ -350,6 +350,7 @@ - self.reason = reason - self.strict = strict - self.decode_content = decode_content -+ self._has_decoded_content = False - self.retries = retries - self.enforce_content_length = enforce_content_length - self.auto_close = auto_close -@@ -414,7 +415,11 @@ - Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. - """ - try: -- self.read() -+ self.read( -+ # Do not spend resources decoding the content unless -+ # decoding has already been initiated. -+ decode_content=self._has_decoded_content, -+ ) - except (HTTPError, SocketError, BaseSSLError, HTTPException): - pass - -@@ -536,6 +541,7 @@ - try: - if self._decoder: - data = self._decoder.decompress(data, max_length=max_length) -+ self._has_decoded_content = True - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( diff --git a/SOURCES/RHEL-146351-kubevirt-1-fix-bundled-urllib3-CVE-2024-37891.patch b/SOURCES/RHEL-146351-kubevirt-1-fix-bundled-urllib3-CVE-2024-37891.patch deleted file mode 100644 index f5abf83..0000000 --- a/SOURCES/RHEL-146351-kubevirt-1-fix-bundled-urllib3-CVE-2024-37891.patch +++ /dev/null @@ -1,32 +0,0 @@ -From accff72ecc2f6cf5a76d9570198a93ac7c90270e Mon Sep 17 00:00:00 2001 -From: Quentin Pradet -Date: Mon, 17 Jun 2024 11:09:06 +0400 -Subject: [PATCH] Merge pull request from GHSA-34jh-p97f-mpxf - -* Strip Proxy-Authorization header on redirects - -* Fix test_retry_default_remove_headers_on_redirect - -* Set release date ---- - CHANGES.rst | 5 +++++ - src/urllib3/util/retry.py | 4 +++- - test/test_retry.py | 6 ++++- - test/with_dummyserver/test_poolmanager.py | 27 ++++++++++++++++++++--- - 4 files changed, 37 insertions(+), 5 deletions(-) - -diff --git a/kubevirt/urllib3/util/retry.py b/kubevirt/urllib3/util/retry.py -index 7a76a4a6ad..0456cceba4 100644 ---- a/kubevirt/urllib3/util/retry.py -+++ b/kubevirt/urllib3/util/retry.py -@@ -189,7 +189,9 @@ class Retry: - RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - - #: Default headers to be used for ``remove_headers_on_redirect`` -- DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"]) -+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset( -+ ["Cookie", "Authorization", "Proxy-Authorization"] -+ ) - - #: Default maximum backoff time. - DEFAULT_BACKOFF_MAX = 120 diff --git a/SOURCES/RHEL-146351-kubevirt-2-fix-bundled-urllib3-CVE-2025-66418.patch b/SOURCES/RHEL-146351-kubevirt-2-fix-bundled-urllib3-CVE-2025-66418.patch deleted file mode 100644 index 49a9c40..0000000 --- a/SOURCES/RHEL-146351-kubevirt-2-fix-bundled-urllib3-CVE-2025-66418.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/kubevirt/urllib3/response.py 2023-10-17 19:42:56.000000000 +0200 -+++ b/kubevirt/urllib3/response.py 2026-01-02 11:19:25.583808492 +0100 -@@ -135,8 +135,18 @@ - they were applied. - """ - -+ # Maximum allowed number of chained HTTP encodings in the -+ # Content-Encoding header. -+ max_decode_links = 5 -+ - def __init__(self, modes): -- self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")] -+ encodings = [m.strip() for m in modes.split(",")] -+ if len(encodings) > self.max_decode_links: -+ raise DecodeError( -+ "Too many content encodings in the chain: " -+ f"{len(encodings)} > {self.max_decode_links}" -+ ) -+ self._decoders = [_get_decoder(e) for e in encodings] - - def flush(self): - return self._decoders[0].flush() diff --git a/SOURCES/RHEL-146351-kubevirt-3-fix-bundled-urllib3-CVE-2025-66471.patch b/SOURCES/RHEL-146351-kubevirt-3-fix-bundled-urllib3-CVE-2025-66471.patch deleted file mode 100644 index b2aa99c..0000000 --- a/SOURCES/RHEL-146351-kubevirt-3-fix-bundled-urllib3-CVE-2025-66471.patch +++ /dev/null @@ -1,281 +0,0 @@ ---- a/kubevirt/urllib3/response.py 2026-01-20 10:46:57.006470161 +0100 -+++ b/kubevirt/urllib3/response.py 2026-01-20 10:55:44.090084896 +0100 -@@ -23,6 +23,7 @@ - from .exceptions import ( - BodyNotHttplibCompatible, - DecodeError, -+ DependencyWarning, - HTTPError, - IncompleteRead, - InvalidChunkLength, -@@ -41,34 +42,60 @@ - class DeflateDecoder(object): - def __init__(self): - self._first_try = True -- self._data = b"" -+ self._first_try_data = b"" -+ self._unfed_data = b"" - self._obj = zlib.decompressobj() - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -- if not data: -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ data = self._unfed_data + data -+ self._unfed_data = b"" -+ if not data and not self._obj.unconsumed_tail: - return data -+ original_max_length = max_length -+ if original_max_length < 0: -+ max_length = 0 -+ elif original_max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unfed_data = data -+ return b"" - -+ # Subsequent calls always reuse `self._obj`. zlib requires -+ # passing the unconsumed tail if decompression is to continue. - if not self._first_try: -- return self._obj.decompress(data) -+ return self._obj.decompress( -+ self._obj.unconsumed_tail + data, max_length=max_length -+ ) - -- self._data += data -+ # First call tries with RFC 1950 ZLIB format. -+ self._first_try_data += data - try: -- decompressed = self._obj.decompress(data) -+ decompressed = self._obj.decompress(data, max_length=max_length) - if decompressed: - self._first_try = False -- self._data = None -+ self._first_try_data = b"" - return decompressed -+ # On failure, it falls back to RFC 1951 DEFLATE format. - except zlib.error: - self._first_try = False - self._obj = zlib.decompressobj(-zlib.MAX_WBITS) - try: -- return self.decompress(self._data) -+ return self.decompress( -+ self._first_try_data, max_length=original_max_length -+ ) - finally: -- self._data = None -+ self._first_try_data = b"" - -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unfed_data) or ( -+ bool(self._obj.unconsumed_tail) and not self._first_try -+ ) - - class GzipDecoderState(object): - -@@ -81,30 +108,64 @@ - def __init__(self): - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - self._state = GzipDecoderState.FIRST_MEMBER -+ self._unconsumed_tail = b"" - - def __getattr__(self, name): - return getattr(self._obj, name) - -- def decompress(self, data): -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: - ret = bytearray() -- if self._state == GzipDecoderState.SWALLOW_DATA or not data: -+ if self._state == GzipDecoderState.SWALLOW_DATA: -+ return bytes(ret) -+ -+ if max_length == 0: -+ # We should not pass 0 to the zlib decompressor because 0 is -+ # the default value that will make zlib decompress without a -+ # length limit. -+ # Data should be stored for subsequent calls. -+ self._unconsumed_tail += data -+ return b"" -+ -+ # zlib requires passing the unconsumed tail to the subsequent -+ # call if decompression is to continue. -+ data = self._unconsumed_tail + data -+ if not data and self._obj.eof: - return bytes(ret) -+ - while True: - try: -- ret += self._obj.decompress(data) -+ ret += self._obj.decompress( -+ data, max_length=max(max_length - len(ret), 0) -+ ) - except zlib.error: - previous_state = self._state - # Ignore data after the first error - self._state = GzipDecoderState.SWALLOW_DATA -+ self._unconsumed_tail = b"" - if previous_state == GzipDecoderState.OTHER_MEMBERS: - # Allow trailing garbage acceptable in other gzip clients - return bytes(ret) - raise -- data = self._obj.unused_data -+ -+ self._unconsumed_tail = data = ( -+ self._obj.unconsumed_tail or self._obj.unused_data -+ ) -+ if max_length > 0 and len(ret) >= max_length: -+ break -+ - if not data: - return bytes(ret) -- self._state = GzipDecoderState.OTHER_MEMBERS -- self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ # When the end of a gzip member is reached, a new decompressor -+ # must be created for unused (possibly future) data. -+ if self._obj.eof: -+ self._state = GzipDecoderState.OTHER_MEMBERS -+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) -+ -+ return bytes(ret) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return bool(self._unconsumed_tail) - - - if brotli is not None: -@@ -116,9 +177,35 @@ - def __init__(self): - self._obj = brotli.Decompressor() - if hasattr(self._obj, "decompress"): -- self.decompress = self._obj.decompress -+ setattr(self, "_decompress", self._obj.decompress) - else: -- self.decompress = self._obj.process -+ setattr(self, "_decompress", self._obj.process) -+ -+ # Requires Brotli >= 1.2.0 for `output_buffer_limit`. -+ def _decompress(self, data: bytes, output_buffer_limit: int = -1) -> bytes: -+ raise NotImplementedError() -+ -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ try: -+ if max_length > 0: -+ return self._decompress(data, output_buffer_limit=max_length) -+ else: -+ return self._decompress(data) -+ except TypeError: -+ # Fallback for Brotli/brotlicffi/brotlipy versions without -+ # the `output_buffer_limit` parameter. -+ warnings.warn( -+ "Brotli >= 1.2.0 is required to prevent decompression bombs.", -+ DependencyWarning, -+ ) -+ return self._decompress(data) -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ try: -+ return not self._obj.can_accept_more_data() -+ except AttributeError: -+ return False - - def flush(self): - if hasattr(self._obj, "flush"): -@@ -151,10 +238,35 @@ - def flush(self): - return self._decoders[0].flush() - -- def decompress(self, data): -- for d in reversed(self._decoders): -- data = d.decompress(data) -- return data -+ def decompress(self, data: bytes, max_length: int = -1) -> bytes: -+ if max_length <= 0: -+ for d in reversed(self._decoders): -+ data = d.decompress(data) -+ return data -+ -+ ret = bytearray() -+ # Every while loop iteration goes through all decoders once. -+ # It exits when enough data is read or no more data can be read. -+ # It is possible that the while loop iteration does not produce -+ # any data because we retrieve up to `max_length` from every -+ # decoder, and the amount of bytes may be insufficient for the -+ # next decoder to produce enough/any output. -+ while True: -+ any_data = False -+ for d in reversed(self._decoders): -+ data = d.decompress(data, max_length=max_length - len(ret)) -+ if data: -+ any_data = True -+ # We should not break when no data is returned because -+ # next decoders may produce data even with empty input. -+ ret += data -+ if not any_data or len(ret) >= max_length: -+ return bytes(ret) -+ data = b"" -+ -+ @property -+ def has_unconsumed_tail(self) -> bool: -+ return any(d.has_unconsumed_tail for d in self._decoders) - - - def _get_decoder(mode): -@@ -405,16 +517,25 @@ - if brotli is not None: - DECODER_ERROR_CLASSES += (brotli.error,) - -- def _decode(self, data, decode_content, flush_decoder): -+ def _decode( -+ self, -+ data: bytes, -+ decode_content: bool, -+ flush_decoder: bool, -+ max_length: int = None, -+ ) -> bytes: - """ - Decode the data passed in and potentially flush the decoder. - """ - if not decode_content: - return data - -+ if max_length is None or flush_decoder: -+ max_length = -1 -+ - try: - if self._decoder: -- data = self._decoder.decompress(data) -+ data = self._decoder.decompress(data, max_length=max_length) - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( -@@ -634,7 +755,10 @@ - for line in self.read_chunked(amt, decode_content=decode_content): - yield line - else: -- while not is_fp_closed(self._fp): -+ while ( -+ not is_fp_closed(self._fp) -+ or (self._decoder and self._decoder.has_unconsumed_tail) -+ ): - data = self.read(amt=amt, decode_content=decode_content) - - if data: -@@ -840,7 +964,10 @@ - break - chunk = self._handle_chunk(amt) - decoded = self._decode( -- chunk, decode_content=decode_content, flush_decoder=False -+ chunk, -+ decode_content=decode_content, -+ flush_decoder=False, -+ max_length=amt, - ) - if decoded: - yield decoded diff --git a/SOURCES/RHEL-146351-kubevirt-4-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch b/SOURCES/RHEL-146351-kubevirt-4-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch deleted file mode 100644 index 5e42f36..0000000 --- a/SOURCES/RHEL-146351-kubevirt-4-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/kubevirt/urllib3/response.py 2026-02-03 08:20:11.000000000 +0100 -+++ b/kubevirt/urllib3/response.py 2026-02-03 09:11:38.017998476 +0100 -@@ -350,6 +350,7 @@ - self.reason = reason - self.strict = strict - self.decode_content = decode_content -+ self._has_decoded_content = False - self.retries = retries - self.enforce_content_length = enforce_content_length - self.auto_close = auto_close -@@ -414,7 +415,11 @@ - Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. - """ - try: -- self.read() -+ self.read( -+ # Do not spend resources decoding the content unless -+ # decoding has already been initiated. -+ decode_content=self._has_decoded_content, -+ ) - except (HTTPError, SocketError, BaseSSLError, HTTPException): - pass - -@@ -536,6 +541,7 @@ - try: - if self._decoder: - data = self._decoder.decompress(data, max_length=max_length) -+ self._has_decoded_content = True - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( diff --git a/SOURCES/RHEL-146351-kubevirt-5-fix-bundled-pyasn1-CVE-2026-23490.patch b/SOURCES/RHEL-146351-kubevirt-fix-bundled-pyasn1-CVE-2026-23490.patch similarity index 81% rename from SOURCES/RHEL-146351-kubevirt-5-fix-bundled-pyasn1-CVE-2026-23490.patch rename to SOURCES/RHEL-146351-kubevirt-fix-bundled-pyasn1-CVE-2026-23490.patch index e7ba33d..8bbe037 100644 --- a/SOURCES/RHEL-146351-kubevirt-5-fix-bundled-pyasn1-CVE-2026-23490.patch +++ b/SOURCES/RHEL-146351-kubevirt-fix-bundled-pyasn1-CVE-2026-23490.patch @@ -1,5 +1,5 @@ ---- a/kubevirt/pyasn1/codec/ber/decoder.py 2019-10-17 07:00:19.000000000 +0200 -+++ b/kubevirt/pyasn1/codec/ber/decoder.py 2026-01-27 10:43:12.757563432 +0100 +--- a/kubevirt/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py 2019-10-17 07:00:19.000000000 +0200 ++++ b/kubevirt/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py 2026-01-27 10:43:12.757563432 +0100 @@ -22,6 +22,10 @@ noValue = base.noValue diff --git a/SOURCES/RHEL-157201-1-kubevirt-fix-bundled-pyasn1-CVE-2026-30922.patch b/SOURCES/RHEL-157201-1-kubevirt-fix-bundled-pyasn1-CVE-2026-30922.patch new file mode 100644 index 0000000..a58762e --- /dev/null +++ b/SOURCES/RHEL-157201-1-kubevirt-fix-bundled-pyasn1-CVE-2026-30922.patch @@ -0,0 +1,40 @@ +From 25ad481c19fdb006e20485ef3fc2e5b3eff30ef0 Mon Sep 17 00:00:00 2001 +From: Simon Pichugin +Date: Mon, 16 Mar 2026 17:23:11 -0700 +Subject: [PATCH] Merge commit from fork + +--- + pyasn1/codec/ber/decoder.py | 10 +++ + tests/codec/ber/test_decoder.py | 116 ++++++++++++++++++++++++++++++++ + tests/codec/cer/test_decoder.py | 24 +++++++ + tests/codec/der/test_decoder.py | 42 ++++++++++++ + 4 files changed, 192 insertions(+) + +diff --git a/kubevirt/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py b/kubevirt/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py +index 50b14e98..2ea0be13 100644 +--- a/kubevirt/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py ++++ b/kubevirt/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py +@@ -36,6 +36,7 @@ + # Maximum number of continuation octets (high-bit set) allowed per OID arc. + # 20 octets allows up to 140-bit integers, supporting UUID-based OIDs + MAX_OID_ARC_CONTINUATION_OCTETS = 20 ++MAX_NESTING_DEPTH = 100 + + # Maximum number of bytes in a BER length field (8 bytes = up to 2^64-1) + MAX_LENGTH_OCTETS = 8 +@@ -1568,6 +1569,15 @@ def __call__(self, substrate, asn1Spec=None, + decodeFun=None, substrateFun=None, + **options): + ++ _nestingLevel = options.get('_nestingLevel', 0) ++ ++ if _nestingLevel > MAX_NESTING_DEPTH: ++ raise error.PyAsn1Error( ++ 'ASN.1 structure nesting depth exceeds limit (%d)' % MAX_NESTING_DEPTH ++ ) ++ ++ options['_nestingLevel'] = _nestingLevel + 1 ++ + allowEoo = options.pop('allowEoo', False) + + if LOG: diff --git a/SOURCES/RHEL-157201-2-google-fix-bundled-pyasn1-CVE-2026-30922.patch b/SOURCES/RHEL-157201-2-google-fix-bundled-pyasn1-CVE-2026-30922.patch new file mode 100644 index 0000000..57fc83d --- /dev/null +++ b/SOURCES/RHEL-157201-2-google-fix-bundled-pyasn1-CVE-2026-30922.patch @@ -0,0 +1,40 @@ +From 25ad481c19fdb006e20485ef3fc2e5b3eff30ef0 Mon Sep 17 00:00:00 2001 +From: Simon Pichugin +Date: Mon, 16 Mar 2026 17:23:11 -0700 +Subject: [PATCH] Merge commit from fork + +--- + pyasn1/codec/ber/decoder.py | 10 +++ + tests/codec/ber/test_decoder.py | 116 ++++++++++++++++++++++++++++++++ + tests/codec/cer/test_decoder.py | 24 +++++++ + tests/codec/der/test_decoder.py | 42 ++++++++++++ + 4 files changed, 192 insertions(+) + +diff --git a/google/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py b/google/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py +index 50b14e98..2ea0be13 100644 +--- a/google/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py ++++ b/google/lib/python#PYTHON3_VERSION#/site-packages/pyasn1/codec/ber/decoder.py +@@ -36,6 +36,7 @@ + # Maximum number of continuation octets (high-bit set) allowed per OID arc. + # 20 octets allows up to 140-bit integers, supporting UUID-based OIDs + MAX_OID_ARC_CONTINUATION_OCTETS = 20 ++MAX_NESTING_DEPTH = 100 + + # Maximum number of bytes in a BER length field (8 bytes = up to 2^64-1) + MAX_LENGTH_OCTETS = 8 +@@ -1568,6 +1569,15 @@ def __call__(self, substrate, asn1Spec=None, + decodeFun=None, substrateFun=None, + **options): + ++ _nestingLevel = options.get('_nestingLevel', 0) ++ ++ if _nestingLevel > MAX_NESTING_DEPTH: ++ raise error.PyAsn1Error( ++ 'ASN.1 structure nesting depth exceeds limit (%d)' % MAX_NESTING_DEPTH ++ ) ++ ++ options['_nestingLevel'] = _nestingLevel + 1 ++ + allowEoo = options.pop('allowEoo', False) + + if LOG: diff --git a/SOURCES/RHEL-31488-RHEL-31485-RHEL-31483-fence_aliyun-update.patch b/SOURCES/RHEL-31488-RHEL-31485-RHEL-31483-fence_aliyun-update.patch index b9bb334..7a3039d 100644 --- a/SOURCES/RHEL-31488-RHEL-31485-RHEL-31483-fence_aliyun-update.patch +++ b/SOURCES/RHEL-31488-RHEL-31485-RHEL-31483-fence_aliyun-update.patch @@ -16,7 +16,7 @@ + try: - sys.path.insert(0, '/usr/lib/fence-agents/support/aliyun') + sys.path.insert(0, '/usr/lib/fence-agents/support/aliyun/lib/python#PYTHON3_VERSION#/site-packages') from aliyunsdkcore import client from aliyunsdkcore.auth.credentials import EcsRamRoleCredential + from aliyunsdkcore.profile import region_provider diff --git a/SOURCES/RHEL-43562-fix-bundled-urllib3-CVE-2024-37891.patch b/SOURCES/RHEL-43562-fix-bundled-urllib3-CVE-2024-37891.patch deleted file mode 100644 index 84eec46..0000000 --- a/SOURCES/RHEL-43562-fix-bundled-urllib3-CVE-2024-37891.patch +++ /dev/null @@ -1,64 +0,0 @@ -From accff72ecc2f6cf5a76d9570198a93ac7c90270e Mon Sep 17 00:00:00 2001 -From: Quentin Pradet -Date: Mon, 17 Jun 2024 11:09:06 +0400 -Subject: [PATCH] Merge pull request from GHSA-34jh-p97f-mpxf - -* Strip Proxy-Authorization header on redirects - -* Fix test_retry_default_remove_headers_on_redirect - -* Set release date ---- - CHANGES.rst | 5 +++++ - src/urllib3/util/retry.py | 4 +++- - test/test_retry.py | 6 ++++- - test/with_dummyserver/test_poolmanager.py | 27 ++++++++++++++++++++--- - 4 files changed, 37 insertions(+), 5 deletions(-) - -diff --git a/aws/urllib3/util/retry.py b/aws/urllib3/util/retry.py -index 7a76a4a6ad..0456cceba4 100644 ---- a/aws/urllib3/util/retry.py -+++ b/aws/urllib3/util/retry.py -@@ -189,7 +189,9 @@ class Retry: - RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - - #: Default headers to be used for ``remove_headers_on_redirect`` -- DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"]) -+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset( -+ ["Cookie", "Authorization", "Proxy-Authorization"] -+ ) - - #: Default maximum backoff time. - DEFAULT_BACKOFF_MAX = 120 - -diff --git a/azure/urllib3/util/retry.py b/azure/urllib3/util/retry.py -index 7a76a4a6ad..0456cceba4 100644 ---- a/azure/urllib3/util/retry.py -+++ b/azure/urllib3/util/retry.py -@@ -189,7 +189,9 @@ class Retry: - RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - - #: Default headers to be used for ``remove_headers_on_redirect`` -- DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"]) -+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset( -+ ["Cookie", "Authorization", "Proxy-Authorization"] -+ ) - - #: Default maximum backoff time. - DEFAULT_BACKOFF_MAX = 120 - -diff --git a/google/urllib3/util/retry.py b/google/urllib3/util/retry.py -index 7a76a4a6ad..0456cceba4 100644 ---- a/google/urllib3/util/retry.py -+++ b/google/urllib3/util/retry.py -@@ -189,7 +189,9 @@ class Retry: - RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - - #: Default headers to be used for ``remove_headers_on_redirect`` -- DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"]) -+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset( -+ ["Cookie", "Authorization", "Proxy-Authorization"] -+ ) - - #: Default maximum backoff time. - DEFAULT_BACKOFF_MAX = 120 diff --git a/SOURCES/RHEL-76493-fence_azure_arm-use-azure-identity.patch b/SOURCES/RHEL-76493-fence_azure_arm-use-azure-identity.patch index 081d1cd..ff2a12f 100644 --- a/SOURCES/RHEL-76493-fence_azure_arm-use-azure-identity.patch +++ b/SOURCES/RHEL-76493-fence_azure_arm-use-azure-identity.patch @@ -5,7 +5,7 @@ from fencing import fail_usage -import sys --sys.path.insert(0, '/usr/lib/fence-agents/support/azure') +-sys.path.insert(0, '/usr/lib/fence-agents/support/azure/lib/python#PYTHON3_VERSION#/site-packages') - FENCE_SUBNET_NAME = "fence-subnet" FENCE_INBOUND_RULE_NAME = "FENCE_DENY_ALL_INBOUND" @@ -403,8 +403,8 @@ @@ -2,6 +2,7 @@ import sys, re - sys.path.insert(0, '/usr/lib/fence-agents/support/common') -+sys.path.insert(1, '/usr/lib/fence-agents/support/azure') + sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') ++sys.path.insert(1, '/usr/lib/fence-agents/support/azure/lib/python#PYTHON3_VERSION#/site-packages') try: import pexpect except: diff --git a/SOURCES/RHEL-95901-pkg_resources-suppress-UserWarning.patch b/SOURCES/RHEL-95901-pkg_resources-suppress-UserWarning.patch deleted file mode 100644 index d1972fd..0000000 --- a/SOURCES/RHEL-95901-pkg_resources-suppress-UserWarning.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- a/google/pkg_resources/__init__.py 2025-06-12 09:41:54.535219946 +0000 -+++ b/google/pkg_resources/__init__.py 2025-06-12 09:42:07.508276281 +0000 -@@ -95,16 +95,6 @@ - from _typeshed.importlib import LoaderProtocol - from typing_extensions import Self, TypeAlias - --warnings.warn( -- "pkg_resources is deprecated as an API. " -- "See https://setuptools.pypa.io/en/latest/pkg_resources.html. " -- "The pkg_resources package is slated for removal as early as " -- "2025-11-30. Refrain from using this package or pin to " -- "Setuptools<81.", -- UserWarning, -- stacklevel=2, --) -- - _T = TypeVar("_T") - _DistributionT = TypeVar("_DistributionT", bound="Distribution") - # Type aliases ---- a/kubevirt/pkg_resources/__init__.py 2025-06-12 09:41:54.535219946 +0000 -+++ b/kubevirt/pkg_resources/__init__.py 2025-06-12 09:42:07.508276281 +0000 -@@ -95,16 +95,6 @@ - from _typeshed.importlib import LoaderProtocol - from typing_extensions import Self, TypeAlias - --warnings.warn( -- "pkg_resources is deprecated as an API. " -- "See https://setuptools.pypa.io/en/latest/pkg_resources.html. " -- "The pkg_resources package is slated for removal as early as " -- "2025-11-30. Refrain from using this package or pin to " -- "Setuptools<81.", -- UserWarning, -- stacklevel=2, --) -- - _T = TypeVar("_T") - _DistributionT = TypeVar("_DistributionT", bound="Distribution") - # Type aliases diff --git a/SOURCES/bundled-pexpect.patch b/SOURCES/bundled-pexpect.patch index 41f355d..4758fe4 100644 --- a/SOURCES/bundled-pexpect.patch +++ b/SOURCES/bundled-pexpect.patch @@ -6,7 +6,7 @@ diff --color -uNr a/agents/azure_arm/fence_azure_arm.py b/agents/azure_arm/fence -import sys, re, pexpect +import sys, re -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -22,7 +22,7 @@ diff --color -uNr a/agents/hpblade/fence_hpblade.py b/agents/hpblade/fence_hpbla import sys, re -import pexpect -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -39,7 +39,7 @@ diff --color -uNr a/agents/ilo/fence_ilo.py b/agents/ilo/fence_ilo.py -import sys, re, pexpect +import sys, re -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -56,7 +56,7 @@ diff --color -uNr a/agents/ldom/fence_ldom.py b/agents/ldom/fence_ldom.py -import sys, re, pexpect +import sys, re -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -72,11 +72,11 @@ diff --color -uNr a/agents/Makefile.am b/agents/Makefile.am $(eval INPUT=$(subst .delay-check,,$@)) FENCE_TEST_ARGS_CISCO_MDS=$$(printf '$(FENCE_TEST_ARGS)' | sed 's#port=1#port=fc1/1#'); \ - test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib /usr/bin/time -p \ -+ test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common /usr/bin/time -p \ ++ test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages /usr/bin/time -p \ sh -c "printf 'delay=10\n $$FENCE_TEST_ARGS_CISCO_MDS' | $(PYTHON) ./$(INPUT)" 2>&1 |\ awk -F"[. ]" -vOFS= '/real/ {print $$2,$$3}'` -ge 1000 || ( \ - PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib /usr/bin/time -p \ -+ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common /usr/bin/time -p \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages /usr/bin/time -p \ sh -c "printf "delay=0\n $$FENCE_TEST_ARGS_CISCO_MDS" | $(PYTHON) ./$(INPUT)"; false ) include $(top_srcdir)/make/fencebuild.mk @@ -88,7 +88,7 @@ diff --color -uNr a/agents/netio/fence_netio.py b/agents/netio/fence_netio.py -import sys, re, pexpect +import sys, re -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -104,7 +104,7 @@ diff --color -uNr a/agents/raritan/fence_raritan.py b/agents/raritan/fence_rarit -import sys, re, pexpect +import sys, re -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -121,7 +121,7 @@ diff --color -uNr a/agents/sanbox2/fence_sanbox2.py b/agents/sanbox2/fence_sanbo -import sys, re, pexpect +import sys, re -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -138,7 +138,7 @@ diff --color -uNr a/agents/vmware/fence_vmware.py b/agents/vmware/fence_vmware.p -import sys, re, pexpect +import sys, re -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -155,7 +155,7 @@ diff --color -uNr a/agents/wti/fence_wti.py b/agents/wti/fence_wti.py -import sys, re, pexpect +import sys, re -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -181,7 +181,7 @@ diff --color -uNr a/lib/fencing.py.py b/lib/fencing.py.py import sys, getopt, time, os, uuid, pycurl, stat -import pexpect, re, syslog -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -255,7 +255,7 @@ diff --color -uNr a/lib/fencing_snmp.py.py b/lib/fencing_snmp.py.py -import re, pexpect +import sys -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') +try: + import pexpect +except: @@ -272,10 +272,10 @@ diff --color -uNr a/make/agentpycheck.mk b/make/agentpycheck.mk %.xml-check: %.8 $(eval INPUT=$(subst .xml-check,,$(@F))) - for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ -+ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ TEMPFILE=$$(mktemp); \ - PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $$TEMPFILE && \ -+ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $$TEMPFILE && \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $$TEMPFILE && \ diff $$TEMPFILE $(DATADIR)/$$x.xml || exit 1 && \ rm $$TEMPFILE; \ done @@ -284,8 +284,8 @@ diff --color -uNr a/make/agentpycheck.mk b/make/agentpycheck.mk $(eval INPUT=$(subst .xml-upload,,$(@F))) - for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ - PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $(DATADIR)/$$x.xml; \ -+ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ -+ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $(DATADIR)/$$x.xml; \ ++ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(@D)/$$x -o metadata | $(AWK) $(AWK_VAL) > $(DATADIR)/$$x.xml; \ done # If test will fail, rerun fence agents to show problems @@ -293,12 +293,12 @@ diff --color -uNr a/make/agentpycheck.mk b/make/agentpycheck.mk $(eval INPUT=$(subst .delay-check,,$(@F))) - for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ - test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib /usr/bin/time -p \ -+ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ -+ test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common /usr/bin/time -p \ ++ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ test `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages /usr/bin/time -p \ sh -c "printf 'delay=10\n $(FENCE_TEST_ARGS)' | $(PYTHON) $(@D)/$$x" 2>&1 |\ awk -F"[. ]" -vOFS= '/real/ {print $$2,$$3}'` -ge 1000 || ( \ - PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib /usr/bin/time -p \ -+ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common /usr/bin/time -p \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages /usr/bin/time -p \ sh -c "printf 'delay=0\n $(FENCE_TEST_ARGS)' | $(PYTHON) $(@D)/$$x"; false ); \ done @@ -306,8 +306,8 @@ diff --color -uNr a/make/agentpycheck.mk b/make/agentpycheck.mk $(eval INPUT=$(subst .rng-check,,$(@F))) - for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ - PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@D)/$$x -o metadata | \ -+ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ -+ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@D)/$$x -o metadata | \ ++ for x in $(INPUT) `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(@D)/$(INPUT) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(@D)/$$x -o metadata | \ xsltproc ${abs_top_srcdir}/lib/fence2rng.xsl - | \ sed -e 's/ rha:description=/ description=/g' -e 's/ rha:name=/ name=/g' | \ xmllint --nsclean --noout -; \ @@ -319,11 +319,11 @@ diff --color -uNr a/make/fencebuild.mk b/make/fencebuild.mk if [ 0 -eq `echo "$(@)" | grep fence_ > /dev/null 2>&1; echo $$?` ]; then \ - PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(top_srcdir)/lib/check_used_options.py $@; \ -+ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(top_srcdir)/lib/check_used_options.py $@; \ ++ PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(top_srcdir)/lib/check_used_options.py $@; \ else true ; fi - for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $(@) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ -+for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $(@) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $(@) -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ cp -f $(@) $(@D)/$$x; \ $(MAKE) $(@D)/$$x.8; \ done @@ -332,7 +332,7 @@ diff --color -uNr a/make/fencebuild.mk b/make/fencebuild.mk for p in $(TARGET); do \ dir=`dirname $$p`; \ - for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ -+ for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ ++ for x in `PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"`; do \ echo " $(INSTALL_SCRIPT) $$dir/$$x '$(DESTDIR)$(sbindir)'"; \ $(INSTALL_SCRIPT) $$dir/$$x "$(DESTDIR)$(sbindir)" || exit $$?; \ echo " $(INSTALL_DATA) '$$dir/$$x.8' '$(DESTDIR)$(man8dir)'"; \ @@ -341,7 +341,7 @@ diff --color -uNr a/make/fencebuild.mk b/make/fencebuild.mk uninstall-hook: $(TARGET) files=`for p in $(TARGET); do \ - for x in \`PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"\`; do \ -+ for x in \`PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"\`; do \ ++ for x in \`PYTHONPATH=$(abs_top_srcdir)/lib:$(abs_top_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages $(PYTHON) $$p -o metadata | grep symlink | sed -e "s/.*\(fence.*\)\" .*/\1/g"\`; do \ echo " rm -f '$(DESTDIR)$(sbindir)/$$x'"; \ rm -f "$(DESTDIR)$(sbindir)/$$x"; \ echo " rm -f '$(DESTDIR)$(man8dir)/$$x.8'"; \ @@ -352,7 +352,7 @@ diff --color -uNr a/make/fenceman.mk b/make/fenceman.mk %.8: % $(top_srcdir)/lib/fence2man.xsl set -e && \ - PYTHONPATH=$(abs_srcdir)/lib:$(abs_builddir)/../lib:$(abs_builddir)/lib \ -+ PYTHONPATH=$(abs_srcdir)/lib:$(abs_builddir)/../lib:$(abs_builddir)/lib:$(abs_top_builddir)/support/common \ ++ PYTHONPATH=$(abs_srcdir)/lib:$(abs_builddir)/../lib:$(abs_builddir)/lib:$(abs_top_builddir)/support/common/lib/python#PYTHON3_VERSION#/site-packages \ $(PYTHON) $* -o manpage > $(@D)/.$(@F).tmp && \ xmllint --noout --relaxng $(top_srcdir)/lib/metadata.rng $(@D)/.$(@F).tmp && \ xsltproc $(top_srcdir)/lib/fence2man.xsl $(@D)/.$(@F).tmp > $@ diff --git a/SOURCES/bundled-suds.patch b/SOURCES/bundled-suds.patch index b8a6ba1..ff28d2e 100644 --- a/SOURCES/bundled-suds.patch +++ b/SOURCES/bundled-suds.patch @@ -4,7 +4,7 @@ #!@PYTHON@ -tt import sys -+sys.path.insert(0, '/usr/lib/fence-agents/support/common') ++sys.path.insert(0, '/usr/lib/fence-agents/support/common/lib/python#PYTHON3_VERSION#/site-packages') import shutil, tempfile, suds import logging, requests import atexit, signal diff --git a/SOURCES/bz2000954-2-fence_kubevirt.patch b/SOURCES/bz2000954-2-fence_kubevirt.patch index 44ac751..3e672cb 100644 --- a/SOURCES/bz2000954-2-fence_kubevirt.patch +++ b/SOURCES/bz2000954-2-fence_kubevirt.patch @@ -1,6 +1,6 @@ ---- fence-agents-4.10.0/agents/kubevirt/fence_kubevirt.py 2021-07-08 13:09:05.000000000 +0200 -+++ /home/oalbrigt/rhpkg/fence-agents-8.6/fence-agents-4.2.1/agents/kubevirt/fence_kubevirt.py 2021-11-02 15:35:46.217440426 +0100 -@@ -2,24 +2,25 @@ +--- a/agents/kubevirt/fence_kubevirt.py 2026-04-14 15:49:53.368718050 +0200 ++++ b/agents/kubevirt/fence_kubevirt.py 2026-04-14 15:51:18.996925630 +0200 +@@ -2,24 +2,26 @@ import sys import logging @@ -11,7 +11,8 @@ +from fencing import fail, fail_usage, run_delay, EC_STATUS, EC_FETCH_VM_UUID try: -+ sys.path.insert(0, '/usr/lib/fence-agents/support/kubevirt') ++ sys.path.insert(0, '/usr/lib/fence-agents/support/kubevirt/lib64/python#PYTHON3_VERSION#/site-packages') ++ sys.path.insert(1, '/usr/lib/fence-agents/support/kubevirt/lib/python#PYTHON3_VERSION#/site-packages') from kubernetes.client.exceptions import ApiException except ImportError: logging.error("Couldn\'t import kubernetes.client.exceptions.ApiException - not found or not accessible") @@ -30,7 +31,7 @@ vm_list = vm_api.get(namespace=namespace) for vm in vm_list.items: result[vm.metadata.name] = ("", None) -@@ -30,18 +31,21 @@ +@@ -30,18 +32,21 @@ def get_power_status(conn, options): logging.debug("Starting get status operation") try: @@ -58,7 +59,7 @@ return "off" logging.error("Failed to get power status, with API Exception: %s", e) fail(EC_STATUS) -@@ -49,38 +53,53 @@ +@@ -49,38 +54,53 @@ logging.error("Failed to get power status, with Exception: %s", e) fail(EC_STATUS) @@ -131,7 +132,7 @@ return conn.request('put', path, header_params={'accept': '*/*'}) def validate_options(required_options_list, options): -@@ -92,8 +111,13 @@ +@@ -92,8 +112,13 @@ def main(): conn = None @@ -146,7 +147,7 @@ options = check_input(device_opt, process_input(device_opt)) docs = {} -@@ -106,6 +130,11 @@ +@@ -106,6 +131,11 @@ validate_options(['--namespace'], options) diff --git a/SOURCES/bz2079889-fence_gce-update.patch b/SOURCES/bz2079889-fence_gce-update.patch index 97e5193..2a3b142 100644 --- a/SOURCES/bz2079889-fence_gce-update.patch +++ b/SOURCES/bz2079889-fence_gce-update.patch @@ -22,8 +22,8 @@ -from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action +from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action, run_command try: - sys.path.insert(0, '/usr/lib/fence-agents/support/google') - import httplib2 + sys.path.insert(0, '/usr/lib/fence-agents/support/google/lib64/python#PYTHON3_VERSION#/site-packages') + sys.path.insert(1, '/usr/lib/fence-agents/support/google/lib/python#PYTHON3_VERSION#/site-packages') @@ -42,6 +42,19 @@ METADATA_SERVER = 'http://metadata.google.internal/computeMetadata/v1/' diff --git a/SOURCES/bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch b/SOURCES/bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch index 97707a5..8092dca 100644 --- a/SOURCES/bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch +++ b/SOURCES/bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch @@ -1,5 +1,5 @@ ---- a/kubevirt/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 -+++ b/kubevirt/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 +--- a/kubevirt/lib/python#PYTHON3_VERSION#/site-packages/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 ++++ b/kubevirt/lib/python#PYTHON3_VERSION#/site-packages/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 @@ -21,7 +21,12 @@ try: with TarFile.open(filename) as tf: diff --git a/SOURCES/bz2217902-2-aws-azure-fix-bundled-dateutil-CVE-2007-4559.patch b/SOURCES/bz2217902-2-aws-azure-fix-bundled-dateutil-CVE-2007-4559.patch index c829991..a6324d2 100644 --- a/SOURCES/bz2217902-2-aws-azure-fix-bundled-dateutil-CVE-2007-4559.patch +++ b/SOURCES/bz2217902-2-aws-azure-fix-bundled-dateutil-CVE-2007-4559.patch @@ -1,5 +1,5 @@ ---- a/aws/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 -+++ b/aws/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 +--- a/aws/lib/python#PYTHON3_VERSION#/site-packages/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 ++++ b/aws/lib/python#PYTHON3_VERSION#/site-packages/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 @@ -21,7 +21,12 @@ try: with TarFile.open(filename) as tf: @@ -15,8 +15,8 @@ _run_zic(zonedir, filepaths) ---- a/azure/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 -+++ b/azure/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 +--- a/azure/lib/python#PYTHON3_VERSION#/site-packages/dateutil/zoneinfo/rebuild.py 2023-01-26 16:29:30.000000000 +0100 ++++ b/azure/lib/python#PYTHON3_VERSION#/site-packages/dateutil/zoneinfo/rebuild.py 2023-07-19 10:12:42.277559948 +0200 @@ -21,7 +21,12 @@ try: with TarFile.open(filename) as tf: diff --git a/SOURCES/ha-cloud-support-aliyun.patch b/SOURCES/ha-cloud-support-aliyun.patch index 5f310f1..591f217 100644 --- a/SOURCES/ha-cloud-support-aliyun.patch +++ b/SOURCES/ha-cloud-support-aliyun.patch @@ -4,7 +4,7 @@ from fencing import fail, fail_usage, EC_TIMED_OUT, run_delay try: -+ sys.path.insert(0, '/usr/lib/fence-agents/support/aliyun') ++ sys.path.insert(0, '/usr/lib/fence-agents/support/aliyun/lib/python#PYTHON3_VERSION#/site-packages') from aliyunsdkcore import client from aliyunsdkcore.auth.credentials import EcsRamRoleCredential from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest diff --git a/SOURCES/ha-cloud-support-aws.patch b/SOURCES/ha-cloud-support-aws.patch index f4939dd..39f7353 100644 --- a/SOURCES/ha-cloud-support-aws.patch +++ b/SOURCES/ha-cloud-support-aws.patch @@ -4,7 +4,7 @@ from requests import HTTPError try: -+ sys.path.insert(0, '/usr/lib/fence-agents/support/aws') ++ sys.path.insert(0, '/usr/lib/fence-agents/support/aws/lib/python#PYTHON3_VERSION#/site-packages') import boto3 from botocore.exceptions import ConnectionError, ClientError, EndpointConnectionError, NoRegionError except ImportError: diff --git a/SOURCES/ha-cloud-support-azure.patch b/SOURCES/ha-cloud-support-azure.patch index f8290f5..569b543 100644 --- a/SOURCES/ha-cloud-support-azure.patch +++ b/SOURCES/ha-cloud-support-azure.patch @@ -5,7 +5,7 @@ from fencing import fail_usage +import sys -+sys.path.insert(0, '/usr/lib/fence-agents/support/azure') ++sys.path.insert(0, '/usr/lib/fence-agents/support/azure/lib/python#PYTHON3_VERSION#/site-packages') + FENCE_SUBNET_NAME = "fence-subnet" FENCE_INBOUND_RULE_NAME = "FENCE_DENY_ALL_INBOUND" diff --git a/SOURCES/ha-cloud-support-google.patch b/SOURCES/ha-cloud-support-google.patch index 5335073..58e2c71 100644 --- a/SOURCES/ha-cloud-support-google.patch +++ b/SOURCES/ha-cloud-support-google.patch @@ -1,6 +1,5 @@ -diff --color -uNr a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py ---- a/agents/gce/fence_gce.py 2021-06-03 13:10:44.752999470 +0200 -+++ b/agents/gce/fence_gce.py 2021-06-03 13:10:36.512971619 +0200 +--- a/agents/gce/fence_gce.py 2026-04-15 10:38:15.742597179 +0200 ++++ b/agents/gce/fence_gce.py 2026-04-15 10:40:20.021924656 +0200 @@ -9,7 +9,6 @@ # @@ -9,13 +8,13 @@ diff --color -uNr a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py import logging import json import re -@@ -30,6 +29,8 @@ +@@ -30,6 +29,9 @@ from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action try: -+ sys.path.insert(0, '/usr/lib/fence-agents/support/google') ++ sys.path.insert(0, '/usr/lib/fence-agents/support/google/lib64/python#PYTHON3_VERSION#/site-packages') ++ sys.path.insert(1, '/usr/lib/fence-agents/support/google/lib/python#PYTHON3_VERSION#/site-packages') + import httplib2 import googleapiclient.discovery import socks try: -Binary files a/agents/gce/.fence_gce.py.swp and b/agents/gce/.fence_gce.py.swp differ diff --git a/SOURCES/requirements-google.txt b/SOURCES/requirements-google.txt index 4ef59ba..6fbd87f 100644 --- a/SOURCES/requirements-google.txt +++ b/SOURCES/requirements-google.txt @@ -1,4 +1,4 @@ google-api-python-client==1.12.8 -chardet<4.0 +chardet # for gcp-vpc-move-route pyroute2 diff --git a/SPECS/fence-agents.spec b/SPECS/fence-agents.spec index 4ad6933..0b16710 100644 --- a/SPECS/fence-agents.spec +++ b/SPECS/fence-agents.spec @@ -23,32 +23,22 @@ %global googleauth_version 2.3.0 %global cachetools cachetools %global cachetools_version 4.2.4 -%global pyasn1modules pyasn1-modules -%global pyasn1modules_version 0.2.8 %global pyasn1 pyasn1 %global pyasn1_version 0.4.8 +%global pyasn1modules pyasn1-modules +%global pyasn1modules_version 0.2.8 %global dateutil dateutil %global dateutil_version 2.8.1 %global pyyaml PyYAML %global pyyaml_version 5.1 -%global six six -%global six_version 1.16.0 -%global urllib3 urllib3 -%global urllib3_version 1.26.18 -%global websocketclient websocket-client -%global websocketclient_version 1.2.1 +%global websocketclient websocket_client +%global websocketclient_version 1.9.0 %global jinja2 jinja2 %global jinja2_version 3.1.6 %global markupsafe MarkupSafe %global markupsafe_version 2.0.1 %global stringutils string-utils %global stringutils_version 1.0.0 -%global requests requests -%global requests_version 2.26.0 -%global chrstnormalizer charset-normalizer -%global chrstnormalizer_version 2.0.7 -%global idna idna -%global idna_version 3.3 %global reqstsoauthlib requests-oauthlib %global reqstsoauthlib_version 1.3.0 %global ruamelyaml ruamel.yaml @@ -57,7 +47,7 @@ Name: fence-agents Summary: Set of unified programs capable of host isolation ("fencing") Version: 4.10.0 -Release: 98%{?alphatag:.%{alphatag}}%{?dist}.10 +Release: 98%{?alphatag:.%{alphatag}}%{?dist}.13 License: GPLv2+ and LGPLv2+ URL: https://github.com/ClusterLabs/fence-agents Source0: https://fedorahosted.org/releases/f/e/fence-agents/%{name}-%{version}.tar.gz @@ -69,117 +59,87 @@ Source103: requirements-azure.txt Source104: requirements-google.txt Source105: requirements-ibm.txt ### HA support libs/utils ### -# update with ./update-ha-support.sh and replace lines below with output -### BEGIN ### # aliyun -Source1000: aliyun-python-sdk-core-2.11.5.tar.gz -Source1001: aliyun_python_sdk_ecs-4.24.7-py2.py3-none-any.whl -Source1002: cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl -Source1003: colorama-0.3.3.tar.gz -Source1004: jmespath-0.7.1-py2.py3-none-any.whl -Source1005: pycryptodome-3.20.0.tar.gz -Source1006: pycparser-2.20-py2.py3-none-any.whl +# common (pexpect / suds) +Source1000: pexpect-4.8.0-py2.py3-none-any.whl +Source1001: ptyprocess-0.7.0-py2.py3-none-any.whl +Source1002: suds_community-0.8.5-py3-none-any.whl +Source1100: aliyun-python-sdk-core-2.16.0.tar.gz +Source1101: aliyun-python-sdk-ecs-4.24.82.tar.gz +Source1102: colorama-0.3.3.tar.gz +Source1103: jmespath-0.10.0.tar.gz # aliyun-cli -Source2000: aliyun-cli-3.0.198.tar.gz +Source1200: aliyun-cli-3.0.198.tar.gz ## TAG=$(git log --pretty="format:%h" -n 1) ## distdir="aliyun-openapi-meta-${TAG}" ## TARFILE="${distdir}.tar.gz" ## rm -rf $TARFILE $distdir ## git archive --prefix=$distdir/ HEAD | gzip > $TARFILE -Source2001: aliyun-openapi-meta-5cf98b660.tar.gz +Source1201: aliyun-openapi-meta-5cf98b660.tar.gz ## go mod vendor -Source2002: aliyun-cli-go-vendor.tar.gz +Source1202: aliyun-cli-go-vendor.tar.gz # aws -Source1007: boto3-1.40.13.tar.gz -Source1008: botocore-1.40.13.tar.gz -Source1009: python_%{dateutil}-%{dateutil_version}-py2.py3-none-any.whl -Source1010: s3transfer-0.13.1.tar.gz -Source1011: %{urllib3}-%{urllib3_version}.tar.gz +Source1300: boto3-1.40.13.tar.gz +Source1301: botocore-1.40.13.tar.gz +Source1302: python_%{dateutil}-%{dateutil_version}-py2.py3-none-any.whl +Source1303: s3transfer-0.13.1.tar.gz # azure -Source1012: adal-1.2.7.tar.gz -Source1013: azure-common-1.1.28.zip -Source1014: azure_core-1.32.0.tar.gz -Source1015: azure_mgmt_compute-34.0.0.tar.gz -Source1016: azure_mgmt_core-1.5.0.tar.gz -Source1017: azure_mgmt_network-28.1.0.tar.gz -Source1018: azure_identity-1.19.0.tar.gz -Source1019: chardet-4.0.0-py2.py3-none-any.whl -Source1020: isodate-0.6.1.tar.gz -Source1021: msrest-0.7.1.zip -Source1022: msrestazure-0.6.4.post1.tar.gz -Source1023: %{oauthlib}-%{oauthlib_version}.tar.gz -Source1024: PyJWT-2.1.0-py3-none-any.whl -Source1025: requests_oauthlib-1.3.0-py2.py3-none-any.whl -Source1026: msal-1.31.1.tar.gz -Source1027: msal_extensions-1.2.0.tar.gz -Source1028: portalocker-2.5.1.tar.gz -Source1029: cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl -Source1030: typing_extensions-4.12.2.tar.gz +Source1400: adal-1.2.7.tar.gz +Source1401: azure-common-1.1.28.zip +Source1402: azure_core-1.32.0.tar.gz +Source1403: azure_mgmt_core-1.5.0.tar.gz +Source1404: azure_mgmt_compute-34.0.0.tar.gz +Source1405: azure_mgmt_network-28.1.0.tar.gz +Source1406: azure_identity-1.25.3.tar.gz +Source1407: isodate-0.6.1.tar.gz +Source1408: msrest-0.7.1.zip +Source1409: msrestazure-0.6.4.post1.tar.gz +Source1410: %{oauthlib}-%{oauthlib_version}.tar.gz +Source1411: pyjwt-2.12.1.tar.gz +Source1412: requests_oauthlib-1.3.0-py2.py3-none-any.whl +Source1413: msal-1.36.0.tar.gz +Source1414: msal_extensions-1.3.1.tar.gz +Source1415: portalocker-2.5.1.tar.gz +Source1416: typing_extensions-4.12.2.tar.gz # google -Source1031: cachetools-4.2.2-py3-none-any.whl -Source1032: chardet-3.0.4-py2.py3-none-any.whl -Source1033: google_api_core-1.30.0-py2.py3-none-any.whl -Source1034: google_api_python_client-1.12.8-py2.py3-none-any.whl -Source1035: googleapis_common_protos-1.53.0-py2.py3-none-any.whl -Source1036: google_auth-1.32.0-py2.py3-none-any.whl -Source1037: google_auth_httplib2-0.1.0-py2.py3-none-any.whl -Source1038: httplib2-0.19.1-py3-none-any.whl -Source1039: packaging-20.9-py2.py3-none-any.whl -Source1040: protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl -Source1041: pyasn1-0.4.8-py2.py3-none-any.whl -Source1042: pyasn1_modules-0.2.8-py2.py3-none-any.whl -Source1043: pyparsing-2.4.7-py2.py3-none-any.whl -Source1044: pyroute2-0.7.12.tar.gz -Source1045: pyroute2.core-0.6.13.tar.gz -Source1046: pyroute2.ethtool-0.6.13.tar.gz -Source1047: pyroute2.ipdb-0.6.13.tar.gz -Source1048: pyroute2.ipset-0.6.13.tar.gz -Source1049: pyroute2.ndb-0.6.13.tar.gz -Source1050: pyroute2.nftables-0.6.13.tar.gz -Source1051: pyroute2.nslink-0.6.13.tar.gz -Source1052: pytz-2021.1-py2.py3-none-any.whl -Source1053: rsa-4.7.2-py3-none-any.whl -Source1054: setuptools-80.9.0.tar.gz -Source1055: uritemplate-3.0.1-py2.py3-none-any.whl -# common (pexpect / suds) -Source1056: pexpect-4.8.0-py2.py3-none-any.whl -Source1057: ptyprocess-0.7.0-py2.py3-none-any.whl -Source1058: suds_community-0.8.5-py3-none-any.whl -### END ### +Source1500: %{cachetools}-%{cachetools_version}.tar.gz +Source1501: google_api_core-1.30.0-py2.py3-none-any.whl +Source1502: google_api_python_client-1.12.8-py2.py3-none-any.whl +Source1503: googleapis_common_protos-1.53.0-py2.py3-none-any.whl +Source1504: google_auth-1.32.0-py2.py3-none-any.whl +Source1505: google_auth_httplib2-0.1.0-py2.py3-none-any.whl +Source1506: httplib2-0.19.1-py3-none-any.whl +Source1507: protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl +Source1508: pyroute2-0.7.12.tar.gz +Source1509: pytz-2021.1-py2.py3-none-any.whl +Source1510: rsa-4.7.2-py3-none-any.whl +Source1511: uritemplate-3.0.1-py2.py3-none-any.whl # kubevirt ## pip download --no-binary :all: openshift "ruamel.yaml.clib>=0.1.2" -### BEGIN -Source1060: %{openshift}-%{openshift_version}.tar.gz -Source1061: %{ruamelyamlclib}-%{ruamelyamlclib_version}.tar.gz -Source1062: %{kubernetes}-%{kubernetes_version}.tar.gz -Source1063: %{certifi}-%{certifi_version}.tar.gz -Source1064: %{googleauth}-%{googleauth_version}.tar.gz -Source1065: %{cachetools}-%{cachetools_version}.tar.gz -Source1066: %{pyasn1modules}-%{pyasn1modules_version}.tar.gz -Source1067: %{pyasn1}-%{pyasn1_version}.tar.gz -Source1068: %{pyyaml}-%{pyyaml_version}.tar.gz +Source1600: %{openshift}-%{openshift_version}.tar.gz +Source1601: %{ruamelyamlclib}-%{ruamelyamlclib_version}.tar.gz +Source1602: %{kubernetes}-%{kubernetes_version}.tar.gz +Source1603: %{certifi}-%{certifi_version}.tar.gz +Source1604: %{googleauth}-%{googleauth_version}.tar.gz +Source1605: %{pyasn1}-%{pyasn1_version}.tar.gz +Source1606: %{pyasn1modules}-%{pyasn1modules_version}.tar.gz +Source1607: %{pyyaml}-%{pyyaml_version}.tar.gz ## rsa is dependency for "pip install", ## but gets removed to use cryptography lib instead -Source1069: rsa-4.7.2.tar.gz -Source1070: %{six}-%{six_version}.tar.gz -Source1071: %{websocketclient}-%{websocketclient_version}.tar.gz -Source1072: %{jinja2}-%{jinja2_version}.tar.gz -Source1073: %{markupsafe}-%{markupsafe_version}.tar.gz -Source1074: python-%{stringutils}-%{stringutils_version}.tar.gz -Source1075: %{requests}-%{requests_version}.tar.gz -Source1076: %{chrstnormalizer}-%{chrstnormalizer_version}.tar.gz -Source1077: %{idna}-%{idna_version}.tar.gz -Source1078: %{reqstsoauthlib}-%{reqstsoauthlib_version}.tar.gz -Source1079: %{ruamelyaml}-%{ruamelyaml_version}.tar.gz +Source1608: %{websocketclient}-%{websocketclient_version}.tar.gz +Source1609: %{jinja2}-%{jinja2_version}.tar.gz +Source1610: %{markupsafe}-%{markupsafe_version}.tar.gz +Source1611: python-%{stringutils}-%{stringutils_version}.tar.gz +Source1612: %{reqstsoauthlib}-%{reqstsoauthlib_version}.tar.gz +Source1613: %{ruamelyaml}-%{ruamelyaml_version}.tar.gz ## required for installation -Source1080: setuptools_scm-8.1.0.tar.gz -Source1081: packaging-21.2-py3-none-any.whl -Source1082: poetry-core-1.0.7.tar.gz -Source1083: pyparsing-3.0.1.tar.gz -Source1084: tomli-2.0.1.tar.gz -Source1085: flit_core-3.9.0.tar.gz -Source1086: wheel-0.37.0-py2.py3-none-any.whl -### END +Source1900: setuptools_scm-8.1.0.tar.gz +Source1901: packaging-26.0.tar.gz +Source1902: tomli-2.0.1.tar.gz +Source1903: flit_core-3.12.0.tar.gz +Source1904: pip-26.0.1.tar.gz +Source1905: setuptools-82.0.1.tar.gz +Source1906: wheel-0.46.3.tar.gz Patch0: ha-cloud-support-aliyun.patch Patch1: ha-cloud-support-aws.patch @@ -259,24 +219,12 @@ Patch73: RHEL-145761-fence_ibm_vpc-fix-missing-statuses.patch ### HA support libs/utils ### # all archs Patch1000: bz2217902-1-kubevirt-fix-bundled-dateutil-CVE-2007-4559.patch -Patch1001: RHEL-146351-kubevirt-1-fix-bundled-urllib3-CVE-2024-37891.patch -Patch1002: RHEL-146351-kubevirt-2-fix-bundled-urllib3-CVE-2025-66418.patch -Patch1003: RHEL-146351-kubevirt-3-fix-bundled-urllib3-CVE-2025-66471.patch -Patch1004: RHEL-146351-kubevirt-4-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch -Patch1005: RHEL-146351-kubevirt-5-fix-bundled-pyasn1-CVE-2026-23490.patch +Patch1001: RHEL-146351-kubevirt-fix-bundled-pyasn1-CVE-2026-23490.patch +Patch1002: RHEL-157201-1-kubevirt-fix-bundled-pyasn1-CVE-2026-30922.patch # cloud (x86_64 only) Patch2000: bz2217902-2-aws-azure-fix-bundled-dateutil-CVE-2007-4559.patch -Patch2001: RHEL-43562-fix-bundled-urllib3-CVE-2024-37891.patch -Patch2002: RHEL-95901-pkg_resources-suppress-UserWarning.patch -Patch2003: RHEL-136061-fix-bundled-urllib3-CVE-2025-66418.patch -Patch2004: RHEL-139793-fix-bundled-urllib3-CVE-2025-66471.patch -Patch2005: RHEL-140795-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch -Patch2006: RHEL-142459-fix-bundled-pyasn1-CVE-2026-23490.patch -# cloud (ppc64le only) -Patch3000: RHEL-146351-ibm-1-fix-bundled-urllib3-CVE-2024-37891.patch -Patch3001: RHEL-146351-ibm-2-fix-bundled-urllib3-CVE-2025-66418.patch -Patch3002: RHEL-146351-ibm-3-fix-bundled-urllib3-CVE-2025-66471.patch -Patch3003: RHEL-146351-ibm-4-RHEL-146294-fix-bundled-urllib3-CVE-2026-21441.patch +Patch2001: RHEL-142459-fix-bundled-pyasn1-CVE-2026-23490.patch +Patch2002: RHEL-157201-2-google-fix-bundled-pyasn1-CVE-2026-30922.patch %global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate hpblade ibmblade ibm_powervs ibm_vpc ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan kdump kubevirt lpar mpath nutanix_ahv redfish rhevm rsa rsb sbd scsi vmware_rest vmware_soap wti %ifarch x86_64 @@ -347,7 +295,7 @@ BuildRequires: gcc BuildRequires: libxslt ## Python dependencies %if 0%{?fedora} || 0%{?centos} > 7 || 0%{?rhel} > 7 || 0%{?suse_version} -BuildRequires: python3-devel +BuildRequires: python3-devel python3-cryptography # dependencies for building HA support subpackages BuildRequires: python3-pip python3-wheel %ifarch x86_64 @@ -475,12 +423,12 @@ sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac # aliyun-cli %ifarch x86_64 -tar zxf %SOURCE2000 +tar zxf %SOURCE1200 pushd aliyun-cli-* git init rmdir aliyun-openapi-meta -tar zxf %SOURCE2001 -tar zxf %SOURCE2002 +tar zxf %SOURCE1201 +tar zxf %SOURCE1202 mv aliyun-openapi-meta-* aliyun-openapi-meta %define aliyun_cli_version 3.0.198 # based on https://github.com/containers/podman/blob/main/rpm/podman.spec @@ -492,6 +440,9 @@ popd %endif # support libs +%{__python3} -m pip install --no-build-isolation --user --upgrade --no-index --find-links %{_sourcedir} flit-core +%{__python3} -m pip install --no-build-isolation --user --upgrade --no-index --find-links %{_sourcedir} packaging +%{__python3} -m pip install --no-build-isolation --user --upgrade --no-index --find-links %{_sourcedir} pip setuptools wheel %ifarch x86_64 LIBS="%{_sourcedir}/requirements-*.txt" %endif @@ -503,47 +454,42 @@ LIBS="%{_sourcedir}/requirements-common.txt" %endif for x in $LIBS; do [ "%{_arch}" = "x86_64" ] && [ "$x" = "%{_sourcedir}/requirements-ibm.txt" ] && continue - %{__python3} -m pip install --target support/$(echo $x | sed -E "s/.*requirements-(.*).txt/\1/") --no-index --find-links %{_sourcedir} -r $x + # use --prefix "usr" due to default varying per arch (and "" uses default unlike on RHEL10+) + %{__python3} -m pip install --no-build-isolation --use-deprecated=legacy-resolver --prefix "usr" --root support/$(echo $x | sed -E "s/.*requirements-(.*).txt/\1/") --no-index --find-links %{_sourcedir} -r $x done -# fix incorrect #! detected by CI -%ifarch x86_64 -sed -i -e "/^#\!\/Users/c#\!%{__python3}" support/aws/bin/jp -%endif - # kubevirt -%{__python3} -m pip install --user --no-index --find-links %{_sourcedir} setuptools-scm -%{__python3} -m pip install --target support/kubevirt --no-index --find-links %{_sourcedir} openshift +%{__python3} -m pip install --no-build-isolation --user --no-index --find-links %{_sourcedir} tomli +%{__python3} -m pip install --no-build-isolation --user --no-index --find-links %{_sourcedir} setuptools-scm +# use --prefix "usr" due to default varying per arch (and "" uses default unlike on RHEL10+) +%{__python3} -m pip install --no-build-isolation --prefix "usr" --root support/kubevirt --no-index --find-links %{_sourcedir} openshift rm -rf kubevirt/rsa* +# workaround due to --prefix and jmespath bugs mentioned above +for d in support/*; do + mv "$d/usr/lib" "$d" + [ -d "$d/usr/lib64" ] && mv "$d/usr/lib64" "$d" + rm -rfv "$d/usr" +done + +sed -i -e "s/#PYTHON3_VERSION#/%{python3_version}/" %{_sourcedir}/*.patch make/*.mk lib/*.py agents/*/*.py + # regular patch doesnt work in build-section pushd support /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH1000} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH1001} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH1002} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH1003} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH1004} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH1005} +/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH1001} +/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH1002} %ifarch x86_64 /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH2000} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH2001} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH2002} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH2003} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH2004} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH2005} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH2006} -%endif -%ifarch ppc64le -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH3000} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH3001} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH3002} -/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH3003} +/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH2001} +/usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=2 < %{PATCH2002} %endif popd +export PYTHONPATH="support/common/lib/python%{python3_version}/site-packages:support/aliyun/lib/python%{python3_version}/site-packages:support/aws/lib/python%{python3_version}/site-packages:support/azure/lib/python%{python3_version}/site-packages:support/google/lib/python%{python3_version}/site-packages:support/kubevirt/lib/python%{python3_version}/site-packages" ./autogen.sh -%{configure} --disable-libvirt-qmf-plugin PYTHONPATH="support/aliyun:support/aws:support/azure:support/google:support/common" \ +%{configure} --disable-libvirt-qmf-plugin \ %if %{defined _tmpfilesdir} SYSTEMD_TMPFILES_DIR=%{_tmpfilesdir} \ --with-fencetmpdir=/run/fence-agents \ @@ -559,7 +505,7 @@ rm -rf %{buildroot} mkdir -p %{buildroot}%{_usr}/lib/%{name} mv support %{buildroot}%{_usr}/lib/%{name} -export PYTHONPATH=%{buildroot}%{_usr}/lib/%{name}/support +export PYTHONPATH="%{buildroot}%{_usr}/lib/%{name}/support/common/lib/python%{python3_version}/site-packages:%{buildroot}%{_usr}/lib/%{name}/support/aliyun/lib/python%{python3_version}/site-packages:%{buildroot}%{_usr}/lib/%{name}/support/aws/lib/python%{python3_version}/site-packages:%{buildroot}%{_usr}/lib/%{name}/support/azure/lib/python%{python3_version}/site-packages:%{buildroot}%{_usr}/lib/%{name}/support/google/lib/python%{python3_version}/site-packages:%{buildroot}%{_usr}/lib/%{name}/support/kubevirt/lib/python%{python3_version}/site-packages" make install DESTDIR=%{buildroot} mkdir -p %{buildroot}/%{_unitdir}/ %ifarch x86_64 @@ -664,95 +610,67 @@ This package contains support files including the Python fencing library. %package -n ha-cloud-support License: GPL-2.0-or-later AND LGPL-2.0-or-later AND LGPL-2.1-or-later AND Apache-2.0 AND MIT AND BSD-2-Clause AND BSD-3-Clause AND MPL-2.0 AND Apache-2.0 AND PSF-2.0 AND Unlicense AND ISC Summary: Support libraries for HA Cloud agents +Requires: python3-cryptography python3-requests python3-urllib3 %ifarch x86_64 Requires: awscli2 # aliyun -Provides: bundled(python-aliyun-python-sdk-core) = 2.11.5 -Provides: bundled(python-aliyun-python-sdk-ecs) = 4.24.7 -Provides: bundled(python-cffi) = 1.14.5 -Provides: bundled(python-colorama) = 0.3.3 -Provides: bundled(python-jmespath) = 0.7.1 -Provides: bundled(python-pycryptodome) = 3.20.0 -Provides: bundled(python-pycparser) = 2.20 +Provides: bundled(python-aliyun-sdk-core) = 2.16.0 +Provides: bundled(python-aliyun-sdk-ecs) = 4.24.82 +Provides: bundled(python-jmespath) = 0.10.0 +# aliyuncli (golang) Provides: bundled(aliyun-cli) = 3.0.198 Provides: bundled(aliyun-openapi-meta) = 5cf98b660 # aws Provides: bundled(python-boto3) = 1.40.13 Provides: bundled(python-botocore) = 1.40.13 Provides: bundled(python-%{dateutil}) = %{dateutil_version} +Provides: bundled(python-jmespath) = 0.10.0 Provides: bundled(python-s3transfer) = 0.13.1 -Provides: bundled(python-urllib3) = 1.26.18 # azure Provides: bundled(python-adal) = 1.2.7 Provides: bundled(python-azure-common) = 1.1.28 Provides: bundled(python-azure-core) = 1.32.0 -Provides: bundled(python-azure-identity) = 1.19.0 -Provides: bundled(python-azure-mgmt-compute) = 34.0.0 +Provides: bundled(python-azure-identity) = 1.25.3 Provides: bundled(python-azure-mgmt-core) = 1.5.0 +Provides: bundled(python-azure-mgmt-compute) = 34.0.0 Provides: bundled(python-azure-mgmt-network) = 28.1.0 -Provides: bundled(python-chardet) = 4.0.0 -Provides: bundled(python-cffi) = 1.14.5 -Provides: bundled(python-%{chrstnormalizer}) = %{chrstnormalizer_version} -Provides: bundled(python-cryptography) = 3.3.2 Provides: bundled(python-%{dateutil}) = %{dateutil_version} -Provides: bundled(python-%{idna}) = %{idna_version} Provides: bundled(python-isodate) = 0.6.1 -Provides: bundled(python-msal) = 1.31.1 -Provides: bundled(python-msal-extensions) = 1.2.0 +Provides: bundled(python-msal) = 1.36.0 +Provides: bundled(python-msal-extensions) = 1.3.1 Provides: bundled(python-msrest) = 0.7.1 Provides: bundled(python-msrestazure) = 0.6.4.post1 Provides: bundled(python-%{oauthlib}) = %{oauthlib_version} Provides: bundled(python-portalocker) = 2.5.1 -Provides: bundled(python-pycparser) = 2.20 -Provides: bundled(python-PyJWT) = 2.1.0 -Provides: bundled(python-%{requests}) = %{requests_version} +Provides: bundled(python-PyJWT) = 2.12.1 Provides: bundled(python-requests-oauthlib) = 1.3.0 -Provides: bundled(python-%{six}) = %{six_version} Provides: bundled(python-typing-extensions) = 4.12.2 -Provides: bundled(python-%{urllib3}) = %{urllib3_version} # google -Provides: bundled(python-cachetools) = 4.2.2 -Provides: bundled(python-chardet) = 3.0.4 +Provides: bundled(python3-%{cachetools}) = %{cachetools_version} Provides: bundled(python-google-api-core) = 1.30.0 Provides: bundled(python-google-api-client) = 1.12.8 Provides: bundled(python-googleapis-common-protos) = 1.53.0 Provides: bundled(python-google-auth) = 1.32.0 Provides: bundled(python-google-auth-httplib2) = 0.1.0 Provides: bundled(python-httplib2) = 0.19.1 -Provides: bundled(python-packaging) = 20.9 Provides: bundled(python-protobuf) = 3.17.3 -Provides: bundled(python-pyasn1) = 0.4.8 -Provides: bundled(python-pyasn1-modules) = 0.2.8 -Provides: bundled(python-pyparsing) = 2.4.7 +Provides: bundled(python3-%{pyasn1}) = %{pyasn1_version} +Provides: bundled(python3-%{pyasn1modules}) = %{pyasn1modules_version} Provides: bundled(python-pyroute2) = 0.7.12 -Provides: bundled(python-pyroute2-core) = 0.6.13 -Provides: bundled(python-pyroute2-ethtool) = 0.6.13 -Provides: bundled(python-pyroute2-ipdb) = 0.6.13 -Provides: bundled(python-pyroute2-ipset) = 0.6.13 -Provides: bundled(python-pyroute2-ndb) = 0.6.13 -Provides: bundled(python-pyroute2-nftables) = 0.6.13 -Provides: bundled(python-pyroute2-nslink) = 0.6.13 Provides: bundled(python-pytz) = 2021.1 Provides: bundled(python-rsa) = 4.7.2 -Provides: bundled(python3-setuptools) = 80.9.0 Provides: bundled(python-uritemplate) = 3.0.1 %endif -%ifarch ppc64le -# ibm -Provides: bundled(python3-%{certifi}) = %{certifi_version} -Provides: bundled(python3-%{chrstnormalizer}) = %{chrstnormalizer_version} -Provides: bundled(python3-%{idna}) = %{idna_version} -Provides: bundled(python3-%{requests}) = %{requests_version} -Provides: bundled(python3-%{urllib3}) = %{urllib3_version} -%endif %description -n ha-cloud-support Support libraries for Fence Agents. %files -n ha-cloud-support +%ifnarch ppc64le %dir %{_usr}/lib/%{name} %{_usr}/lib/%{name}/support %exclude %{_usr}/lib/%{name}/support/common %exclude %{_usr}/lib/%{name}/support/kubevirt %endif +%endif %package all License: GPLv2+ and LGPLv2+ and ASL 2.0 @@ -781,7 +699,6 @@ Group: System Environment/Base Summary: Fence agent for Alibaba Cloud (Aliyun) Requires: fence-agents-common >= %{version}-%{release} Requires: ha-cloud-support = %{version}-%{release} -Requires: python3-jmespath >= 0.9.0 Obsoletes: %{name} < %{version}-%{release} %description aliyun The fence-agents-aliyun package contains a fence agent for Alibaba Cloud (Aliyun) instances. @@ -1259,28 +1176,22 @@ License: GPLv2+ and LGPLv2+ and ASL 2.0 and BSD and BSD-2-Clause and BSD-3-Claus Summary: Fence agent for KubeVirt platform Requires: fence-agents-common = %{version}-%{release} Provides: bundled(python3-%{openshift}) = %{openshift_version} -Provides: bundled(python3-%{ruamelyamlclib}) = %{ruamelyamlclib_version} Provides: bundled(python3-%{kubernetes}) = %{kubernetes_version} Provides: bundled(python3-%{certifi}) = %{certifi_version} Provides: bundled(python3-%{googleauth}) = %{googleauth_version} Provides: bundled(python3-%{cachetools}) = %{cachetools_version} -Provides: bundled(python3-%{pyasn1modules}) = %{pyasn1modules_version} Provides: bundled(python3-%{pyasn1}) = %{pyasn1_version} +Provides: bundled(python3-%{pyasn1modules}) = %{pyasn1modules_version} Provides: bundled(python3-%{dateutil}) = %{dateutil_version} Provides: bundled(python3-%{pyyaml}) = %{pyyaml_version} -Provides: bundled(python3-%{six}) = %{six_version} -Provides: bundled(python3-%{urllib3}) = %{urllib3_version} Provides: bundled(python3-%{websocketclient}) = %{websocketclient_version} Provides: bundled(python3-%{jinja2}) = %{jinja2_version} Provides: bundled(python3-%{markupsafe}) = %{markupsafe_version} Provides: bundled(python3-%{stringutils}) = %{stringutils_version} -Provides: bundled(python3-%{requests}) = %{requests_version} -Provides: bundled(python3-%{chrstnormalizer}) = %{chrstnormalizer_version} -Provides: bundled(python3-%{idna}) = %{idna_version} Provides: bundled(python3-%{reqstsoauthlib}) = %{reqstsoauthlib_version} Provides: bundled(python3-%{oauthlib}) = %{oauthlib_version} Provides: bundled(python3-%{ruamelyaml}) = %{ruamelyaml_version} -Provides: bundled(python3-setuptools) = 80.9.0 +Provides: bundled(python3-%{ruamelyamlclib}) = %{ruamelyamlclib_version} %description kubevirt Fence agent for KubeVirt platform. %files kubevirt @@ -1599,6 +1510,15 @@ are located on corosync cluster nodes. %endif %changelog +* Wed Apr 29 2026 Oyvind Albrigtsen - 4.10.0-98.13 +- bundled pyasn1: fix CVE-2026-30922 + Resolves: RHEL-157201 + +* Thu Apr 16 2026 Oyvind Albrigtsen - 4.10.0-98.12 +- bundled cryptography: replace with dependency to fix CVE-2026-26007 +- bundled PyJWT: upgrade to v2.12.1 to fix CVE-2026-32597 + Resolves: RHEL-148436, RHEL-155675 + * Wed Feb 11 2026 Oyvind Albrigtsen - 4.10.0-98.10 - bundled urllib3: fix CVE-2024-37891, CVE-2025-66418, CVE-2025-66471, CVE-2026-21441, and pyasn1 CVE-2026-23490 on all archs