From: Waldemar Kozaczuk <jwkozac...@gmail.com> Committer: Waldemar Kozaczuk <jwkozac...@gmail.com> Branch: master
httpserver: allow compiling out features not needed for monitoring api This patch modifies httpserver-api source code to add pre-processor conditionals - "#if !defined(MONITORING)" - to disable fragments of code that are not needed for monitoring api. More specifically it disables all non-GET routes (with exception of trace API) and YAML file-based configuration. It also disables SSL. All of which is done to allow creating minimal "read-only" version of httpserver API intended for monitoring purposes only. Finally it also explicitly makes only certains symbols (like "main") public by using compiler directives like "__attribute__((visibility("default")))" and "#pragma GCC visibility push(default)/#pragma GCC visibility pop". The latter is used to make portion of common code public so that is available to modules like trace API. Hiding most symbols in monitoring module also helps to reduce its size. Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com> --- diff --git a/modules/httpserver-api/api/api.cc b/modules/httpserver-api/api/api.cc --- a/modules/httpserver-api/api/api.cc +++ b/modules/httpserver-api/api/api.cc @@ -240,19 +240,23 @@ class api_param_handler : public handler_base { routes& _routes; }; +#if !defined(MONITORING) extern "C" void httpserver_plugin_register_routes(httpserver::routes* routes) { httpserver::api::api::init(*routes); } +#endif void init(routes& routes) { api_json_init_path("Advanced API options"); api_batch.set_handler(new api_param_handler(routes)); +#if !defined(MONITORING) stop_api.set_handler([](const_req req){ global_server::stop(); return ""; }); +#endif } diff --git a/modules/httpserver-api/api/env.cc b/modules/httpserver-api/api/env.cc --- a/modules/httpserver-api/api/env.cc +++ b/modules/httpserver-api/api/env.cc @@ -20,9 +20,11 @@ using namespace json; using namespace std; using namespace env_json; +#if !defined(MONITORING) extern "C" void httpserver_plugin_register_routes(httpserver::routes* routes) { httpserver::api::env::init(*routes); } +#endif void init(routes& routes) { @@ -46,6 +48,7 @@ void init(routes& routes) return res; }); +#if !defined(MONITORING) setEnv.set_handler([](const_req req) { string param = req.param.at("var").substr(1); if (setenv(param.c_str(), @@ -62,7 +65,7 @@ void init(routes& routes) } return ""; }); - +#endif } } diff --git a/modules/httpserver-api/api/file.cc b/modules/httpserver-api/api/file.cc --- a/modules/httpserver-api/api/file.cc +++ b/modules/httpserver-api/api/file.cc @@ -98,6 +98,7 @@ static string file_name(const string& path) return path.substr(found + 1); } +#if !defined(MONITORING) /** * Generate a temporary file name in a target directory * according to a file name @@ -152,6 +153,7 @@ static void copy(const std::string& from, const std::string& to) + e.code().message()); } } +#endif class get_file_handler : public file_interaction_handler { virtual void handle(const std::string& path, parameters* params, @@ -318,6 +320,7 @@ class get_file_handler : public file_interaction_handler { } }; +#if !defined(MONITORING) class del_file_handler : public handler_base { virtual void handle(const std::string& path, parameters* params, const http::server::request& req, http::server::reply& rep) @@ -442,18 +445,23 @@ class put_file_handler : public handler_base { set_headers(rep, "json"); } }; +#endif +#if !defined(MONITORING) extern "C" void httpserver_plugin_register_routes(httpserver::routes* routes) { httpserver::api::file::init(*routes); } +#endif void init(routes& routes) { file_json_init_path("file API"); getFile.set_handler(new get_file_handler()); +#if !defined(MONITORING) delFile.set_handler(new del_file_handler()); putFile.set_handler(new put_file_handler()); upload.set_handler(new post_file_handler()); +#endif } } diff --git a/modules/httpserver-api/api/fs.cc b/modules/httpserver-api/api/fs.cc --- a/modules/httpserver-api/api/fs.cc +++ b/modules/httpserver-api/api/fs.cc @@ -33,9 +33,11 @@ static void fill_dfstat(DFStat& dfstat, const osv::mount_desc& mount, const stru dfstat.blocksize = st.f_frsize; } +#if !defined(MONITORING) extern "C" void httpserver_plugin_register_routes(httpserver::routes* routes) { httpserver::api::fs::init(*routes); } +#endif void init(routes& routes) { diff --git a/modules/httpserver-api/api/hardware.cc b/modules/httpserver-api/api/hardware.cc --- a/modules/httpserver-api/api/hardware.cc +++ b/modules/httpserver-api/api/hardware.cc @@ -24,9 +24,11 @@ using namespace std; using namespace json; using namespace hardware_json; +#if !defined(MONITORING) extern "C" void httpserver_plugin_register_routes(httpserver::routes* routes) { httpserver::api::hardware::init(*routes); } +#endif void init(routes& routes) { diff --git a/modules/httpserver-api/api/network.cc b/modules/httpserver-api/api/network.cc --- a/modules/httpserver-api/api/network.cc +++ b/modules/httpserver-api/api/network.cc @@ -30,7 +30,6 @@ static Interface get_interface(const string& name, ifnet* ifp, long time) Interface f; interface intf(name); - if_data cur_data = { 0 }; if (!set_interface_info(ifp, cur_data, intf)) { throw server_error_exception("Failed getting interface information"); @@ -43,9 +42,11 @@ static Interface get_interface(const string& name, ifnet* ifp, long time) return f; } +#if !defined(MONITORING) extern "C" void httpserver_plugin_register_routes(httpserver::routes* routes) { httpserver::api::network::init(*routes); } +#endif /** * Initialize the routes object with specific routes mapping diff --git a/modules/httpserver-api/api/os.cc b/modules/httpserver-api/api/os.cc --- a/modules/httpserver-api/api/os.cc +++ b/modules/httpserver-api/api/os.cc @@ -33,9 +33,11 @@ using namespace std; using namespace json; using namespace os_json; +#if !defined(MONITORING) extern "C" void httpserver_plugin_register_routes(httpserver::routes* routes) { httpserver::api::os::init(*routes); } +#endif void init(routes& routes) { @@ -83,6 +85,7 @@ void init(routes& routes) return memory::get_balloon_size(); }); +#if !defined(MONITORING) os_shutdown.set_handler([](const_req req) { osv::shutdown(); return ""; @@ -97,6 +100,7 @@ void init(routes& routes) osv::reboot(); return ""; }); +#endif os_dmesg.set_handler([](const_req req) { return debug_buffer; @@ -109,11 +113,13 @@ void init(routes& routes) return json_return_type(hostname); }); +#if !defined(MONITORING) os_set_hostname.set_handler([](const_req req) { string hostname = req.get_query_param("name"); sethostname(hostname.c_str(), hostname.size()); return ""; }); +#endif os_threads.set_handler([](const_req req) { using namespace std::chrono; @@ -143,6 +149,7 @@ void init(routes& routes) return osv::getcmdline(); }); +#if !defined(MONITORING) os_set_cmdline.set_handler([](const_req req) { string newcmd = req.get_query_param("cmdline"); @@ -157,6 +164,7 @@ void init(routes& routes) return osv::getcmdline(); }); +#endif } diff --git a/modules/httpserver-api/api/trace.cc b/modules/httpserver-api/api/trace.cc --- a/modules/httpserver-api/api/trace.cc +++ b/modules/httpserver-api/api/trace.cc @@ -25,7 +25,7 @@ using namespace httpserver::json::trace_json; static std::unordered_map<tracepoint_base*, std::unique_ptr<tracepoint_counter>> counters; -extern "C" void httpserver_plugin_register_routes(httpserver::routes* routes) { +extern "C" void __attribute__((visibility("default"))) httpserver_plugin_register_routes(httpserver::routes* routes) { httpserver::api::trace::init(*routes); } diff --git a/modules/httpserver-api/global_server.cc b/modules/httpserver-api/global_server.cc --- a/modules/httpserver-api/global_server.cc +++ b/modules/httpserver-api/global_server.cc @@ -13,11 +13,21 @@ #include <dlfcn.h> #include <boost/filesystem.hpp> #include <boost/foreach.hpp> -#include "yaml-cpp/yaml.h" #include "json/api_docs.hh" #include <osv/debug.h> #include "transformers.hh" #include <osv/options.hh> +#if !defined(MONITORING) +#include "yaml-cpp/yaml.h" +#else +#include "api/os.hh" +#include "api/fs.hh" +#include "api/file.hh" +#include "api/network.hh" +#include "api/hardware.hh" +#include "api/api.hh" +#include "api/env.hh" +#endif namespace httpserver { @@ -36,6 +46,7 @@ bool global_server::run(std::map<std::string,std::vector<std::string>>& _config) if (get().s != nullptr) { return false; } +#if !defined(MONITORING) std::string config_file_path = "/tmp/httpserver.conf"; if (options::option_value_exists(_config, "config-file")) { config_file_path = options::extract_option_value(_config, "config-file"); @@ -79,16 +90,19 @@ bool global_server::run(std::map<std::string,std::vector<std::string>>& _config) throw e; } } +#endif set(_config); get().set("ipaddress", "0.0.0.0"); get().set("port", "8000"); +#if !defined(MONITORING) if (get().config.count("ssl")) { get().set("cert", "/etc/pki/server.pem"); get().set("key", "/etc/pki/private/server.key"); get().set("cacert", "/etc/pki/CA/cacert.pem"); } +#endif auto port = get().config["port"][0]; get().s = new http::server::server(get().config, &get()._routes); @@ -105,6 +119,7 @@ bool global_server::run(std::map<std::string,std::vector<std::string>>& _config) return true; } +#if !defined(MONITORING) void global_server::setup_file_mappings(const YAML::Node& file_mappings_node) { for (auto node : file_mappings_node) { const YAML::Node path = node["path"]; @@ -154,6 +169,7 @@ void global_server::setup_redirects(const YAML::Node& redirects_node) { } } } +#endif global_server::global_server() : s(nullptr) @@ -182,7 +198,15 @@ void global_server::set_routes() { path_holder::set_routes(&_routes); json::api_doc_init(_routes); - +#if defined(MONITORING) + httpserver::api::api::init(_routes); + httpserver::api::fs::init(_routes); + httpserver::api::os::init(_routes); + httpserver::api::network::init(_routes); + httpserver::api::hardware::init(_routes); + httpserver::api::env::init(_routes); + httpserver::api::file::init(_routes); +#endif { namespace fs = boost::filesystem; fs::path plugin_path("/usr/mgmt/plugins/"); diff --git a/modules/httpserver-api/global_server.hh b/modules/httpserver-api/global_server.hh --- a/modules/httpserver-api/global_server.hh +++ b/modules/httpserver-api/global_server.hh @@ -12,7 +12,9 @@ #include <vector> #include <mutex> #include <condition_variable> +#if !defined(MONITORING) #include <yaml-cpp/node/iterator.h> +#endif namespace httpserver { /** @@ -64,8 +66,10 @@ private: global_server(); void set_routes(); +#if !defined(MONITORING) void setup_redirects(const YAML::Node& node); void setup_file_mappings(const YAML::Node& node); +#endif void load_plugin(const std::string& path); static global_server* instance; routes _routes; diff --git a/modules/httpserver-api/handlers.cc b/modules/httpserver-api/handlers.cc --- a/modules/httpserver-api/handlers.cc +++ b/modules/httpserver-api/handlers.cc @@ -19,6 +19,7 @@ const std::string handler_base::ERROR_500_PAGE("<h1>Something went wrong</h1>"); const std::string handler_base::ERROR_404_PAGE( "<h1>We didn't find the page you were looking for</h1>"); +#pragma GCC visibility push(default) void handler_base::set_headers_explicit(http::server::reply& rep, const std::string& mime) { const int contentLength = rep.content.size(); @@ -53,6 +54,7 @@ void handler_base::reply500(http::server::reply& rep, const std::string& alterna rep = http::server::reply::stock_reply(http::server::reply::internal_server_error, &alternative_message); } +#pragma GCC visibility pop directory_handler::directory_handler(const string& doc_root, file_transformer* transformer) @@ -76,6 +78,7 @@ void directory_handler::handle(const string& path, parameters* parts, read(full_path, req, rep); } +#pragma GCC visibility push(default) file_interaction_handler::~file_interaction_handler() { delete transformer; @@ -128,6 +131,7 @@ bool file_interaction_handler::redirect_if_needed( } return false; } +#pragma GCC visibility pop void file_handler::handle(const string& path, parameters* parts, const http::server::request& req, http::server::reply& rep) diff --git a/modules/httpserver-api/handlers.hh b/modules/httpserver-api/handlers.hh --- a/modules/httpserver-api/handlers.hh +++ b/modules/httpserver-api/handlers.hh @@ -32,6 +32,7 @@ typedef const http::server::request& const_req; * file_handler - map a url path to a file * function_handler - uses a lambda expression to handle a reqeust */ +#pragma GCC visibility push(default) class handler_base { public: /** @@ -90,7 +91,7 @@ public: virtual void reply500(http::server::reply& rep, const std::string& alternative_message = ERROR_500_PAGE); - /** + /** * Add a mandatory parameter * @param param a parameter name * @return a reference to the handler @@ -107,6 +108,7 @@ public: std::vector<std::string> mandatory_param; }; +#pragma GCC visibility pop /** * This is a base class for file transformer. @@ -132,6 +134,7 @@ public: virtual ~file_transformer() = default; }; +#pragma GCC visibility push(default) /** * A base class for handlers that interact with files. * directory and file handlers both share some common logic @@ -188,6 +191,7 @@ protected: http::server::reply& rep); file_transformer* transformer; }; +#pragma GCC visibility pop /** * The directory handler get a disk path in the diff --git a/modules/httpserver-api/json/api_docs.cc b/modules/httpserver-api/json/api_docs.cc --- a/modules/httpserver-api/json/api_docs.cc +++ b/modules/httpserver-api/json/api_docs.cc @@ -43,9 +43,11 @@ class api_registry : public handler_base { const string api_registry::base_path = "/api-doc"; static api_registry* registry = nullptr; +#pragma GCC visibility push(default) void register_api(const std::string& api, const std::string& description) { registry->reg(api, description); } +#pragma GCC visibility pop void api_doc_init(routes& _routes) { registry = new api_registry(_routes); diff --git a/modules/httpserver-api/json/api_docs.hh b/modules/httpserver-api/json/api_docs.hh --- a/modules/httpserver-api/json/api_docs.hh +++ b/modules/httpserver-api/json/api_docs.hh @@ -87,8 +87,10 @@ struct api_docs : public json::json_base { } }; +#pragma GCC visibility push(default) void register_api(const std::string& api, const std::string& description); +#pragma GCC visibility pop /** * Initialize the routes object with specific routes mapping diff --git a/modules/httpserver-api/json/formatter.cc b/modules/httpserver-api/json/formatter.cc --- a/modules/httpserver-api/json/formatter.cc +++ b/modules/httpserver-api/json/formatter.cc @@ -13,6 +13,7 @@ using namespace std; +#pragma GCC visibility push(default) namespace httpserver { namespace json { @@ -97,3 +98,4 @@ std::string formatter::json_escape_UTF8_string(const std::string& utf8_string) { } } +#pragma GCC visibility pop diff --git a/modules/httpserver-api/json/formatter.hh b/modules/httpserver-api/json/formatter.hh --- a/modules/httpserver-api/json/formatter.hh +++ b/modules/httpserver-api/json/formatter.hh @@ -12,6 +12,7 @@ #include <time.h> #include <sstream> +#pragma GCC visibility push(default) namespace httpserver { namespace json { @@ -124,4 +125,5 @@ private: } } +#pragma GCC visibility pop #endif /* FORMATTER_HH_ */ diff --git a/modules/httpserver-api/json/json_elements.cc b/modules/httpserver-api/json/json_elements.cc --- a/modules/httpserver-api/json/json_elements.cc +++ b/modules/httpserver-api/json/json_elements.cc @@ -13,6 +13,7 @@ using namespace std; +#pragma GCC visibility push(default) namespace httpserver { namespace json { @@ -107,3 +108,4 @@ bool json_base::is_verify() const } } +#pragma GCC visibility pop \ No newline at end of file diff --git a/modules/httpserver-api/json/json_elements.hh b/modules/httpserver-api/json/json_elements.hh --- a/modules/httpserver-api/json/json_elements.hh +++ b/modules/httpserver-api/json/json_elements.hh @@ -14,6 +14,7 @@ #include <sstream> #include "formatter.hh" +#pragma GCC visibility push(default) namespace httpserver { namespace json { @@ -224,4 +225,5 @@ struct json_return_type { } } +#pragma GCC visibility pop #endif /* JSON_ELEMENTS_HH_ */ diff --git a/modules/httpserver-api/json/json_path.cc b/modules/httpserver-api/json/json_path.cc --- a/modules/httpserver-api/json/json_path.cc +++ b/modules/httpserver-api/json/json_path.cc @@ -7,6 +7,7 @@ #include "json_path.hh" +#pragma GCC visibility push(default) namespace httpserver { namespace json { @@ -36,3 +37,4 @@ path_description* path_description::get(string nickname) } } +#pragma GCC visibility pop \ No newline at end of file diff --git a/modules/httpserver-api/json/json_path.hh b/modules/httpserver-api/json/json_path.hh --- a/modules/httpserver-api/json/json_path.hh +++ b/modules/httpserver-api/json/json_path.hh @@ -14,6 +14,7 @@ #include <tuple> #include "common.hh" +#pragma GCC visibility push(default) namespace httpserver { namespace json { @@ -142,4 +143,5 @@ struct path_description { } } +#pragma GCC visibility pop #endif /* JSON_PATH_HH_ */ diff --git a/modules/httpserver-api/main.cc b/modules/httpserver-api/main.cc --- a/modules/httpserver-api/main.cc +++ b/modules/httpserver-api/main.cc @@ -40,7 +40,7 @@ static void handle_parse_error(const std::string &message) exit(1); } -int main(int argc, char* argv[]) +int __attribute__((visibility("default"))) main(int argc, char* argv[]) { auto options_values = options::parse_options_values(argc - 1, argv + 1, handle_parse_error); diff --git a/modules/httpserver-api/path_holder.cc b/modules/httpserver-api/path_holder.cc --- a/modules/httpserver-api/path_holder.cc +++ b/modules/httpserver-api/path_holder.cc @@ -7,6 +7,7 @@ #include "path_holder.hh" #include <assert.h> +#pragma GCC visibility push(default) namespace httpserver { routes* path_holder::_routes = nullptr; @@ -36,3 +37,4 @@ handler_base& path_holder::set_handler(const json_request_function& fun) const } } +#pragma GCC visibility pop \ No newline at end of file diff --git a/modules/httpserver-api/path_holder.hh b/modules/httpserver-api/path_holder.hh --- a/modules/httpserver-api/path_holder.hh +++ b/modules/httpserver-api/path_holder.hh @@ -11,6 +11,7 @@ #include "handlers.hh" #include "routes.hh" +#pragma GCC visibility push(default) namespace httpserver { /** * Path holder glues handlers and implementation. @@ -89,5 +90,5 @@ private: }; } - +#pragma GCC visibility pop #endif /* PATH_HOLDER_HH_ */ diff --git a/modules/httpserver-api/reply.cc b/modules/httpserver-api/reply.cc --- a/modules/httpserver-api/reply.cc +++ b/modules/httpserver-api/reply.cc @@ -11,6 +11,7 @@ #include "reply.hh" #include <string> +#pragma GCC visibility push(default) namespace http { namespace server { @@ -239,3 +240,4 @@ reply& reply::add_header(const std::string& h, const std::string& value) { } // namespace server } // namespace http +#pragma GCC visibility pop \ No newline at end of file diff --git a/modules/httpserver-api/reply.hh b/modules/httpserver-api/reply.hh --- a/modules/httpserver-api/reply.hh +++ b/modules/httpserver-api/reply.hh @@ -17,6 +17,7 @@ #include <vector> #include <boost/asio.hpp> +#pragma GCC visibility push(default) namespace http { namespace server { @@ -87,4 +88,5 @@ struct reply { } // namespace http +#pragma GCC visibility pop #endif // HTTP_REPLY_HPP diff --git a/modules/httpserver-api/server.cc b/modules/httpserver-api/server.cc --- a/modules/httpserver-api/server.cc +++ b/modules/httpserver-api/server.cc @@ -11,23 +11,29 @@ #include "server.hh" #include "connection.hh" +#if !defined(MONITORING) #include "ssl_server.hh" #include "openssl-init.hh" +#endif #include "plain_server.hh" #include <utility> +#if !defined(MONITORING) #include <openssl/ssl.h> +#endif #include <osv/options.hh> namespace http { namespace server { +#if !defined(MONITORING) static bool exists(const std::string& path) { struct stat s; return stat(path.c_str(), &s) == 0; } +#endif server::server(std::map<std::string,std::vector<std::string>> &config, httpserver::routes* routes) @@ -48,6 +54,7 @@ server::server(std::map<std::string,std::vector<std::string>> &config, tcp_acceptor.bind(endpoint); tcp_acceptor.listen(); +#if !defined(MONITORING) if (options::extract_option_flag(config, "ssl", [](const std::string &message) { std::cerr << message << std::endl; throw std::runtime_error("invalid configuration"); @@ -81,6 +88,7 @@ server::server(std::map<std::string,std::vector<std::string>> &config, ssl::context ctx = make_ssl_context(ca_cert_path, cert_path, key_path); acceptor_.reset(new ssl_acceptor(io_service_, std::move(ctx), std::move(tcp_acceptor))); } else { +#endif if (!config.empty()) { for (auto option : config) { std::cout << "Unrecognized option: " << option.first << std::endl; @@ -89,7 +97,9 @@ server::server(std::map<std::string,std::vector<std::string>> &config, } acceptor_.reset(new plain_acceptor(io_service_, std::move(tcp_acceptor))); +#if !defined(MONITORING) } +#endif acceptor_->do_accept(std::bind(&server::on_connected, this, std::placeholders::_1)); } -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/0000000000000f881905a1d83294%40google.com.