]> git.proxmox.com Git - ceph.git/blame - ceph/src/mgr/PyModule.h
bump version to 15.2.11-pve1
[ceph.git] / ceph / src / mgr / PyModule.h
CommitLineData
11fdf7f2
TL
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#pragma once
15
16#include <map>
17#include <memory>
18#include <string>
19#include <vector>
20#include <boost/optional.hpp>
9f95a23c 21#include "common/ceph_mutex.h"
11fdf7f2
TL
22#include "Python.h"
23#include "Gil.h"
24#include "mon/MgrMap.h"
25
26
27class MonClient;
28
29std::string handle_pyerror();
30
31std::string peek_pyerror();
32
33/**
34 * A Ceph CLI command description provided from a Python module
35 */
36class ModuleCommand {
37public:
38 std::string cmdstring;
39 std::string helpstring;
40 std::string perm;
41 bool polling;
42
43 // Call the ActivePyModule of this name to handle the command
44 std::string module_name;
45};
46
47class PyModule
48{
9f95a23c 49 mutable ceph::mutex lock = ceph::make_mutex("PyModule::lock");
11fdf7f2
TL
50private:
51 const std::string module_name;
52 std::string get_site_packages();
53 int load_subclass_of(const char* class_name, PyObject** py_class);
54
55 // Did the MgrMap identify this module as one that should run?
56 bool enabled = false;
57
58 // Did the MgrMap flag this module as always on?
59 bool always_on = false;
60
61 // Did we successfully import this python module and look up symbols?
62 // (i.e. is it possible to instantiate a MgrModule subclass instance?)
63 bool loaded = false;
64
65 // Did the module identify itself as being able to run?
66 // (i.e. should we expect instantiating and calling serve() to work?)
67 bool can_run = false;
68
69 // Did the module encounter an unexpected error while running?
70 // (e.g. throwing an exception from serve())
71 bool failed = false;
72
73 // Populated if loaded, can_run or failed indicates a problem
74 std::string error_string;
75
76 // Helper for loading MODULE_OPTIONS and COMMANDS members
77 int walk_dict_list(
78 const std::string &attr_name,
79 std::function<int(PyObject*)> fn);
80
81 int load_commands();
82 std::vector<ModuleCommand> commands;
83
9f95a23c 84 int register_options(PyObject *cls);
11fdf7f2
TL
85 int load_options();
86 std::map<std::string, MgrMap::ModuleOption> options;
87
88public:
89 static std::string config_prefix;
90
91 SafeThreadState pMyThreadState;
92 PyObject *pClass = nullptr;
93 PyObject *pStandbyClass = nullptr;
94
95 explicit PyModule(const std::string &module_name_)
96 : module_name(module_name_)
97 {
98 }
99
100 ~PyModule();
101
102 bool is_option(const std::string &option_name);
103 const std::map<std::string,MgrMap::ModuleOption>& get_options() const {
104 return options;
105 }
106
107 PyObject *get_typed_option_value(
108 const std::string& option,
109 const std::string& value);
110
111 int load(PyThreadState *pMainThreadState);
112#if PY_MAJOR_VERSION >= 3
113 static PyObject* init_ceph_logger();
114 static PyObject* init_ceph_module();
115#else
116 static void init_ceph_logger();
117 static void init_ceph_module();
118#endif
119
120 void set_enabled(const bool enabled_)
121 {
122 enabled = enabled_;
123 }
124
125 void set_always_on(const bool always_on_) {
126 always_on = always_on_;
127 }
128
129 /**
130 * Extend `out` with the contents of `this->commands`
131 */
132 void get_commands(std::vector<ModuleCommand> *out) const
133 {
134 std::lock_guard l(lock);
135 ceph_assert(out != nullptr);
136 out->insert(out->end(), commands.begin(), commands.end());
137 }
138
139
140 /**
141 * Mark the module as failed, recording the reason in the error
142 * string.
143 */
144 void fail(const std::string &reason)
145 {
146 std::lock_guard l(lock);
147 failed = true;
148 error_string = reason;
149 }
150
151 bool is_enabled() const {
152 std::lock_guard l(lock);
153 return enabled || always_on;
154 }
155
156 bool is_failed() const { std::lock_guard l(lock) ; return failed; }
157 bool is_loaded() const { std::lock_guard l(lock) ; return loaded; }
158 bool is_always_on() const { std::lock_guard l(lock) ; return always_on; }
159
160 const std::string &get_name() const {
161 std::lock_guard l(lock) ; return module_name;
162 }
163 const std::string &get_error_string() const {
164 std::lock_guard l(lock) ; return error_string;
165 }
166 bool get_can_run() const {
167 std::lock_guard l(lock) ; return can_run;
168 }
169};
170
171typedef std::shared_ptr<PyModule> PyModuleRef;
172
173class PyModuleConfig {
174public:
9f95a23c 175 mutable ceph::mutex lock = ceph::make_mutex("PyModuleConfig::lock");
11fdf7f2
TL
176 std::map<std::string, std::string> config;
177
178 PyModuleConfig();
179
180 PyModuleConfig(PyModuleConfig &mconfig);
181
182 ~PyModuleConfig();
183
184 void set_config(
185 MonClient *monc,
186 const std::string &module_name,
187 const std::string &key, const boost::optional<std::string>& val);
188
189};