]> git.proxmox.com Git - ceph.git/blame - ceph/src/mgr/BaseMgrStandbyModule.cc
import ceph quincy 17.2.4
[ceph.git] / ceph / src / mgr / BaseMgrStandbyModule.cc
CommitLineData
3efd9988
FG
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) 2016 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#include "BaseMgrStandbyModule.h"
16
17#include "StandbyPyModules.h"
b3b6e05e 18#include "PyFormatter.h"
3efd9988
FG
19
20
21#define dout_context g_ceph_context
22#define dout_subsys ceph_subsys_mgr
23
20effc67
TL
24using std::string;
25
3efd9988
FG
26typedef struct {
27 PyObject_HEAD
28 StandbyPyModule *this_module;
29} BaseMgrStandbyModule;
30
31static PyObject *
32BaseMgrStandbyModule_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
33{
34 BaseMgrStandbyModule *self;
35
36 self = (BaseMgrStandbyModule *)type->tp_alloc(type, 0);
37
38 return (PyObject *)self;
39}
40
41static int
42BaseMgrStandbyModule_init(BaseMgrStandbyModule *self, PyObject *args, PyObject *kwds)
43{
44 PyObject *this_module_capsule = nullptr;
45 static const char *kwlist[] = {"this_module", NULL};
46
47 if (! PyArg_ParseTupleAndKeywords(args, kwds, "O",
48 const_cast<char**>(kwlist),
49 &this_module_capsule)) {
50 return -1;
51 }
52
11fdf7f2
TL
53 self->this_module = static_cast<StandbyPyModule*>(PyCapsule_GetPointer(
54 this_module_capsule, nullptr));
55 ceph_assert(self->this_module);
3efd9988
FG
56
57 return 0;
58}
59
60static PyObject*
61ceph_get_mgr_id(BaseMgrStandbyModule *self, PyObject *args)
62{
9f95a23c 63 return PyUnicode_FromString(g_conf()->name.get_id().c_str());
3efd9988
FG
64}
65
66static PyObject*
11fdf7f2 67ceph_get_module_option(BaseMgrStandbyModule *self, PyObject *args)
3efd9988
FG
68{
69 char *what = nullptr;
11fdf7f2
TL
70 char *prefix = nullptr;
71 if (!PyArg_ParseTuple(args, "s|s:ceph_get_module_option", &what, &prefix)) {
72 derr << "Invalid args!" << dendl;
73 return nullptr;
74 }
eafe8130 75 PyThreadState *tstate = PyEval_SaveThread();
11fdf7f2
TL
76 std::string final_key;
77 std::string value;
78 bool found = false;
79 if (prefix) {
80 final_key = std::string(prefix) + "/" + what;
81 found = self->this_module->get_config(final_key, &value);
82 }
83 if (!found) {
84 final_key = what;
85 found = self->this_module->get_config(final_key, &value);
86 }
eafe8130 87 PyEval_RestoreThread(tstate);
11fdf7f2
TL
88 if (found) {
89 dout(10) << __func__ << " " << final_key << " found: " << value
90 << dendl;
91 return self->this_module->py_module->get_typed_option_value(what, value);
92 } else {
93 if (prefix) {
94 dout(4) << __func__ << " [" << prefix << "/]" << what << " not found "
95 << dendl;
96 } else {
97 dout(4) << __func__ << " " << what << " not found " << dendl;
98 }
99 Py_RETURN_NONE;
100 }
101}
102
103static PyObject*
104ceph_option_get(BaseMgrStandbyModule *self, PyObject *args)
105{
106 char *what = nullptr;
107 if (!PyArg_ParseTuple(args, "s:ceph_option_get", &what)) {
3efd9988
FG
108 derr << "Invalid args!" << dendl;
109 return nullptr;
110 }
111
112 std::string value;
11fdf7f2
TL
113 int r = g_conf().get_val(string(what), &value);
114 if (r >= 0) {
115 dout(10) << "ceph_option_get " << what << " found: " << value << dendl;
9f95a23c 116 return PyUnicode_FromString(value.c_str());
11fdf7f2
TL
117 } else {
118 dout(4) << "ceph_option_get " << what << " not found " << dendl;
119 Py_RETURN_NONE;
120 }
121}
122
123static PyObject*
124ceph_store_get(BaseMgrStandbyModule *self, PyObject *args)
125{
126 char *what = nullptr;
127 if (!PyArg_ParseTuple(args, "s:ceph_store_get", &what)) {
128 derr << "Invalid args!" << dendl;
129 return nullptr;
130 }
131
132 // Drop GIL for blocking mon command execution
133 PyThreadState *tstate = PyEval_SaveThread();
134
135 std::string value;
136 bool found = self->this_module->get_store(what, &value);
137
138 PyEval_RestoreThread(tstate);
139
3efd9988 140 if (found) {
11fdf7f2 141 dout(10) << "ceph_store_get " << what << " found: " << value.c_str() << dendl;
9f95a23c 142 return PyUnicode_FromString(value.c_str());
3efd9988 143 } else {
11fdf7f2 144 dout(4) << "ceph_store_get " << what << " not found " << dendl;
3efd9988
FG
145 Py_RETURN_NONE;
146 }
147}
148
149static PyObject*
150ceph_get_active_uri(BaseMgrStandbyModule *self, PyObject *args)
151{
9f95a23c 152 return PyUnicode_FromString(self->this_module->get_active_uri().c_str());
3efd9988
FG
153}
154
155static PyObject*
156ceph_log(BaseMgrStandbyModule *self, PyObject *args)
157{
3efd9988 158 char *record = nullptr;
9f95a23c 159 if (!PyArg_ParseTuple(args, "s:log", &record)) {
3efd9988
FG
160 return nullptr;
161 }
162
11fdf7f2 163 ceph_assert(self->this_module);
3efd9988 164
9f95a23c 165 self->this_module->log(record);
3efd9988
FG
166
167 Py_RETURN_NONE;
168}
169
b3b6e05e
TL
170static PyObject*
171ceph_standby_state_get(BaseMgrStandbyModule *self, PyObject *args)
172{
173 char *whatc = NULL;
174 if (!PyArg_ParseTuple(args, "s:ceph_state_get", &whatc)) {
175 return NULL;
176 }
177 std::string what(whatc);
178
179 PyFormatter f;
180
181 // Drop the GIL, as most of the following blocks will block on
182 // a mutex -- they are all responsible for re-taking the GIL before
183 // touching the PyFormatter instance or returning from the function.
184 without_gil_t no_gil;
185
186 if (what == "mgr_ips") {
187 entity_addrvec_t myaddrs = self->this_module->get_myaddrs();
188 with_gil_t with_gil{no_gil};
189 f.open_array_section("ips");
190 std::set<std::string> did;
191 for (auto& i : myaddrs.v) {
192 std::string ip = i.ip_only_to_str();
193 if (auto [where, inserted] = did.insert(ip); inserted) {
194 f.dump_string("ip", ip);
195 }
196 }
197 f.close_section();
198 return f.get();
199 } else {
200 derr << "Python module requested unknown data '" << what << "'" << dendl;
201 with_gil_t with_gil{no_gil};
202 Py_RETURN_NONE;
203 }
204}
205
206
3efd9988 207PyMethodDef BaseMgrStandbyModule_methods[] = {
b3b6e05e
TL
208 {"_ceph_get", (PyCFunction)ceph_standby_state_get, METH_VARARGS,
209 "Get a cluster object (standby)"},
3efd9988
FG
210
211 {"_ceph_get_mgr_id", (PyCFunction)ceph_get_mgr_id, METH_NOARGS,
212 "Get the name of the Mgr daemon where we are running"},
213
11fdf7f2
TL
214 {"_ceph_get_module_option", (PyCFunction)ceph_get_module_option, METH_VARARGS,
215 "Get a module configuration option value"},
216
217 {"_ceph_get_option", (PyCFunction)ceph_option_get, METH_VARARGS,
218 "Get a native configuration option value"},
219
220 {"_ceph_get_store", (PyCFunction)ceph_store_get, METH_VARARGS,
221 "Get a KV store value"},
3efd9988
FG
222
223 {"_ceph_get_active_uri", (PyCFunction)ceph_get_active_uri, METH_NOARGS,
224 "Get the URI of the active instance of this module, if any"},
225
226 {"_ceph_log", (PyCFunction)ceph_log, METH_VARARGS,
227 "Emit a log message"},
228
229 {NULL, NULL, 0, NULL}
230};
231
232PyTypeObject BaseMgrStandbyModuleType = {
233 PyVarObject_HEAD_INIT(NULL, 0)
234 "ceph_module.BaseMgrStandbyModule", /* tp_name */
235 sizeof(BaseMgrStandbyModule), /* tp_basicsize */
236 0, /* tp_itemsize */
237 0, /* tp_dealloc */
238 0, /* tp_print */
239 0, /* tp_getattr */
240 0, /* tp_setattr */
241 0, /* tp_compare */
242 0, /* tp_repr */
243 0, /* tp_as_number */
244 0, /* tp_as_sequence */
245 0, /* tp_as_mapping */
246 0, /* tp_hash */
247 0, /* tp_call */
248 0, /* tp_str */
249 0, /* tp_getattro */
250 0, /* tp_setattro */
251 0, /* tp_as_buffer */
252 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
253 "ceph-mgr Standby Python Plugin", /* tp_doc */
254 0, /* tp_traverse */
255 0, /* tp_clear */
256 0, /* tp_richcompare */
257 0, /* tp_weaklistoffset */
258 0, /* tp_iter */
259 0, /* tp_iternext */
260 BaseMgrStandbyModule_methods, /* tp_methods */
261 0, /* tp_members */
262 0, /* tp_getset */
263 0, /* tp_base */
264 0, /* tp_dict */
265 0, /* tp_descr_get */
266 0, /* tp_descr_set */
267 0, /* tp_dictoffset */
268 (initproc)BaseMgrStandbyModule_init, /* tp_init */
269 0, /* tp_alloc */
270 BaseMgrStandbyModule_new, /* tp_new */
271};