From 6dd4d0504de9806fcf7c398a8d66b956b45986d9 Mon Sep 17 00:00:00 2001 From: John Spray Date: Thu, 27 Jul 2017 11:50:23 -0400 Subject: [PATCH] mgr: enable python modules to advertise their service URI Fixes: http://tracker.ceph.com/issues/17460 Signed-off-by: John Spray (cherry picked from commit a0183a63fa791954d14c57632e184858cefe893d) --- src/mgr/Mgr.cc | 7 +++++++ src/mgr/Mgr.h | 1 + src/mgr/MgrPyModule.h | 13 +++++++++++++ src/mgr/MgrStandby.cc | 18 +++++++++++------- src/mgr/PyModules.cc | 27 +++++++++++++++++++++++++++ src/mgr/PyModules.h | 4 ++++ src/mgr/PyState.cc | 20 +++++++++++++++++++- src/pybind/mgr/mgr_module.py | 11 ++++++++++- 8 files changed, 92 insertions(+), 9 deletions(-) diff --git a/src/mgr/Mgr.cc b/src/mgr/Mgr.cc index 092b71fdb9fac..e51bd369d4029 100644 --- a/src/mgr/Mgr.cc +++ b/src/mgr/Mgr.cc @@ -646,3 +646,10 @@ std::vector Mgr::get_command_set() const return commands; } +std::map Mgr::get_services() const +{ + Mutex::Locker l(lock); + + return py_modules.get_services(); +} + diff --git a/src/mgr/Mgr.h b/src/mgr/Mgr.h index 68f2b40b4616d..e37b1b9bee6f6 100644 --- a/src/mgr/Mgr.h +++ b/src/mgr/Mgr.h @@ -100,6 +100,7 @@ public: void shutdown(); std::vector get_command_set() const; + std::map get_services() const; }; #endif diff --git a/src/mgr/MgrPyModule.h b/src/mgr/MgrPyModule.h index 232d4ebac9233..bb1dc5b621467 100644 --- a/src/mgr/MgrPyModule.h +++ b/src/mgr/MgrPyModule.h @@ -57,6 +57,9 @@ private: int load_commands(); + // Optional, URI exposed by plugins that implement serve() + std::string uri; + public: MgrPyModule(const std::string &module_name, const std::string &sys_path, PyThreadState *main_ts); ~MgrPyModule(); @@ -86,6 +89,16 @@ public: health_checks = std::move(c); } void get_health_checks(health_check_map_t *checks); + + void set_uri(const std::string &str) + { + uri = str; + } + + std::string get_uri() const + { + return uri; + } }; std::string handle_pyerror(); diff --git a/src/mgr/MgrStandby.cc b/src/mgr/MgrStandby.cc index 4eb80e22fca68..d3bdcdfc16741 100644 --- a/src/mgr/MgrStandby.cc +++ b/src/mgr/MgrStandby.cc @@ -171,13 +171,17 @@ void MgrStandby::send_beacon() modules, std::move(metadata)); - if (available && !available_in_map) { - // We are informing the mon that we are done initializing: inform - // it of our command set. This has to happen after init() because - // it needs the python modules to have loaded. - m->set_command_descs(active_mgr->get_command_set()); - dout(4) << "going active, including " << m->get_command_descs().size() - << " commands in beacon" << dendl; + if (available) { + if (!available_in_map) { + // We are informing the mon that we are done initializing: inform + // it of our command set. This has to happen after init() because + // it needs the python modules to have loaded. + m->set_command_descs(active_mgr->get_command_set()); + dout(4) << "going active, including " << m->get_command_descs().size() + << " commands in beacon" << dendl; + } + + m->set_services(active_mgr->get_services()); } monc.send_mon_message(m); diff --git a/src/mgr/PyModules.cc b/src/mgr/PyModules.cc index be81c62ad6f49..9410c3c441098 100644 --- a/src/mgr/PyModules.cc +++ b/src/mgr/PyModules.cc @@ -667,6 +667,22 @@ std::vector PyModules::get_commands() const return result; } + +std::map PyModules::get_services() const +{ + std::map result; + Mutex::Locker l(lock); + for (const auto& i : modules) { + const auto &module = i.second.get(); + std::string svc_str = module->get_uri(); + if (!svc_str.empty()) { + result[module->get_name()] = svc_str; + } + } + + return result; +} + void PyModules::insert_config(const std::map &new_config) { @@ -865,3 +881,14 @@ void PyModules::get_health_checks(health_check_map_t *checks) p.second->get_health_checks(checks); } } + +void PyModules::set_uri(const std::string& module_name, + const std::string &uri) +{ + Mutex::Locker l(lock); + + dout(4) << " module " << module_name << " set URI '" << uri << "'" << dendl; + + modules[module_name]->set_uri(uri); +} + diff --git a/src/mgr/PyModules.h b/src/mgr/PyModules.h index 521ee757db0f8..17553541ee5ad 100644 --- a/src/mgr/PyModules.h +++ b/src/mgr/PyModules.h @@ -92,6 +92,8 @@ public: health_check_map_t&& checks); void get_health_checks(health_check_map_t *checks); + void set_uri(const std::string& module_name, const std::string &uri); + void log(const std::string &module_name, int level, const std::string &record); @@ -105,6 +107,8 @@ public: void insert_config(const std::map &new_config); + std::map get_services() const; + // Public so that MonCommandCompletion can use it // FIXME: for send_command completion notifications, // send it to only the module that sent the command, not everyone diff --git a/src/mgr/PyState.cc b/src/mgr/PyState.cc index d919d5af1fa09..a0112c5e49967 100644 --- a/src/mgr/PyState.cc +++ b/src/mgr/PyState.cc @@ -460,13 +460,28 @@ get_perf_schema(BaseMgrModule *self, PyObject *args) return self->py_modules->get_perf_schema_python(type_str, svc_id); } - static PyObject * ceph_get_osdmap(BaseMgrModule *self, PyObject *args) { return self->py_modules->get_osdmap(); } +static PyObject* +ceph_set_uri(BaseMgrModule *self, PyObject *args) +{ + char *svc_str = nullptr; + if (!PyArg_ParseTuple(args, "s:ceph_advertize_service", + &svc_str)) { + return nullptr; + } + + // We call down into PyModules even though we have a MgrPyModule + // reference here, because MgrPyModule's fields are protected + // by PyModules' lock. + self->py_modules->set_uri(self->this_module->get_name(), svc_str); + + Py_RETURN_NONE; +} PyMethodDef BaseMgrModule_methods[] = { @@ -518,6 +533,9 @@ PyMethodDef BaseMgrModule_methods[] = { {"_ceph_get_osdmap", (PyCFunction)ceph_get_osdmap, METH_NOARGS, "Get an OSDMap* in a python capsule"}, + {"_ceph_set_uri", (PyCFunction)ceph_set_uri, METH_VARARGS, + "Advertize a service URI served by this module"}, + {NULL, NULL, 0, NULL} }; diff --git a/src/pybind/mgr/mgr_module.py b/src/pybind/mgr/mgr_module.py index fdcd24a92030c..aaad609e6192f 100644 --- a/src/pybind/mgr/mgr_module.py +++ b/src/pybind/mgr/mgr_module.py @@ -433,7 +433,7 @@ class MgrModule(ceph_module.BaseMgrModule): OSDMap. :return: OSDMap """ - return OSDMap(ceph_state.get_osdmap()) + return OSDMap(self._ceph_get_osdmap()) def get_all_perf_counters(self, prio_limit=PRIO_USEFUL): """ @@ -491,3 +491,12 @@ class MgrModule(ceph_module.BaseMgrModule): self.log.debug("returning {0} counter".format(len(result))) return result + + def set_uri(self, uri): + """ + If the module exposes a service, then call this to publish the + address once it is available. + + :return: a string + """ + return self._ceph_set_uri(uri) -- 2.39.5