New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mgr: In plugins 'module' classes need not to be called "Module" anymore #18171
Conversation
src/mgr/MgrPyModule.cc
Outdated
@@ -172,31 +172,43 @@ int MgrPyModule::load() | |||
|
|||
// Find the class | |||
// TODO: let them call it what they want instead of just 'Module' | |||
auto pClass = PyObject_GetAttrString(pModule, (const char*)"Module"); | |||
auto tempClass = PyObject_GetAttrString(pModule, (const char*)"MgrModule"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, checking the tp_subclasses
might work. but because tp_subclasses
is an internal member variable and only for CPython's internal usage, this is fragile. we should get using PyModule_GetDict()
and check them using PyObject_IsSubclass()
, the pseudo code looks like
auto locals = PyModule_GetDict(pModule);
PyObject *key, *value;
Py_ssize_t pos = 0;
while (PyDict_Next(locals, &pos, &key, &value)) {
if (!PyType_Check(value)) {
continue;
}
if (PyObject_IsSubclass(value, mgr_module_type)) {
// ...
}
}
where mgr_module_type
is thePyObject
of MgrModule
.
88f532c
to
d9a6378
Compare
src/mgr/MgrPyModule.cc
Outdated
|
||
if (!PyType_Check(value)) { | ||
continue; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong indent
src/mgr/MgrPyModule.cc
Outdated
continue; | ||
} | ||
|
||
if (PyObject_IsSubclass(value, mgr_module_type)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!PyObject_IsSubclass(value, mgr_module_type)) {
continue;
}
to reduce the indent level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bhavishyagopesh could you reconsider this suggestion?
src/mgr/MgrPyModule.cc
Outdated
PyObject *key, *value; | ||
Py_ssize_t pos = 0; | ||
|
||
if (mgr_module_type == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this check to where mgr_module_type
is initialized.
src/mgr/MgrPyModule.cc
Outdated
Py_DECREF(pyHandle); | ||
Py_DECREF(pArgs); | ||
if (pClassInstance == nullptr) { | ||
derr << "Failed to construct class in '" << module_name << "'" << dendl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be helpful if we can print out the name (key
) of the class.
src/mgr/MgrPyModule.cc
Outdated
derr << handle_pyerror() << dendl; | ||
return -EINVAL; | ||
} else { | ||
dout(1) << "Constructed class from module: " << module_name << dendl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto.
src/mgr/MgrPyModule.cc
Outdated
dout(1) << "Constructed class from module: " << module_name << dendl; | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this empty line, please.
4dab29a
to
f0a6b56
Compare
@tchaikov Any other suggestions? |
src/mgr/MgrPyModule.cc
Outdated
Py_DECREF(pModule); | ||
if (pClass == nullptr) { | ||
auto mgr_module_type = PyObject_GetAttrString(pModule, (const char*)"MgrModule"); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this empty line.
src/mgr/MgrPyModule.cc
Outdated
return -EINVAL; | ||
} else { | ||
dout(1) << "Constructed class from module: " << module_name << dendl; | ||
Py_DECREF(pModule); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we cannot deref pModule
yet. we are actually referencing it right after this line.
src/mgr/MgrPyModule.cc
Outdated
Py_ssize_t pos = 0; | ||
|
||
while (PyDict_Next(locals, &pos, &key, &value)) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this empty line.
src/mgr/MgrPyModule.cc
Outdated
if (!PyType_Check(value)) { | ||
continue; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto.
src/mgr/MgrPyModule.cc
Outdated
} | ||
|
||
if (PyObject_IsSubclass(value, mgr_module_type)) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto.
src/mgr/MgrPyModule.cc
Outdated
Py_DECREF(pyHandle); | ||
Py_DECREF(pArgs); | ||
if (pClassInstance == nullptr) { | ||
derr << "Failed to construct class '" << PyObject_Str(pClass) << "'" << " in " << "'" << module_name << "'" << dendl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use key
? also PyObject_Str()
returns a new reference, we should deref after using it. and what's the point of printing a PyObjecter
pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw, use PyString_AsString(key)
to retrieve the c string from it.
could you prefix the title of your commit message with the subcomponent your are changing ? see https://github.com/ceph/ceph/blob/master/SubmittingPatches.rst#3-describe-your-changes |
src/mgr/MgrPyModule.cc
Outdated
if (pClass == nullptr) { | ||
auto mgr_module_type = PyObject_GetAttrString(pModule, (const char*)"MgrModule"); | ||
|
||
if (mgr_module_type == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think the plugin is not required to expose MgrModule
. can we load this class from mgr_module
instead?
f0a6b56
to
57f9fa2
Compare
@tchaikov Any more improvements? |
57f9fa2
to
89f1c41
Compare
OK - docs built |
src/mgr/MgrPyModule.cc
Outdated
} else { | ||
dout(1) << "Constructed class: " << PyString_AsString(key) << " from module: " << module_name << dendl; | ||
} | ||
Py_DECREF(pClass); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, could move this line next to Py_DECREF(pyHandle);
.
src/mgr/MgrPyModule.cc
Outdated
auto pClass = PyObject_GetAttrString(pModule, (const char*)"Module"); | ||
Py_DECREF(pModule); | ||
if (pClass == nullptr) { | ||
auto mgr_module_type = PyImport_ImportModule("mgr_module.MgrModule"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove the extra space after auto
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please Py_DECREF(mgr_module_type)
after done with it.
src/mgr/MgrPyModule.cc
Outdated
Py_DECREF(pModule); | ||
if (pClass == nullptr) { | ||
auto mgr_module_type = PyImport_ImportModule("mgr_module.MgrModule"); | ||
if (mgr_module_type == nullptr) { | ||
derr << "Class not found in module '" << module_name << "'" << dendl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change the error message to something like
Unable to import mgr_module from MgrModule
as we are not importing the Module
from from $module_name
here.
src/mgr/MgrPyModule.cc
Outdated
auto locals = PyModule_GetDict(pModule); | ||
PyObject *key, *value; | ||
Py_ssize_t pos = 0; | ||
Py_DECREF(pModule); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, move this line right after PyModule_GetDict(pModule)
.
89f1c41
to
5ec26ad
Compare
@tchaikov any more suggestions? |
src/mgr/MgrPyModule.cc
Outdated
pClassInstance = PyObject_CallObject(pClass, pArgs); | ||
Py_DECREF(pyHandle); | ||
Py_DECREF(pArgs); | ||
Py_DECREF(pClass); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't deref pClass
here, as we are not holding a reference to it.
src/mgr/MgrPyModule.cc
Outdated
Py_DECREF(pArgs); | ||
Py_DECREF(pClass); | ||
if (pClassInstance == nullptr) { | ||
derr << "Failed to construct class '" << PyString_AsString(key) << "'" << " in " << "'" << module_name << "'" << dendl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might want to have a variable holding the retval of PyString_AsString(key)
, like
auto class_name = PyString_AsString(key);
as you are referencing the class using pClass
, while referencing its name using PyString_AsString(key)
.
5ec26ad
to
72b6c5d
Compare
@tchaikov Probably due to some ci/infra issues build is not being reported...but if you still find any improvement you could mention it. Thanks. |
@bhavishyagopesh IIRC, this PR is addressing a ticket a tracker, could you reference it in the commit message? like
please replace "123456" with the actual ticket id. |
1fe58d2
to
e4a851d
Compare
@tchaikov is it okay now? |
@bhavishyagopesh please could you test this yourself and let us know if it is working |
@jcsp Are there any available Dockerfiles that I can run on local system...only for testing purpose. |
please run the minimal test, vstart would suffice. see http://docs.ceph.com/docs/master/dev/quick_guide/ |
@tchaikov two tests fail but they do not look related to plugins.
|
@bhavishyagopesh how did you test this change? |
@tchaikov I ran the |
restful, status, dashboard and balancer are enabled by default in ceph cli is not a binary, it's a python script. and should be built by default. |
@tchaikov it does detect |
again, how do you test this? |
@tchaikov I now ran the |
src/mgr/MgrPyModule.cc
Outdated
Py_DECREF(pModule); | ||
if (pClass == nullptr) { | ||
derr << "Class not found in module '" << module_name << "'" << dendl; | ||
PyObject *mgr_module_name = PyString_FromString("mgr_module"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bhavishyagopesh why don't you just use PyImport_ImportModule()
?
see. #18171 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tchaikov I messed that up, I have changed it now.
e4a851d
to
4a95b4f
Compare
Fixes: http://tracker.ceph.com/issues/17454 Signed-off-by: bhavishyagopesh <bhavishyagopesh@gmail.com>
@bhavishyagopesh the test above would do. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am posting a fixed version at #18526
} | ||
// Just using the module name as the handle, replace with a | ||
// uuidish thing if needed | ||
auto pClass = value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is chance the last loaded class is MgrModule
, which overwrites the one we want to load. so pClassInstance
will be a MgrModule
instance.
closing in favor of #18526 |
failures are due to localpool and influx plugins' failure to load. |
Seems like the failures are not exactly from failures to load but more from the way the tests are a bit racy (doesn't guarantee command descriptions have loaded before running). The tests get more robust in #16651 |
Signed-off-by: bhavishyagopesh bhavishyagopesh@gmail.com