oeAware-manager/0003-add-client-error-description-extract-class-and-fix-b.patch
fly_1997 9b1ab30deb fix spec file and some bugs
(cherry picked from commit ca6063d6790f27ef39fb17c5ec7e917c99d83dce)
2024-04-29 20:28:48 +08:00

1035 lines
35 KiB
Diff

From 72ec3921622e81b1faf0adda88cb40aa63bb4504 Mon Sep 17 00:00:00 2001
From: fly_1997 <flylove7@outlook.com>
Date: Sun, 28 Apr 2024 20:13:37 +0800
Subject: [PATCH 3/4] add client error description, extract class, and fix bugs
---
oeAware.service => oeaware.service | 0
src/client/arg_parse.cpp | 104 ++++++++++++++++++
src/client/arg_parse.h | 37 +++++++
src/client/client.cpp | 92 +++-------------
src/client/client.h | 15 ++-
src/client/cmd_handler.cpp | 165 ++++++++++++++++-------------
src/client/cmd_handler.h | 38 +++----
src/client/main.cpp | 10 +-
src/common/utils.cpp | 38 ++++---
src/plugin_mgr/config.cpp | 29 ++++-
src/plugin_mgr/config.h | 27 ++++-
src/plugin_mgr/error_code.cpp | 1 +
src/plugin_mgr/error_code.h | 1 +
src/plugin_mgr/plugin_manager.cpp | 33 +++---
src/plugin_mgr/plugin_manager.h | 4 +-
15 files changed, 363 insertions(+), 231 deletions(-)
rename oeAware.service => oeaware.service (100%)
create mode 100644 src/client/arg_parse.cpp
create mode 100644 src/client/arg_parse.h
diff --git a/oeAware.service b/oeaware.service
similarity index 100%
rename from oeAware.service
rename to oeaware.service
diff --git a/src/client/arg_parse.cpp b/src/client/arg_parse.cpp
new file mode 100644
index 0000000..cbf0b8e
--- /dev/null
+++ b/src/client/arg_parse.cpp
@@ -0,0 +1,104 @@
+/******************************************************************************
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ * oeAware is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ ******************************************************************************/
+#include "arg_parse.h"
+#include <iostream>
+#include <getopt.h>
+
+const std::string ArgParse::OPT_STRING = "Qqd:t:l:r:e:";
+const struct option ArgParse::long_options[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"load", required_argument, NULL, 'l'},
+ {"type", required_argument, NULL, 't'},
+ {"remove", required_argument, NULL, 'r'},
+ {"query", required_argument, NULL, 'q'},
+ {"query-dep", required_argument, NULL, 'Q'},
+ {"enable", required_argument, NULL, 'e'},
+ {"disable", required_argument, NULL, 'd'},
+ {"list", no_argument, NULL, 'L'},
+ {"install", required_argument, NULL, 'i'},
+ {0, 0, 0, 0},
+};
+
+void ArgParse::arg_error(const std::string &msg) {
+ std::cerr << "oeawarectl: " << msg << "\n";
+ exit(EXIT_FAILURE);
+}
+
+void ArgParse::set_type(char *_type) {
+ type = _type;
+}
+
+void ArgParse::set_arg(char *_arg) {
+ arg = std::string(_arg);
+}
+
+void ArgParse::print_help() {
+ std::cout << "oeawarectl [options]...\n"
+ " options\n"
+ " -l|--load [plugin] load plugin and need plugin type.\n"
+ " -t|--type [plugin_type] assign plugin type. there are three types:\n"
+ " collector: collection plugin.\n"
+ " scenario: awareness plugin.\n"
+ " tune: tune plugin.\n"
+ " -r|--remove [plugin] remove plugin from system.\n"
+ " -e|--enable [instance] enable the plugin instance.\n"
+ " -d|--disable [instance] disable the plugin instance.\n"
+ " -q query all plugins information.\n"
+ " --query [plugin] query the plugin information.\n"
+ " -Q query all instances dependencies.\n"
+ " --query-dep [instance] query the instance dependency.\n"
+ " --list the list of supported plugins.\n"
+ " --install [plugin] install plugin from the list.\n"
+ " --help show this help message.\n";
+}
+
+int ArgParse::init(int argc, char *argv[]) {
+ int cmd = -1;
+ int opt;
+ bool help = false;
+ opterr = 0;
+ while((opt = getopt_long(argc, argv, OPT_STRING.c_str(), long_options, nullptr)) != -1) {
+ std::string full_opt;
+ switch (opt) {
+ case 't':
+ set_type(optarg);
+ break;
+ case 'h':
+ help = true;
+ break;
+ case '?':
+ arg_error("unknown option. See --help.");
+ return -1;
+ default: {
+ if (opt == 'l' || opt == 'r' || opt == 'q' || opt == 'Q' || opt == 'e' || opt == 'd' || opt == 'L' || opt == 'i') {
+ if (cmd != -1) {
+ arg_error("invalid option. See --help.\n");
+ return -1;
+ }
+ cmd = opt;
+ if (optarg) {
+ set_arg(optarg);
+ }
+ }
+ }
+
+ }
+ }
+ if (help) {
+ print_help();
+ exit(EXIT_SUCCESS);
+ }
+ if (cmd < 0) {
+ arg_error("no option.");
+ }
+ return cmd;
+}
diff --git a/src/client/arg_parse.h b/src/client/arg_parse.h
new file mode 100644
index 0000000..8535e9c
--- /dev/null
+++ b/src/client/arg_parse.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * Copyright (c) 2024 Huawei Technologies Co., Ltd.
+ * oeAware is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ ******************************************************************************/
+#ifndef CLIENT_ARG_PARSE_H
+#define CLIENT_ARG_PARSE_H
+#include <string>
+
+class ArgParse {
+public:
+ static void arg_error(const std::string &msg);
+ static void print_help();
+ int init(int argc, char *argv[]);
+ void set_type(char* _type);
+ void set_arg(char* _arg);
+ std::string get_type() const {
+ return this->type;
+ }
+ std::string get_arg() const {
+ return this->arg;
+ }
+private:
+ std::string arg;
+ std::string type;
+ static const std::string OPT_STRING;
+ static const int MAX_OPT_SIZE = 20;
+ static const struct option long_options[MAX_OPT_SIZE];
+};
+
+#endif // !CLIENT_ARG_PARSE_H
diff --git a/src/client/client.cpp b/src/client/client.cpp
index 72fb6a2..39a0072 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -11,97 +11,39 @@
******************************************************************************/
#include "client.h"
-const std::string Client::OPT_STRING = "Qqd:t:l:r:e:";
-const struct option Client::long_options[] = {
- {"help", no_argument, NULL, 'h'},
- {"load", required_argument, NULL, 'l'},
- {"type", required_argument, NULL, 't'},
- {"remove", required_argument, NULL, 'r'},
- {"query", required_argument, NULL, 'q'},
- {"query-dep", required_argument, NULL, 'Q'},
- {"enable", required_argument, NULL, 'e'},
- {"disable", required_argument, NULL, 'd'},
- {"list", no_argument, NULL, 'L'},
- {"download", required_argument, NULL, 'D'},
- {0, 0, 0, 0},
-};
-
-static void print_error(const Msg &msg) {
- for (int i = 0; i < msg.payload_size(); ++i) {
- printf("%s\n", msg.payload(i).c_str());
- }
+void Client::cmd_groups_init() {
+ cmd_handler_groups.insert(std::make_pair('l', new LoadHandler()));
+ cmd_handler_groups.insert(std::make_pair('q', new QueryHandler()));
+ cmd_handler_groups.insert(std::make_pair('r', new RemoveHandler()));
+ cmd_handler_groups.insert(std::make_pair('Q', new QueryTopHandler()));
+ cmd_handler_groups.insert(std::make_pair('e', new EnabledHandler()));
+ cmd_handler_groups.insert(std::make_pair('d', new DisabledHandler()));
+ cmd_handler_groups.insert(std::make_pair('L', new ListHandler()));
+ cmd_handler_groups.insert(std::make_pair('i', new InstallHandler(arg_parse.get_arg())));
}
-
-bool Client::init() {
+bool Client::init(int argc, char *argv[]) {
+ if ((cmd = arg_parse.init(argc, argv)) < 0) {
+ return false;
+ }
+ cmd_groups_init();
return this->tcp_socket.init();
}
-void Client::run_cmd(int cmd) {
+void Client::run_cmd() {
Msg msg;
Msg res;
MessageHeader header;
- this->cmd_handler = get_cmd_handler(cmd);
- this->cmd_handler->handler(msg);
+ this->cmd_handler = cmd_handler_groups[cmd];
+ this->cmd_handler->handler(arg_parse, msg);
if(!this->tcp_socket.send_msg(msg)) {
return;
}
if (!this->tcp_socket.recv_msg(res, header)) {
return;
}
- if (header.get_state_code() == HEADER_STATE_FAILED) {
- print_error(res);
- return;
- }
this->cmd_handler->res_handler(res);
}
-int Client::arg_parse(int argc, char *argv[]) {
- int cmd = -1;
- int opt;
- bool help = false;
- opterr = 0;
- while((opt = getopt_long(argc, argv, OPT_STRING.c_str(), long_options, nullptr)) != -1) {
- std::string full_opt;
- switch (opt) {
- case 't':
- set_type(optarg);
- break;
- case 'h':
- help = true;
- break;
- case '?':
- arg_error("unknown option. See --help.");
- return -1;
- default: {
- if (opt == 'l' || opt == 'r' || opt == 'q' || opt == 'Q' || opt == 'e' || opt == 'd' || opt == 'L' || opt == 'D') {
- if (cmd != -1) {
- arg_error("invalid option. See --help.\n");
- return -1;
- }
- cmd = opt;
- if (optarg) {
- set_arg(optarg);
- }
- }
- }
-
- }
- }
- if (help) {
- print_help();
- exit(EXIT_SUCCESS);
- }
- if (cmd < 0) {
- arg_error("no option.");
- }
- return cmd;
-}
-
-void Client::arg_error(const std::string &msg) {
- std::cerr << "oeawarectl: " << msg << "\n";
- exit(EXIT_FAILURE);
-}
-
void Client::close() {
tcp_socket.clear();
}
diff --git a/src/client/client.h b/src/client/client.h
index 9528f13..9e60251 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -13,7 +13,7 @@
#define CLIENT_H
#include "tcp_socket.h"
#include "cmd_handler.h"
-#include <getopt.h>
+#include <unordered_map>
class Client {
public:
@@ -22,18 +22,17 @@ public:
if (cmd_handler)
delete cmd_handler;
}
- bool init();
- void run_cmd(int cmd);
+ bool init(int argc, char *argv[]);
+ void run_cmd();
void close();
- int arg_parse(int argc, char *argv[]);
private:
- void arg_error(const std::string &msg);
+ void cmd_groups_init();
+ int cmd;
TcpSocket tcp_socket;
+ ArgParse arg_parse;
CmdHandler *cmd_handler;
- static const std::string OPT_STRING;
- static const int MAX_OPT_SIZE = 20;
- static const struct option long_options[MAX_OPT_SIZE];
+ std::unordered_map<int, CmdHandler*> cmd_handler_groups;
};
#endif // !CLIENT_H
diff --git a/src/client/cmd_handler.cpp b/src/client/cmd_handler.cpp
index 8cdf8d2..1f2b8a5 100644
--- a/src/client/cmd_handler.cpp
+++ b/src/client/cmd_handler.cpp
@@ -13,42 +13,13 @@
#include "utils.h"
#include <fstream>
-CmdHandler* get_cmd_handler(int cmd) {
- switch (cmd) {
- case 'l':
- return new LoadHandler();
- case 'q':
- return new QueryHandler();
- case 'r':
- return new RemoveHandler();
- case 'Q':
- return new QueryTopHandler();
- case 'e':
- return new EnabledHandler();
- case 'd':
- return new DisabledHandler();
- case 'L':
- return new ListHandler();
- case 'D':
- return new DownloadHandler();
- default:
- return nullptr;
- }
- return nullptr;
-}
-
-void set_type(char *_type) {
- type = _type;
-}
+std::unordered_set<std::string> LoadHandler::types = {"collector", "scenario", "tune"};
-void set_arg(char *_arg) {
- arg = std::string(_arg);
-}
-
-void LoadHandler::handler(Msg &msg) {
- if (type.empty()) {
- printf("plugin type needed!\n");
- exit(EXIT_FAILURE);
+void LoadHandler::handler(const ArgParse &arg_parse, Msg &msg) {
+ std::string arg = arg_parse.get_arg();
+ std::string type = arg_parse.get_type();
+ if (arg.empty() || type.empty() || !types.count(type)) {
+ ArgParse::arg_error("args error.");
}
msg.add_payload(arg);
msg.add_payload(type);
@@ -56,12 +27,24 @@ void LoadHandler::handler(Msg &msg) {
}
void LoadHandler::res_handler(Msg &msg) {
- for (int i = 0; i < msg.payload_size(); ++i) {
- printf("%s\n", msg.payload(i).c_str());
+ if (msg.get_opt() == Opt::RESPONSE_OK) {
+ std::cout << "Plugin loaded successfully.";
+ if (msg.payload_size()) {
+ std::cout << "But plugin requires the following dependencies to run.\n";
+ for (int i = 0; i < msg.payload_size(); ++i) {
+ std::cout << msg.payload(i) << '\n';
+ }
+ } else {
+ std::cout << '\n';
+ }
+ } else {
+ std::cout << "Plugin loaded failed, because "<< msg.payload(0) << ".\n";
}
+
}
-void QueryHandler::handler(Msg &msg) {
+void QueryHandler::handler(const ArgParse &arg_parse, Msg &msg) {
+ std::string arg = arg_parse.get_arg();
if (arg.empty()) {
msg.set_opt(Opt::QUERY_ALL);
} else {
@@ -70,37 +53,57 @@ void QueryHandler::handler(Msg &msg) {
}
}
+void QueryHandler::print_format() {
+ std::cout << "format:\n"
+ "[plugin]\n"
+ "\t[instance]([dependency status], [running status])\n"
+ "dependency status: available means satisfying dependency, otherwise unavailable.\n"
+ "running status: running means that instance is running, otherwise close.\n";
+}
+
void QueryHandler::res_handler(Msg &msg) {
- int len = msg.payload_size();
- if (len == 0) {
- printf("no plugins loaded!\n");
+ if (msg.get_opt() == Opt::RESPONSE_ERROR) {
+ std::cout << "Plugin query failed, because " << msg.payload(0).c_str() <<".\n";
return;
- }
+ }
+ int len = msg.payload_size();
+ std::cout << "Show plugins and instances status.\n";
+ std::cout << "------------------------------------------------------------\n";
for (int i = 0; i < len; ++i) {
- printf("%s\n", msg.payload(i).c_str());
+ std::cout << msg.payload(i).c_str();
}
+ std::cout << "------------------------------------------------------------\n";
+ print_format();
}
-void RemoveHandler::handler(Msg &msg) {
+void RemoveHandler::handler(const ArgParse &arg_parse, Msg &msg) {
+ std::string arg = arg_parse.get_arg();
msg.add_payload(arg);
msg.set_opt(Opt::REMOVE);
}
void RemoveHandler::res_handler(Msg &msg) {
- printf("%s\n", msg.payload(0).c_str());
+ if (msg.get_opt() == Opt::RESPONSE_OK) {
+ std::cout << "plugin remove successful.\n";
+ } else {
+ std::cout << "plugin remove failed, because " << msg.payload(0) << ".\n";
+ }
}
void generate_png_from_dot(const std::string &dot_file, const std::string &png_file) {
std::string command = "dot -Tpng " + dot_file + " -o " + png_file;
std::system(command.c_str());
}
+
void write_to_file(const std::string &file_name, const std::string &text) {
std::ofstream out(file_name);
if (!out.is_open()) return;
out << text;
out.close();
}
-void QueryTopHandler::handler(Msg &msg) {
+
+void QueryTopHandler::handler(const ArgParse &arg_parse, Msg &msg) {
+ std::string arg = arg_parse.get_arg();
if (arg.empty()) {
msg.set_opt(Opt::QUERY_ALL_TOP);
} else {
@@ -110,70 +113,80 @@ void QueryTopHandler::handler(Msg &msg) {
}
void QueryTopHandler::res_handler(Msg &msg) {
- std::string text;
- for(int i = 0; i < msg.payload_size(); ++i) {
- text += msg.payload(i).c_str();
+ if (msg.get_opt() == Opt::RESPONSE_ERROR) {
+ std::cout << "Query instance dependencies failed, because "<< msg.payload(0) << ".\n";
+ return;
}
+ std::string text = msg.payload(0);
write_to_file("dep.dot", text);
generate_png_from_dot("dep.dot", "dep.png");
+ std::cout << "Generate dependencies graph dep.png.\n";
}
-void EnabledHandler::handler(Msg &msg) {
+void EnabledHandler::handler(const ArgParse &arg_parse, Msg &msg) {
+ std::string arg = arg_parse.get_arg();
msg.add_payload(arg);
msg.set_opt(Opt::ENABLED);
}
void EnabledHandler::res_handler(Msg &msg) {
- printf("%s\n", msg.payload(0).c_str());
+ if (msg.get_opt() == Opt::RESPONSE_OK) {
+ std::cout << "instance enabled.\n";
+ } else {
+ std::cout << "instance enabled failed, because "<< msg.payload(0) << ".\n";
+ }
}
-void DisabledHandler::handler(Msg &msg) {
+void DisabledHandler::handler(const ArgParse &arg_parse, Msg &msg) {
+ std::string arg = arg_parse.get_arg();
msg.add_payload(arg);
msg.set_opt(Opt::DISABLED);
}
void DisabledHandler::res_handler(Msg &msg) {
- printf("%s\n", msg.payload(0).c_str());
+ if (msg.get_opt() == Opt::RESPONSE_OK) {
+ std::cout << "instance disabled.\n";
+ } else {
+ std::cout << "instance disabled failed, because "<< msg.payload(0) << ".\n";
+ }
}
-void ListHandler::handler(Msg &msg) {
+void ListHandler::handler(const ArgParse &arg_parse, Msg &msg) {
msg.set_opt(Opt::LIST);
}
void ListHandler::res_handler(Msg &msg) {
+ if (msg.get_opt() == Opt::RESPONSE_ERROR) {
+ std::cerr << "query list failed, because "<< msg.payload(0) << ".\n";
+ return;
+ }
+ std::cout << "plugin list as follows.\n";
+ std::cout << "------------------------------------------------------------\n";
for (int i = 0; i < msg.payload_size(); ++i) {
- printf("%s", msg.payload(i).c_str());
+ std::cout << msg.payload(i);
}
+ std::cout << "------------------------------------------------------------\n";
}
-void DownloadHandler::handler(Msg &msg) {
+void InstallHandler::handler(const ArgParse &arg_parse, Msg &msg) {
+ std::string arg = arg_parse.get_arg();
msg.set_opt(Opt::DOWNLOAD);
msg.add_payload(arg);
}
-void DownloadHandler::res_handler(Msg &msg) {
- std::string path = arg;
+void InstallHandler::res_handler(Msg &msg) {
+ if (msg.get_opt() == Opt::RESPONSE_ERROR) {
+ std::cout << "download failed, because " << msg.payload(0) <<": " << this->arg.c_str() << '\n';
+ return;
+ }
+ std::string path = this->arg;
std::string url = msg.payload(0);
- download(url, path);
+ if (!download(url, path)) {
+ std::cout << "download failed, please check url or your network.\n";
+ return;
+ }
std::string command = "rpm -ivh " + path;
std::string rm = "rm -f " + path;
system(command.c_str());
system(rm.c_str());
}
-
-void print_help() {
- printf("oeAware-client [options]...\n"
- " options\n"
- " -l|--load [plugin] load plugin and need plugin type.\n"
- " -t|--type [plugin_type] assign plugin type.\n"
- " -r|--remove [plugin] remove plugin from system.\n"
- " -e|--enable [instance] enable the plugin instance.\n"
- " -d|--disable [instance] disable the plugin instance.\n"
- " -q query all plugins information.\n"
- " --query [plugin] query the plugin information.\n"
- " -Q query all instances dependencies.\n"
- " --query-dep [instance] query the instance dependency.\n"
- " --list the list of supported plugins.\n"
- " --download [plugin] download plugin from the list.\n"
- );
-}
\ No newline at end of file
diff --git a/src/client/cmd_handler.h b/src/client/cmd_handler.h
index 4afae4c..ab21944 100644
--- a/src/client/cmd_handler.h
+++ b/src/client/cmd_handler.h
@@ -11,72 +11,72 @@
******************************************************************************/
#ifndef CLIENT_CMD_HANDLER_H
#define CLIENT_CMD_HANDLER_H
-
#include "message_protocol.h"
+#include "arg_parse.h"
+#include <unordered_set>
#include <string>
#include <stdio.h>
-static std::string type;
-static std::string arg;
-
class CmdHandler {
public:
- virtual void handler(Msg &msg) = 0;
+ virtual void handler(const ArgParse &arg_parse, Msg &msg) = 0;
virtual void res_handler(Msg &msg) = 0;
+private:
};
class LoadHandler : public CmdHandler {
public:
- void handler(Msg &msg) override;
+ void handler(const ArgParse &arg_parse, Msg &msg) override;
void res_handler(Msg &msg) override;
+private:
+ static std::unordered_set<std::string> types;
};
class QueryHandler : public CmdHandler {
public:
- void handler(Msg &msg) override;
+ void handler(const ArgParse &arg_parse, Msg &msg) override;
void res_handler(Msg &msg) override;
+ void print_format();
};
class RemoveHandler : public CmdHandler {
public:
- void handler(Msg &msg) override;
+ void handler(const ArgParse &arg_parse, Msg &msg) override;
void res_handler(Msg &msg) override;
};
class QueryTopHandler : public CmdHandler {
public:
- void handler(Msg &msg) override;
+ void handler(const ArgParse &arg_parse, Msg &msg) override;
void res_handler(Msg &msg) override;
};
class EnabledHandler : public CmdHandler {
public:
- void handler(Msg &msg) override;
+ void handler(const ArgParse &arg_parse, Msg &msg) override;
void res_handler(Msg &msg) override;
};
class DisabledHandler : public CmdHandler {
public:
- void handler(Msg &msg) override;
+ void handler(const ArgParse &arg_parse, Msg &msg) override;
void res_handler(Msg &msg) override;
};
class ListHandler : public CmdHandler {
public:
- void handler(Msg &msg) override;
+ void handler(const ArgParse &arg_parse, Msg &msg) override;
void res_handler(Msg &msg) override;
};
-class DownloadHandler : public CmdHandler {
+class InstallHandler : public CmdHandler {
public:
- void handler(Msg &msg) override;
+ InstallHandler(const std::string &arg) : arg(arg) { }
+ void handler(const ArgParse &arg_parse, Msg &msg) override;
void res_handler(Msg &msg) override;
+private:
+ std::string arg;
};
-CmdHandler* get_cmd_handler(int cmd);
-void set_type(char* _type);
-void set_arg(char* _arg);
-void print_help();
-
#endif // !CLIENT_CMD_HANDLER_H
diff --git a/src/client/main.cpp b/src/client/main.cpp
index 89aa268..62b7ca5 100644
--- a/src/client/main.cpp
+++ b/src/client/main.cpp
@@ -12,15 +12,11 @@
#include "client.h"
int main(int argc, char *argv[]) {
- int cmd;
Client client;
- if ((cmd = client.arg_parse(argc, argv)) < 0) {
+ if (!client.init(argc, argv)) {
exit(EXIT_FAILURE);
}
- if (!client.init()) {
- exit(EXIT_FAILURE);
- }
- client.run_cmd(cmd);
+ client.run_cmd();
client.close();
return 0;
-}
\ No newline at end of file
+}
diff --git a/src/common/utils.cpp b/src/common/utils.cpp
index 8830c50..9435a5b 100644
--- a/src/common/utils.cpp
+++ b/src/common/utils.cpp
@@ -12,33 +12,39 @@
#include "utils.h"
#include <curl/curl.h>
-static size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
- size_t written = fwrite(ptr, size, nmemb, (FILE*)stream);
- return written;
+static size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *file) {
+ return fwrite(ptr, size, nmemb, file);
}
+// set curl options
+static void curl_set_opt(CURL *curl, const std::string &url, FILE *file) {
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
+
+}
+// Downloads file from the specified url to the path.
bool download(const std::string &url, const std::string &path) {
CURL *curl = nullptr;
CURLcode res;
+ bool ok = true;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
- FILE *fp = fopen(path.c_str(), "wb");
- if (fp == nullptr) {
+ FILE *file = fopen(path.c_str(), "wb");
+ if (file == nullptr) {
return false;
}
- curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
+ curl_set_opt(curl, url, file);
res = curl_easy_perform(curl);
- curl_easy_cleanup(curl);
- fclose(fp);
- if (res == CURLE_OK) {
- return true;
- } else {
- return false;
- }
+ fclose(file);
+ if (res != CURLE_OK) {
+ ok = false;
+ }
+ } else {
+ ok = false;
}
curl_global_cleanup();
- return false;
+ curl_easy_cleanup(curl);
+ return ok;
}
\ No newline at end of file
diff --git a/src/plugin_mgr/config.cpp b/src/plugin_mgr/config.cpp
index b997b8f..1de5a34 100644
--- a/src/plugin_mgr/config.cpp
+++ b/src/plugin_mgr/config.cpp
@@ -14,10 +14,20 @@
#include <iostream>
#include <unistd.h>
-void create_dir(std::string path) {
- if (access(path.c_str(), F_OK) == -1) {
- mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IROTH);
- }
+bool create_dir(const std::string &path) {
+ size_t pos = 0;
+ do {
+ pos = path.find_first_of("/", pos + 1);
+ std::string sub_path = path.substr(0, pos);
+ struct stat buffer;
+ if (stat(sub_path.c_str(), &buffer) == 0) {
+ continue;
+ }
+ if (mkdir(sub_path.c_str(), S_IRWXU | S_IRWXG) != 0) {
+ return false;
+ }
+ } while (pos != std::string::npos);
+ return true;
}
bool Config::load(const std::string path) {
@@ -42,7 +52,16 @@ bool Config::load(const std::string path) {
std::string name = plugin_list[i]["name"].as<std::string>();
std::string description = plugin_list[i]["description"].as<std::string>();
std::string url = plugin_list[i]["url"].as<std::string>();
- this->plugin_list.emplace_back(PluginInfo(name, description, url));
+ PluginInfo info(name, description, url);
+ if (name.empty()) {
+ std::cerr << "Warn: " << name << " url is empty.\n";
+ continue;
+ }
+ if (this->plugin_list.count(name)) {
+ std::cerr << "Warn: duplicate " << name << " in plugin_list.\n";
+ continue;
+ }
+ this->plugin_list.insert(std::make_pair(name, info));
}
} else {
std::cerr << "Error: 'plugin_list' is not a sequence" << '\n';
diff --git a/src/plugin_mgr/config.h b/src/plugin_mgr/config.h
index 2592fbe..16c7871 100644
--- a/src/plugin_mgr/config.h
+++ b/src/plugin_mgr/config.h
@@ -14,6 +14,7 @@
#include "plugin.h"
#include <string>
+#include <unordered_map>
#include <yaml-cpp/yaml.h>
#include <sys/stat.h>
@@ -31,12 +32,24 @@ public:
std::string get_url() const {
return this->url;
}
+ bool operator ==(const PluginInfo &other) const {
+ return name == other.get_name();
+ }
private:
std::string name;
std::string description;
std::string url;
};
+namespace std {
+ template <>
+ struct hash<PluginInfo> {
+ size_t operator ()(const PluginInfo &obj) const {
+ return hash<std::string>()(obj.get_name());
+ }
+ };
+}
+
class EnableItem {
public:
EnableItem(std::string name) : name(name) { }
@@ -79,12 +92,18 @@ public:
std::string get_log_path() const {
return this->log_path;
}
- PluginInfo get_plugin_list(int i) const {
- return this->plugin_list[i];
+ PluginInfo get_plugin_info(const std::string &name) const {
+ return this->plugin_list.at(name);
+ }
+ std::unordered_map<std::string, PluginInfo> get_plugin_list() const {
+ return this->plugin_list;
}
size_t get_plugin_list_size() const {
return this->plugin_list.size();
}
+ bool is_plugin_info_exist(const std::string &name) {
+ return this->plugin_list.count(name);
+ }
EnableItem get_enable_list(int i) const {
return this->enable_list[i];
}
@@ -96,11 +115,11 @@ private:
int schedule_cycle;
std::string log_path;
std::string log_type;
- std::vector<PluginInfo> plugin_list;
+ std::unordered_map<std::string, PluginInfo> plugin_list;
std::vector<EnableItem> enable_list;
};
std::string get_path(PluginType type);
-void create_dir(std::string path);
+bool create_dir(const std::string &path);
#endif
\ No newline at end of file
diff --git a/src/plugin_mgr/error_code.cpp b/src/plugin_mgr/error_code.cpp
index 252e4c2..6e09cb0 100644
--- a/src/plugin_mgr/error_code.cpp
+++ b/src/plugin_mgr/error_code.cpp
@@ -11,6 +11,7 @@ const std::unordered_map<ErrorCode, std::string> ErrorText::error_codes = {
{ErrorCode::REMOVE_INSTANCE_IS_RUNNING, "instance is running"},
{ErrorCode::REMOVE_INSTANCE_HAVE_DEP, "instance with pre-dependency"},
{ErrorCode::LOAD_PLUGIN_FILE_NOT_EXIST, "plugin file does not exist"},
+ {ErrorCode::LOAD_PLUGIN_FILE_IS_NOT_SO, "file is not a plugin file"},
{ErrorCode::LOAD_PLUGIN_FILE_PERMISSION_DEFINED, "plugin file permission defined"},
{ErrorCode::LOAD_PLUGIN_EXIST, "plugin already loaded"},
{ErrorCode::LOAD_PLUGIN_DLOPEN_FAILED, "plugin dlopen failed"},
diff --git a/src/plugin_mgr/error_code.h b/src/plugin_mgr/error_code.h
index f58d5ed..7c06054 100644
--- a/src/plugin_mgr/error_code.h
+++ b/src/plugin_mgr/error_code.h
@@ -15,6 +15,7 @@ enum class ErrorCode {
REMOVE_INSTANCE_HAVE_DEP,
LOAD_PLUGIN_FILE_NOT_EXIST,
LOAD_PLUGIN_FILE_PERMISSION_DEFINED,
+ LOAD_PLUGIN_FILE_IS_NOT_SO,
LOAD_PLUGIN_EXIST,
LOAD_PLUGIN_DLOPEN_FAILED,
LOAD_PLUGIN_DLSYM_FAILED,
diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp
index e7e32bf..c9981ef 100644
--- a/src/plugin_mgr/plugin_manager.cpp
+++ b/src/plugin_mgr/plugin_manager.cpp
@@ -173,11 +173,14 @@ void PluginManager::update_instance_state() {
}
}
-ErrorCode PluginManager::load_plugin(const std::string name, PluginType type) {
+ErrorCode PluginManager::load_plugin(const std::string &name, PluginType type) {
std::string plugin_path = get_path(type) + "/" + name;
if (!file_exist(plugin_path)) {
return ErrorCode::LOAD_PLUGIN_FILE_NOT_EXIST;
}
+ if (!end_with(name, ".so")) {
+ return ErrorCode::LOAD_PLUGIN_FILE_IS_NOT_SO;
+ }
if (!check_permission(plugin_path, S_IRUSR | S_IRGRP)) {
return ErrorCode::LOAD_PLUGIN_FILE_PERMISSION_DEFINED;
}
@@ -285,7 +288,7 @@ ErrorCode PluginManager::instance_disabled(std::string name) {
return ErrorCode::OK;
}
-static bool end_with(const std::string &s, const std::string &ending) {
+bool PluginManager::end_with(const std::string &s, const std::string &ending) {
if (s.length() >= ending.length()) {
return (s.compare(s.length() - ending.length(), ending.length(), ending) == 0);
} else {
@@ -293,7 +296,7 @@ static bool end_with(const std::string &s, const std::string &ending) {
}
}
-static std::string get_plugin_in_dir(const std::string &path) {
+std::string PluginManager::get_plugin_in_dir(const std::string &path) {
std::string res;
struct stat s = {};
lstat(path.c_str(), &s);
@@ -314,10 +317,10 @@ static std::string get_plugin_in_dir(const std::string &path) {
}
ErrorCode PluginManager::add_list(std::string &res) {
- res += "Download Packages:\n";
- for (int i = 0; i < config.get_plugin_list_size(); ++i) {
- PluginInfo info = config.get_plugin_list(i);
- res += info.get_name() + "\n";
+ auto plugin_list = config.get_plugin_list();
+ res += "Supported Packages:\n";
+ for (auto &p : plugin_list) {
+ res += p.first + "\n";
}
res += "Installed Plugins:\n";
res += get_plugin_in_dir(DEFAULT_COLLECTOR_PATH);
@@ -326,20 +329,11 @@ ErrorCode PluginManager::add_list(std::string &res) {
return ErrorCode::OK;
}
-ErrorCode PluginManager::download(const std::string &name, std::string &res) {
- std::string url;
- std::string type;
- for (int i = 0; i < config.get_plugin_list_size(); ++i) {
- PluginInfo info = config.get_plugin_list(i);
- if (info.get_name() == name) {
- url = info.get_url();
- break;
- }
- }
- if (url.empty()) {
+ErrorCode PluginManager::download(const std::string &name, std::string &res) {
+ if (!config.is_plugin_info_exist(name)) {
return ErrorCode::DOWNLOAD_NOT_FOUND;
}
- res += url;
+ res += config.get_plugin_info(name).get_url();
return ErrorCode::OK;
}
@@ -451,7 +445,6 @@ int PluginManager::run() {
case Opt::LOAD: {
std::string plugin_name = msg.get_payload(0);
PluginType type = plugin_types[msg.get_payload(1)];
- if (!end_with(plugin_name, ".so")) break;
ErrorCode ret_code = load_plugin(plugin_name, type);
if(ret_code == ErrorCode::OK) {
INFO("[PluginManager] " << plugin_name << "plugin loaded.");
diff --git a/src/plugin_mgr/plugin_manager.h b/src/plugin_mgr/plugin_manager.h
index 8d240cc..709d42e 100644
--- a/src/plugin_mgr/plugin_manager.h
+++ b/src/plugin_mgr/plugin_manager.h
@@ -36,7 +36,7 @@ public:
void* get_data_buffer(std::string name);
private:
void pre_load_plugin(PluginType type);
- ErrorCode load_plugin(const std::string path, PluginType type);
+ ErrorCode load_plugin(const std::string &path, PluginType type);
ErrorCode remove(const std::string &name);
ErrorCode query_all_plugins(std::string &res);
ErrorCode query_plugin(const std::string &name, std::string &res);
@@ -55,6 +55,8 @@ private:
void batch_load();
void batch_remove();
void update_instance_state();
+ bool end_with(const std::string &s, const std::string &ending);
+ std::string get_plugin_in_dir(const std::string &path);
private:
std::unique_ptr<InstanceRunHandler> instance_run_handler;
Config &config;
--
2.33.0