23 #include <plugins/openprs/aspect/openprs_kernel_manager.h> 24 #include <plugins/openprs/utils/proc.h> 25 #include <plugins/openprs/utils/string.h> 26 #include <logging/logger.h> 27 #include <config/config.h> 28 #include <utils/time/time.h> 29 #include <utils/misc/string_split.h> 31 #include <boost/format.hpp> 58 const std::string &mp_host,
unsigned short mp_tcp_port,
60 : server_host_(server_host), server_port_(server_tcp_port),
61 mp_host_(mp_host), mp_port_(mp_tcp_port)
89 std::list<std::string> &extra_data_path,
bool utils_gdb_delay)
91 if (kernels_.find(kernel_name) != kernels_.end()) {
92 throw Exception(
"OpenPRS kernel '%s' already exists", kernel_name.c_str());
95 std::string
server_port = boost::str(boost::format(
"%u") % server_port_);
96 std::string
mp_port = boost::str(boost::format(
"%u") % mp_port_);
98 const char *argv[] = { use_xoprs ?
"xoprs" :
"oprs",
99 "-s", server_host_.c_str(),
"-i", server_port.c_str(),
100 "-m", mp_host_.c_str(),
"-j", mp_port.c_str(),
102 "-n", kernel_name.c_str(),
105 std::list<std::string> data_path;
107 if (config_->
is_list(
"/openprs/kernels/data-path")) {
108 std::vector<std::string> pl =
109 config_->
get_strings(
"/openprs/kernels/data-path");
110 std::for_each(pl.begin(), pl.end(), [&data_path](std::string &p){ data_path.push_back(p); });
112 std::string cfg_data_path =
113 config_->
get_string(
"/openprs/kernels/data-path");
117 std::list<std::string>::iterator ins_pos = data_path.begin();
118 for (
auto p : extra_data_path) {
119 ins_pos = data_path.insert(ins_pos, p);
121 const std::string env_HOME = getenv(
"HOME");
122 for (
auto &p : data_path) {
123 std::string::size_type pos = 0;
124 while ((pos = p.find(
"$HOME", pos)) != std::string::npos) {
125 p.replace(pos, 5, env_HOME);
126 pos += env_HOME.length();
129 if ((pos = p.find(
"@BASEDIR@")) != std::string::npos) {
130 p.replace(pos, 9, BASEDIR);
132 if ((pos = p.find(
"@FAWKES_BASEDIR@")) != std::string::npos) {
133 p.replace(pos, 16, FAWKES_BASEDIR);
135 if ((pos = p.find(
"@RESDIR@")) != std::string::npos) {
136 p.replace(pos, 8, RESDIR);
138 if ((pos = p.find(
"@CONFDIR@")) != std::string::npos) {
139 p.replace(pos, 9, CONFDIR);
142 std::string oprs_data_path =
str_join(data_path,
':');
144 const char *envp_path_ext[] = {
"LD_LIBRARY_PATH", OPENPRS_MOD_DIR,
145 "OPRS_DATA_PATH", oprs_data_path.c_str(), NULL };
148 envp_v.push_back(boost::str(boost::format(
"FAWKES_OPRS_GDB_DELAY=%s") %
149 (utils_gdb_delay ?
"true" :
"false")));
151 const char *envp[envp_v.size() + 1];
152 for (
unsigned int i = 0; i < envp_v.size(); ++i) {
153 envp[i] = envp_v[i].c_str();
154 if (envp_v[i].find(
"OPRS_DATA_PATH=") == 0) {
155 logger_->
log_info(
"OpenPRSKernelMgr",
"%s data path: %s", kernel_name.c_str(), envp[i]);
158 envp[envp_v.size()] = NULL;
161 logger_->
log_info(
"OpenPRSKernelMgr",
"Running: %s", command.c_str());
163 std::string progname = std::string(use_xoprs ?
"XOPRS" :
"OPRS") +
"-" + kernel_name;
166 std::string oprs_error;
168 oprs =
new SubProcess(progname.c_str(), argv[0], argv, (
const char **)envp, logger_);
178 kernels_[kernel_name] = oprs;
180 throw Exception(
"Failed to initialize OpenPRS kernel '%s' (%s)",
181 kernel_name.c_str(), oprs_error.c_str());
192 if (kernels_.find(kernel_name) != kernels_.end()) {
193 delete kernels_[kernel_name];
194 kernels_.erase(kernel_name);
202 std::list<std::string>
205 std::list<std::string> rv;
206 for (
auto k : kernels_) {
207 rv.push_back(k.first);
OpenPRSKernelManager(const std::string &server_host, unsigned short server_tcp_port, const std::string &mp_host, unsigned short mp_tcp_port, Logger *logger, Clock *clock, Configuration *config)
Constructor.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Fawkes library namespace.
void create_kernel(const std::string &kernel_name, bool use_xoprs, std::list< std::string > &extra_data_path, bool utils_gdb_delay)
Create a new kernel.
This is supposed to be the central clock in Fawkes.
static std::list< std::string > str_split_list(const std::string &s, char delim='/')
Split string by delimiter.
virtual bool is_list(const char *path)=0
Check if a value is a list.
std::list< std::string > kernels() const
Get map of kernels.
void destroy_kernel(const std::string &kernel_name)
Destroy the named kernel.
Base class for exceptions in Fawkes.
std::string command_args_tostring(const char *argv[])
Convert command args to string.
static std::string str_join(const std::vector< std::string > &v, char delim='/')
Join vector of strings string using given delimiter.
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
virtual ~OpenPRSKernelManager()
Destructor.
unsigned short mp_port() const
Get mp-oprs TCP port.
Sub-process execution with stdin/stdout/stderr redirection.
virtual std::vector< std::string > get_strings(const char *path)=0
Get list of values from configuration which is of type string.
std::vector< std::string > envp_copy_expand(char *environ[], const char *path_ext[])
Copy an environment and extend certain paths.
Interface for configuration handling.
unsigned short server_port() const
Get oprs-server TCP port.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.