1035 lines
35 KiB
Diff
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
|
|
|