1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2017 John Spray <john.spray@redhat.com>
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.
20 #include <boost/optional.hpp>
21 #include "common/ceph_mutex.h"
24 #include "mon/MgrMap.h"
29 std::string
handle_pyerror(bool generate_crash_dump
= false,
30 std::string module
= {},
31 std::string caller
= {});
33 std::string
peek_pyerror();
36 * A Ceph CLI command description provided from a Python module
40 std::string cmdstring
;
41 std::string helpstring
;
45 // Call the ActivePyModule of this name to handle the command
46 std::string module_name
;
51 mutable ceph::mutex lock
= ceph::make_mutex("PyModule::lock");
53 const std::string module_name
;
54 std::string
get_site_packages();
55 int load_subclass_of(const char* class_name
, PyObject
** py_class
);
57 // Did the MgrMap identify this module as one that should run?
60 // Did the MgrMap flag this module as always on?
61 bool always_on
= false;
63 // Did we successfully import this python module and look up symbols?
64 // (i.e. is it possible to instantiate a MgrModule subclass instance?)
67 // Did the module identify itself as being able to run?
68 // (i.e. should we expect instantiating and calling serve() to work?)
71 // Did the module encounter an unexpected error while running?
72 // (e.g. throwing an exception from serve())
75 // Populated if loaded, can_run or failed indicates a problem
76 std::string error_string
;
78 // Helper for loading MODULE_OPTIONS and COMMANDS members
80 const std::string
&attr_name
,
81 std::function
<int(PyObject
*)> fn
);
84 std::vector
<ModuleCommand
> commands
;
86 int register_options(PyObject
*cls
);
88 std::map
<std::string
, MgrMap::ModuleOption
> options
;
90 int load_notify_types();
91 std::set
<std::string
> notify_types
;
94 static std::string mgr_store_prefix
;
96 SafeThreadState pMyThreadState
;
97 PyObject
*pClass
= nullptr;
98 PyObject
*pStandbyClass
= nullptr;
100 explicit PyModule(const std::string
&module_name_
)
101 : module_name(module_name_
)
107 bool is_option(const std::string
&option_name
);
108 const std::map
<std::string
,MgrMap::ModuleOption
>& get_options() const {
112 PyObject
*get_typed_option_value(
113 const std::string
& option
,
114 const std::string
& value
);
116 int load(PyThreadState
*pMainThreadState
);
117 static PyObject
* init_ceph_logger();
118 static PyObject
* init_ceph_module();
120 void set_enabled(const bool enabled_
)
125 void set_always_on(const bool always_on_
) {
126 always_on
= always_on_
;
130 * Extend `out` with the contents of `this->commands`
132 void get_commands(std::vector
<ModuleCommand
> *out
) const
134 std::lock_guard
l(lock
);
135 ceph_assert(out
!= nullptr);
136 out
->insert(out
->end(), commands
.begin(), commands
.end());
141 * Mark the module as failed, recording the reason in the error
144 void fail(const std::string
&reason
)
146 std::lock_guard
l(lock
);
148 error_string
= reason
;
151 bool is_enabled() const {
152 std::lock_guard
l(lock
);
153 return enabled
|| always_on
;
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
; }
160 bool should_notify(const std::string
& notify_type
) const {
161 return notify_types
.count(notify_type
);
164 const std::string
&get_name() const {
165 std::lock_guard
l(lock
) ; return module_name
;
167 const std::string
&get_error_string() const {
168 std::lock_guard
l(lock
) ; return error_string
;
170 bool get_can_run() const {
171 std::lock_guard
l(lock
) ; return can_run
;
175 typedef std::shared_ptr
<PyModule
> PyModuleRef
;
177 class PyModuleConfig
{
179 mutable ceph::mutex lock
= ceph::make_mutex("PyModuleConfig::lock");
180 std::map
<std::string
, std::string
> config
;
184 PyModuleConfig(PyModuleConfig
&mconfig
);
188 std::pair
<int, std::string
> set_config(
190 const std::string
&module_name
,
191 const std::string
&key
, const std::optional
<std::string
>& val
);