Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / doc / mgr / plugins.rst
1
2 ceph-mgr plugin author guide
3 ============================
4
5 Creating a plugin
6 -----------------
7
8 In pybind/mgr/, create a python module.  Within your module, create a class
9 named ``Module`` that inherits from ``MgrModule``.
10
11 The most important methods to override are:
12
13 * a ``serve`` member function for server-type modules.  This
14   function should block forever.
15 * a ``notify`` member function if your module needs to
16   take action when new cluster data is available.
17 * a ``handle_command`` member function if your module
18   exposes CLI commands.
19
20 Installing a plugin
21 -------------------
22
23 Once your module is present in the location set by the
24 ``mgr module path`` configuration setting, you can enable it
25 via the ``ceph mgr module enable`` command::
26
27   ceph mgr module enable mymodule
28
29 Note that the MgrModule interface is not stable, so any modules maintained
30 outside of the Ceph tree are liable to break when run against any newer
31 or older versions of Ceph.
32
33 Logging
34 -------
35
36 MgrModule instances have a ``log`` property which is a logger instance that
37 sends log messages into the Ceph logging layer where they will be recorded
38 in the mgr daemon's log file.
39
40 Use it the same way you would any other python logger.  The python
41 log levels debug, info, warn, err are mapped into the Ceph
42 severities 20, 4, 1 and 0 respectively.
43
44 Exposing commands
45 -----------------
46
47 Set the ``COMMANDS`` class attribute of your plugin to a list of dicts
48 like this::
49
50     COMMANDS = [
51         {
52             "cmd": "foobar name=myarg,type=CephString",
53             "desc": "Do something awesome",
54             "perm": "rw"
55         }
56     ]
57
58 The ``cmd`` part of each entry is parsed in the same way as internal
59 Ceph mon and admin socket commands (see mon/MonCommands.h in
60 the Ceph source for examples)
61
62 Config settings
63 ---------------
64
65 Modules have access to a simple key/value store (keys and values are
66 byte strings) for storing configuration.  Don't use this for
67 storing large amounts of data.
68
69 Config values are stored using the mon's config-key commands.
70
71 Hints for using these:
72
73 * Reads are fast: ceph-mgr keeps a local in-memory copy
74 * Don't set things by hand with "ceph config-key", the mgr doesn't update
75   at runtime (only set things from within modules).
76 * Writes block until the value is persisted, but reads from another
77   thread will see the new value immediately.
78
79 Any config settings you want to expose to users from your module will
80 need corresponding hooks in ``COMMANDS`` to expose a setter.
81
82 Accessing cluster data
83 ----------------------
84
85 Modules have access to the in-memory copies of the Ceph cluster's
86 state that the mgr maintains.  Accessor functions as exposed
87 as members of MgrModule.
88
89 Calls that access the cluster or daemon state are generally going
90 from Python into native C++ routines.  There is some overhead to this,
91 but much less than for example calling into a REST API or calling into
92 an SQL database.
93
94 There are no consistency rules about access to cluster structures or
95 daemon metadata.  For example, an OSD might exist in OSDMap but
96 have no metadata, or vice versa.  On a healthy cluster these
97 will be very rare transient states, but plugins should be written
98 to cope with the possibility.
99
100 ``get(self, data_name)``
101
102 Fetch named cluster-wide objects such as the OSDMap.  Valid things
103 to fetch are osd_crush_map_text, osd_map, osd_map_tree,
104 osd_map_crush, config, mon_map, fs_map, osd_metadata, pg_summary,
105 df, osd_stats, health, mon_status.
106
107 All these structures have their own JSON representations: experiment
108 or look at the C++ dump() methods to learn about them.
109
110 ``get_server(self, hostname)``
111
112 Fetch metadata about a particular hostname.  This is information
113 that ceph-mgr has gleaned from the daemon metadata reported
114 by daemons running on a particular server.
115
116 ``list_servers(self)``
117
118 Like ``get_server``, but gives information about all servers (i.e. all
119 unique hostnames that have been mentioned in daemon metadata)
120
121 ``get_metadata(self, svc_type, svc_id)``
122
123 Fetch the daemon metadata for a particular service.  svc_type is one
124 of osd or mds, and svc_id is a string (convert OSD integer IDs to strings
125 when calling this).
126
127 ``get_counter(self, svc_type, svc_name, path)``
128
129 Fetch the latest performance counter data for a particular counter.  The
130 path is a period-separated concatenation of the subsystem and the counter
131 name, for example "mds.inodes".
132
133 A list of two-tuples of (timestamp, value) is returned.  This may be
134 empty if no data is available.
135
136 Sending commands
137 ----------------
138
139 A non-blocking facility is provided for sending monitor commands
140 to the cluster.
141
142 ``send_command(self, result, command_str, tag)``
143
144 The ``result`` parameter should be an instance of the CommandResult
145 class, defined in the same module as MgrModule.  This acts as a
146 completion and stores the output of the command.  Use CommandResult.wait()
147 if you want to block on completion.
148
149 The ``command_str`` parameter is a JSON-serialized command.  This
150 uses the same format as the ceph command line, which is a dictionary
151 of command arguments, with the extra ``prefix`` key containing the
152 command name itself.  Consult MonCommands.h for available commands
153 and their expected arguments.
154
155 The ``tag`` parameter is used for nonblocking operation: when
156 a command completes, the ``notify()`` callback on the MgrModule
157 instance is triggered, with notify_type set to "command", and
158 notify_id set to the tag of the command.
159
160 Implementing standby mode
161 -------------------------
162
163 For some modules, it is useful to run on standby manager daemons as well
164 as on the active daemon.  For example, an HTTP server can usefully
165 serve HTTP redirect responses from the standby managers so that
166 the user can point his browser at any of the manager daemons without
167 having to worry about which one is active.
168
169 Standby manager daemons look for a class called ``StandbyModule``
170 in each module.  If the class is not found then the module is not
171 used at all on standby daemons.  If the class is found, then
172 its ``serve`` method is called.  Implementations of ``StandbyModule``
173 must inherit from ``mgr_module.MgrStandbyModule``.
174
175 The interface of ``MgrStandbyModule`` is much restricted compared to
176 ``MgrModule`` -- none of the Ceph cluster state is available to
177 the module.  ``serve`` and ``shutdown`` methods are used in the same
178 way as a normal module class.  The ``get_active_uri`` method enables
179 the standby module to discover the address of its active peer in
180 order to make redirects.  See the ``MgrStandbyModule`` definition
181 in the Ceph source code for the full list of methods.
182
183 For an example of how to use this interface, look at the source code
184 of the ``dashboard`` module.
185
186 Logging
187 -------
188
189 Use your module's ``log`` attribute as your logger.  This is a logger
190 configured to output via the ceph logging framework, to the local ceph-mgr
191 log files.
192
193 Python log severities are mapped to ceph severities as follows:
194
195 * DEBUG is 20
196 * INFO is 4
197 * WARN is 1
198 * ERR is 0
199
200 Shutting down cleanly
201 ---------------------
202
203 If a module implements the ``serve()`` method, it should also implement
204 the ``shutdown()`` method to shutdown cleanly: misbehaving modules
205 may otherwise prevent clean shutdown of ceph-mgr.
206
207 Is something missing?
208 ---------------------
209
210 The ceph-mgr python interface is not set in stone.  If you have a need
211 that is not satisfied by the current interface, please bring it up
212 on the ceph-devel mailing list.  While it is desired to avoid bloating
213 the interface, it is not generally very hard to expose existing data
214 to the Python code when there is a good reason.
215