]> git.proxmox.com Git - ceph.git/blob - ceph/src/mgr/PyModuleRegistry.h
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / mgr / PyModuleRegistry.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2017 John Spray <john.spray@redhat.com>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 */
13
14
15 #pragma once
16
17 // First because it includes Python.h
18 #include "PyModule.h"
19
20 #include <string>
21 #include <map>
22 #include <set>
23 #include <memory>
24
25 #include "common/LogClient.h"
26
27 #include "ActivePyModules.h"
28 #include "StandbyPyModules.h"
29
30 class MgrSession;
31
32 /**
33 * This class is responsible for setting up the python runtime environment
34 * and importing the python modules.
35 *
36 * It is *not* responsible for constructing instances of their BaseMgrModule
37 * subclasses: that is the job of ActiveMgrModule, which consumes the class
38 * references that we load here.
39 */
40 class PyModuleRegistry
41 {
42 private:
43 mutable Mutex lock{"PyModuleRegistry::lock"};
44 LogChannelRef clog;
45
46 std::map<std::string, PyModuleRef> modules;
47
48 std::unique_ptr<ActivePyModules> active_modules;
49 std::unique_ptr<StandbyPyModules> standby_modules;
50
51 PyThreadState *pMainThreadState;
52
53 // We have our own copy of MgrMap, because we are constructed
54 // before ClusterState exists.
55 MgrMap mgr_map;
56
57 /**
58 * Discover python modules from local disk
59 */
60 std::set<std::string> probe_modules(const std::string &path) const;
61
62 PyModuleConfig module_config;
63
64 public:
65 void handle_config(const std::string &k, const std::string &v);
66 void handle_config_notify();
67
68 /**
69 * Get references to all modules (whether they have loaded and/or
70 * errored) or not.
71 */
72 std::list<PyModuleRef> get_modules() const
73 {
74 std::lock_guard l(lock);
75 std::list<PyModuleRef> modules_out;
76 for (const auto &i : modules) {
77 modules_out.push_back(i.second);
78 }
79
80 return modules_out;
81 }
82
83 explicit PyModuleRegistry(LogChannelRef clog_)
84 : clog(clog_)
85 {}
86
87 /**
88 * @return true if the mgrmap has changed such that the service needs restart
89 */
90 bool handle_mgr_map(const MgrMap &mgr_map_);
91
92 void init();
93
94 void upgrade_config(
95 MonClient *monc,
96 const std::map<std::string, std::string> &old_config);
97
98 void active_start(
99 DaemonStateIndex &ds, ClusterState &cs,
100 const std::map<std::string, std::string> &kv_store,
101 MonClient &mc, LogChannelRef clog_, LogChannelRef audit_clog_,
102 Objecter &objecter_, Client &client_, Finisher &f,
103 DaemonServer &server);
104 void standby_start(MonClient &mc, Finisher &f);
105
106 bool is_standby_running() const
107 {
108 return standby_modules != nullptr;
109 }
110
111 void active_shutdown();
112 void shutdown();
113
114 std::vector<MonCommand> get_commands() const;
115 std::vector<ModuleCommand> get_py_commands() const;
116
117 /**
118 * Get the specified module. The module does not have to be
119 * loaded or runnable.
120 *
121 * Returns an empty reference if it does not exist.
122 */
123 PyModuleRef get_module(const std::string &module_name)
124 {
125 std::lock_guard l(lock);
126 auto module_iter = modules.find(module_name);
127 if (module_iter == modules.end()) {
128 return {};
129 }
130 return module_iter->second;
131 }
132
133 /**
134 * Pass through command to the named module for execution.
135 *
136 * The command must exist in the COMMANDS reported by the module. If it
137 * doesn't then this will abort.
138 *
139 * If ActivePyModules has not been instantiated yet then this will
140 * return EAGAIN.
141 */
142 int handle_command(
143 const ModuleCommand& module_command,
144 const MgrSession& session,
145 const cmdmap_t &cmdmap,
146 const bufferlist &inbuf,
147 std::stringstream *ds,
148 std::stringstream *ss);
149
150 /**
151 * Pass through health checks reported by modules, and report any
152 * modules that have failed (i.e. unhandled exceptions in serve())
153 */
154 void get_health_checks(health_check_map_t *checks);
155
156 void get_progress_events(map<std::string,ProgressEvent> *events) {
157 if (active_modules) {
158 active_modules->get_progress_events(events);
159 }
160 }
161
162 // FIXME: breaking interface so that I don't have to go rewrite all
163 // the places that call into these (for now)
164 // >>>
165 void notify_all(const std::string &notify_type,
166 const std::string &notify_id)
167 {
168 if (active_modules) {
169 active_modules->notify_all(notify_type, notify_id);
170 }
171 }
172
173 void notify_all(const LogEntry &log_entry)
174 {
175 if (active_modules) {
176 active_modules->notify_all(log_entry);
177 }
178 }
179
180 std::map<std::string, std::string> get_services() const
181 {
182 ceph_assert(active_modules);
183 return active_modules->get_services();
184 }
185 // <<< (end of ActivePyModules cheeky call-throughs)
186 };