* [pve-devel] [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading
@ 2025-07-16 17:39 Max R. Carrara
2025-07-16 17:39 ` [pve-devel] [PATCH v1 master ceph 1/2] provide workaround for PyO3 ImportError Max R. Carrara
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Max R. Carrara @ 2025-07-16 17:39 UTC (permalink / raw)
To: pve-devel
Fix Ceph Squid Module Loading - v1
==================================
The first patch provides a workaround for the PyO3 ImportError that's
being thrown by the `restful` Ceph mgr Python module upon import.
This fixes the following error:
2025-07-16T17:40:40.932+0200 7c315bc77080 1 mgr[py] Loading python module 'restful'
2025-07-16T17:40:41.220+0200 7c315bc77080 -1 mgr[py] Module not found: 'restful'
2025-07-16T17:40:41.220+0200 7c315bc77080 -1 mgr[py] Traceback (most recent call last):
File "/usr/share/ceph/mgr/restful/__init__.py", line 1, in <module>
from .module import Module
File "/usr/share/ceph/mgr/restful/module.py", line 22, in <module>
from OpenSSL import crypto
File "/lib/python3/dist-packages/OpenSSL/__init__.py", line 8, in <module>
from OpenSSL import SSL, crypto
File "/lib/python3/dist-packages/OpenSSL/SSL.py", line 15, in <module>
from cryptography import x509
File "/lib/python3/dist-packages/cryptography/x509/__init__.py", line 7, in <module>
from cryptography.x509 import certificate_transparency, verification
File "/lib/python3/dist-packages/cryptography/x509/certificate_transparency.py", line 11, in <module>
from cryptography.hazmat.bindings._rust import x509 as rust_x509
ImportError: PyO3 modules compiled for CPython 3.8 or older may only be initialized once per interpreter process
2025-07-16T17:40:41.222+0200 7c315bc77080 -1 mgr[py] Class not found in module 'restful'
2025-07-16T17:40:41.222+0200 7c315bc77080 -1 mgr[py] Error loading module 'restful': (2) No such file or directory
The second patch fixes how the Ceph mgr looks up the NOTIFY_TYPES
attribute of the mgr Python modules' classes. This also happens to fix
the `mgr_module` Python module import failure. In total, this fixes
errors like the following:
2025-07-16T17:40:41.222+0200 7c315bc77080 1 mgr[py] Loading python module 'selftest'
2025-07-16T17:40:41.377+0200 7c315bc77080 -1 mgr[py] Module selftest has missing NOTIFY_TYPES member
2025-07-16T17:40:41.377+0200 7c315bc77080 -1 mgr[py] Module not found: 'mgr_module'
2025-07-16T17:40:41.377+0200 7c315bc77080 -1 mgr[py] AttributeError: type object 'Module' has no attribute 'NOTIFY_TYPES'
2025-07-16T17:40:41.377+0200 7c315bc77080 1 mgr[py] Loading python module 'snap_schedule'
2025-07-16T17:40:41.497+0200 7c315bc77080 -1 mgr[py] Module snap_schedule has missing NOTIFY_TYPES member
2025-07-16T17:40:41.497+0200 7c315bc77080 -1 mgr[py] Module not found: 'mgr_module'
2025-07-16T17:40:41.497+0200 7c315bc77080 -1 mgr[py] AttributeError: type object 'Module' has no attribute 'NOTIFY_TYPES'
2025-07-16T17:40:41.497+0200 7c315bc77080 1 mgr[py] Loading python module 'stats'
2025-07-16T17:40:41.636+0200 7c315bc77080 1 mgr[py] Loading python module 'status'
2025-07-16T17:40:41.785+0200 7c315bc77080 -1 mgr[py] Module status has missing NOTIFY_TYPES member
2025-07-16T17:40:41.785+0200 7c315bc77080 -1 mgr[py] Module not found: 'mgr_module'
2025-07-16T17:40:41.785+0200 7c315bc77080 -1 mgr[py] AttributeError: type object 'Module' has no attribute 'NOTIFY_TYPES'
Note: These logs can be found inside the ceph-mgr logs in the
/var/log/ceph directory.
The commit messages of the supplied patches elaborate on further
details.
Summary of Changes
------------------
Max R. Carrara (2):
provide workaround for PyO3 ImportError
mgr: fix errors regarding module imports and NOTIFY_TYPES attributes
...ul-provide-workaround-for-PyO3-Impor.patch | 152 ++++++++++++++++++
...mport-by-making-NOTIFY_TYPES-in-py-m.patch | 56 +++++++
patches/series | 2 +
3 files changed, 210 insertions(+)
create mode 100644 patches/0058-pybind-mgr-restful-provide-workaround-for-PyO3-Impor.patch
create mode 100644 patches/0059-mgr-fix-module-import-by-making-NOTIFY_TYPES-in-py-m.patch
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [pve-devel] [PATCH v1 master ceph 1/2] provide workaround for PyO3 ImportError
2025-07-16 17:39 [pve-devel] [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading Max R. Carrara
@ 2025-07-16 17:39 ` Max R. Carrara
2025-07-16 17:39 ` [pve-devel] [PATCH v1 master ceph 2/2] mgr: fix errors regarding module imports and NOTIFY_TYPES attributes Max R. Carrara
2025-07-16 20:15 ` [pve-devel] applied-series: [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading Thomas Lamprecht
2 siblings, 0 replies; 4+ messages in thread
From: Max R. Carrara @ 2025-07-16 17:39 UTC (permalink / raw)
To: pve-devel
By moving the self-signed cert generation into a separate module and
consequently running it via `subprocess.run`--so, as a new,
independent Python process--the PyO3 ImportError is successfully
avoided.
Inspired by an upstream PR [0].
[0]: https://github.com/ceph/ceph/pull/62951
Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
...ul-provide-workaround-for-PyO3-Impor.patch | 152 ++++++++++++++++++
patches/series | 1 +
2 files changed, 153 insertions(+)
create mode 100644 patches/0058-pybind-mgr-restful-provide-workaround-for-PyO3-Impor.patch
diff --git a/patches/0058-pybind-mgr-restful-provide-workaround-for-PyO3-Impor.patch b/patches/0058-pybind-mgr-restful-provide-workaround-for-PyO3-Impor.patch
new file mode 100644
index 0000000000..25fb720410
--- /dev/null
+++ b/patches/0058-pybind-mgr-restful-provide-workaround-for-PyO3-Impor.patch
@@ -0,0 +1,152 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Max R. Carrara" <m.carrara@proxmox.com>
+Date: Wed, 16 Jul 2025 13:14:39 +0200
+Subject: [PATCH 58/59] pybind/mgr/restful: provide workaround for PyO3
+ ImportError
+
+Move the self-signed cert generation into a separate module
+inside python-common/ceph and run the module in a separate Python
+process.
+
+This provides a workaround for the ImportError thrown by PyO3 when
+the `restful` module is loaded in the context of multiple Python
+sub-interpreters being present. In particular, the ImportError is
+thrown by the `crypto` module of the `OpenSSL` package.
+
+Inspired by an upstream PR [0].
+
+[0]: https://github.com/ceph/ceph/pull/62951
+
+Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
+---
+ src/pybind/mgr/restful/module.py | 24 +++------
+ src/python-common/ceph/_crypto_wrap.py | 69 ++++++++++++++++++++++++++
+ 2 files changed, 76 insertions(+), 17 deletions(-)
+ create mode 100644 src/python-common/ceph/_crypto_wrap.py
+
+diff --git a/src/pybind/mgr/restful/module.py b/src/pybind/mgr/restful/module.py
+index 0f8c78e0bd8..7f93c41f1e6 100644
+--- a/src/pybind/mgr/restful/module.py
++++ b/src/pybind/mgr/restful/module.py
+@@ -7,6 +7,7 @@ import json
+ import time
+ import errno
+ import inspect
++import subprocess
+ import tempfile
+ import threading
+ import traceback
+@@ -19,7 +20,6 @@ from . import context
+
+ from uuid import uuid4
+ from pecan import jsonify, make_app
+-from OpenSSL import crypto
+ from pecan.rest import RestController
+ from werkzeug.serving import make_server, make_ssl_devcert
+
+@@ -401,24 +401,14 @@ class Module(MgrModule):
+
+
+ def create_self_signed_cert(self):
+- # create a key pair
+- pkey = crypto.PKey()
+- pkey.generate_key(crypto.TYPE_RSA, 2048)
+-
+- # create a self-signed cert
+- cert = crypto.X509()
+- cert.get_subject().O = "IT"
+- cert.get_subject().CN = "ceph-restful"
+- cert.set_serial_number(int(uuid4()))
+- cert.gmtime_adj_notBefore(0)
+- cert.gmtime_adj_notAfter(10*365*24*60*60)
+- cert.set_issuer(cert.get_subject())
+- cert.set_pubkey(pkey)
+- cert.sign(pkey, 'sha512')
++ cmd = ["python3", "-m", "ceph._crypto_wrap", "create_self_signed_cert"]
++
++ response = subprocess.run(cmd, capture_output=True, check=True)
++ response_obj = json.loads(response.stdout)
+
+ return (
+- crypto.dump_certificate(crypto.FILETYPE_PEM, cert),
+- crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
++ response_obj["cert"].encode("utf-8"),
++ response_obj["key"].encode("utf-8"),
+ )
+
+
+diff --git a/src/python-common/ceph/_crypto_wrap.py b/src/python-common/ceph/_crypto_wrap.py
+new file mode 100644
+index 00000000000..16a19a5345e
+--- /dev/null
++++ b/src/python-common/ceph/_crypto_wrap.py
+@@ -0,0 +1,69 @@
++"""CLI wrapper for cryptographic functions of the :mod:`restful` module.
++
++To be called via :func:`subprocess.run()` as a workaround for
++:class:`ImportError`s related to PyO3's current lack of sub-interpreter
++support.
++
++Note:
++ Since this module is installed as part of the ``ceph`` package,
++ it should be called like so::
++
++ python3 -m ceph._crypto_wrap create_self_signed_cert
++"""
++
++import argparse
++import sys
++import json
++
++from argparse import Namespace
++from typing import Any
++from uuid import uuid4
++
++from OpenSSL import crypto
++
++
++def _respond(data: dict[str, Any]) -> None:
++ json.dump(data, sys.stdout)
++ sys.stdout.flush()
++
++
++def create_self_signed_cert(args: Namespace) -> None:
++ cert_key_pair = _create_self_signed_cert()
++ _respond(cert_key_pair)
++
++
++def _create_self_signed_cert() -> dict[str, str]:
++ # create a key pair
++ pubkey = crypto.PKey()
++ pubkey.generate_key(crypto.TYPE_RSA, 2048)
++
++ # create a self-signed cert
++ cert = crypto.X509()
++ cert.get_subject().O = "IT"
++ cert.get_subject().CN = "ceph-restful"
++ cert.set_serial_number(int(uuid4()))
++ cert.gmtime_adj_notBefore(0)
++ cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
++ cert.set_issuer(cert.get_subject())
++ cert.set_pubkey(pubkey)
++ cert.sign(pubkey, "sha512")
++
++ return {
++ "cert": crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode(),
++ "key": crypto.dump_privatekey(crypto.FILETYPE_PEM, pubkey).decode(),
++ }
++
++
++def main() -> None:
++ parser = argparse.ArgumentParser(prog="_crypto_wrap.py")
++ subparsers = parser.add_subparsers(required=True)
++
++ parser_cssc = subparsers.add_parser("create_self_signed_cert")
++ parser_cssc.set_defaults(func=create_self_signed_cert)
++
++ args = parser.parse_args()
++ args.func(args)
++
++
++if __name__ == "__main__":
++ main()
diff --git a/patches/series b/patches/series
index 728a9f935e..ff23f8b640 100644
--- a/patches/series
+++ b/patches/series
@@ -51,3 +51,4 @@
0055-python-common-cryptotools-catch-all-failures-to-read.patch
0056-mgr-cephadm-always-use-the-internal-cryptocaller.patch
0057-mgr-dashboard-add-an-option-to-control-the-dashboard.patch
+0058-pybind-mgr-restful-provide-workaround-for-PyO3-Impor.patch
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [pve-devel] [PATCH v1 master ceph 2/2] mgr: fix errors regarding module imports and NOTIFY_TYPES attributes
2025-07-16 17:39 [pve-devel] [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading Max R. Carrara
2025-07-16 17:39 ` [pve-devel] [PATCH v1 master ceph 1/2] provide workaround for PyO3 ImportError Max R. Carrara
@ 2025-07-16 17:39 ` Max R. Carrara
2025-07-16 20:15 ` [pve-devel] applied-series: [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading Thomas Lamprecht
2 siblings, 0 replies; 4+ messages in thread
From: Max R. Carrara @ 2025-07-16 17:39 UTC (permalink / raw)
To: pve-devel
By handling the AttributeError that is thrown internally, the import
of several mgr modules also works again.
See the patch's message for all details.
Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
...mport-by-making-NOTIFY_TYPES-in-py-m.patch | 56 +++++++++++++++++++
patches/series | 1 +
2 files changed, 57 insertions(+)
create mode 100644 patches/0059-mgr-fix-module-import-by-making-NOTIFY_TYPES-in-py-m.patch
diff --git a/patches/0059-mgr-fix-module-import-by-making-NOTIFY_TYPES-in-py-m.patch b/patches/0059-mgr-fix-module-import-by-making-NOTIFY_TYPES-in-py-m.patch
new file mode 100644
index 0000000000..5595c96c9e
--- /dev/null
+++ b/patches/0059-mgr-fix-module-import-by-making-NOTIFY_TYPES-in-py-m.patch
@@ -0,0 +1,56 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: "Max R. Carrara" <m.carrara@proxmox.com>
+Date: Wed, 16 Jul 2025 16:31:43 +0200
+Subject: [PATCH 59/59] mgr: fix module import by making NOTIFY_TYPES in py
+ modules optional
+
+If NOTIFY_TYPES isn't an attribute of the passed class, the Python
+(sub-)interpreter raises an AttributeError that must be handled or cleared
+explicitly via the Python C-API. Unfortunately, this isn't done here,
+which means that the exception sticks around until handled.
+
+This caused a call to PyModule::load_subclass_of() to fail and
+incorrectly report the AttributeError as cause.
+
+Checking whether the class has NOTIFY_TYPES as attribute in the first
+place fixes this.
+
+Note that there's an upstream PR [0] that wasn't backported that aimed
+to fix this, but does so incorrectly, as the exception is still not
+cleared there. The warnings regarding NOTIFY_TYPES missing also occurs
+on Reef but doesn't cause any module imports to fail there. As the
+affected Ceph code has stayed mostly the same between bookworm and
+trixie releases, this suggests that some behavior between Python 3.11
+and 3.13 likely changed.
+
+Either way, avoiding the AttributeError altogether fixes this.
+
+[0]: https://github.com/ceph/ceph/pull/57106
+
+Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
+---
+ src/mgr/PyModule.cc | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/src/mgr/PyModule.cc b/src/mgr/PyModule.cc
+index 084cf3ffc1e..e6fd269dca5 100644
+--- a/src/mgr/PyModule.cc
++++ b/src/mgr/PyModule.cc
+@@ -513,11 +513,13 @@ int PyModule::register_options(PyObject *cls)
+
+ int PyModule::load_notify_types()
+ {
+- PyObject *ls = PyObject_GetAttrString(pClass, "NOTIFY_TYPES");
+- if (ls == nullptr) {
+- derr << "Module " << get_name() << " has missing NOTIFY_TYPES member" << dendl;
+- return -EINVAL;
++ if (!PyObject_HasAttrString(pClass, "NOTIFY_TYPES")) {
++ dout(10) << "Module " << get_name() << " has no NOTIFY_TYPES member" << dendl;
++ return 0;
+ }
++
++ PyObject *ls = PyObject_GetAttrString(pClass, "NOTIFY_TYPES");
++
+ if (!PyObject_TypeCheck(ls, &PyList_Type)) {
+ // Relatively easy mistake for human to make, e.g. defining COMMANDS
+ // as a {} instead of a []
diff --git a/patches/series b/patches/series
index ff23f8b640..b820614566 100644
--- a/patches/series
+++ b/patches/series
@@ -52,3 +52,4 @@
0056-mgr-cephadm-always-use-the-internal-cryptocaller.patch
0057-mgr-dashboard-add-an-option-to-control-the-dashboard.patch
0058-pybind-mgr-restful-provide-workaround-for-PyO3-Impor.patch
+0059-mgr-fix-module-import-by-making-NOTIFY_TYPES-in-py-m.patch
--
2.39.5
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [pve-devel] applied-series: [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading
2025-07-16 17:39 [pve-devel] [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading Max R. Carrara
2025-07-16 17:39 ` [pve-devel] [PATCH v1 master ceph 1/2] provide workaround for PyO3 ImportError Max R. Carrara
2025-07-16 17:39 ` [pve-devel] [PATCH v1 master ceph 2/2] mgr: fix errors regarding module imports and NOTIFY_TYPES attributes Max R. Carrara
@ 2025-07-16 20:15 ` Thomas Lamprecht
2 siblings, 0 replies; 4+ messages in thread
From: Thomas Lamprecht @ 2025-07-16 20:15 UTC (permalink / raw)
To: pve-devel, Max R. Carrara
On Wed, 16 Jul 2025 19:39:54 +0200, Max R. Carrara wrote:
> Fix Ceph Squid Module Loading - v1
> ==================================
>
> The first patch provides a workaround for the PyO3 ImportError that's
> being thrown by the `restful` Ceph mgr Python module upon import.
> This fixes the following error:
>
> [...]
Patches seem relatively straight forward and I saw no new crash reports about
mgr modules in my test cluster, so:
Applied, thanks!
[1/2] provide workaround for PyO3 ImportError
commit: 51c4e16ffa4d46944b03b376e14aa92c7ca758ab
[2/2] mgr: fix errors regarding module imports and NOTIFY_TYPES attributes
commit: 099772ef89be90332860fc9606b70ee5ad6b6d38
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-07-16 20:14 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-16 17:39 [pve-devel] [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading Max R. Carrara
2025-07-16 17:39 ` [pve-devel] [PATCH v1 master ceph 1/2] provide workaround for PyO3 ImportError Max R. Carrara
2025-07-16 17:39 ` [pve-devel] [PATCH v1 master ceph 2/2] mgr: fix errors regarding module imports and NOTIFY_TYPES attributes Max R. Carrara
2025-07-16 20:15 ` [pve-devel] applied-series: [PATCH v1 master ceph 0/2] Fix Ceph Squid Module Loading Thomas Lamprecht
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.