nodes_data::ptr start_nodes(std::ostream &debug_stream, const std::vector<config_data> &configs, const std::string &path) { nodes_data::ptr data = std::make_shared<nodes_data>(); std::string base_path; std::string auth_cookie; std::string cocaine_config_template = read_file(COCAINE_CONFIG_PATH); std::string run_path; { char buffer[1024]; snprintf(buffer, sizeof(buffer), "%04x%04x", rand(), rand()); buffer[sizeof(buffer) - 1] = 0; auth_cookie = buffer; snprintf(buffer, sizeof(buffer), "/tmp/elliptics-test-run-%04x/", rand()); buffer[sizeof(buffer) - 1] = 0; run_path = buffer; } const auto ports = generate_ports(configs.size()); if (path.empty()) { char buffer[1024]; snprintf(buffer, sizeof(buffer), "/tmp/elliptics-test-%04x/", rand()); buffer[sizeof(buffer) - 1] = 0; base_path = buffer; create_directory(base_path); data->directory = directory_handler(base_path, true); } else { base_path = path; create_directory(base_path); data->directory = directory_handler(base_path, false); } debug_stream << "Set base directory: \"" << base_path << "\"" << std::endl; create_directory(run_path); data->run_directory = directory_handler(run_path, true); debug_stream << "Set cocaine run directory: \"" << run_path << "\"" << std::endl; std::string cocaine_remotes; for (size_t j = 0; j < configs.size(); ++j) { if (j > 0) cocaine_remotes += ", "; cocaine_remotes += "\"localhost\": " + ports[j]; } const auto cocaine_locator_ports = generate_ports(configs.size()); // client only needs connection to one (any) locator service data->locator_port = std::stoul(cocaine_locator_ports[0]); debug_stream << "Starting " << configs.size() << " servers" << std::endl; for (size_t i = 0; i < configs.size(); ++i) { debug_stream << "Starting server #" << (i + 1) << std::endl; const std::string server_path = base_path + "/server-" + boost::lexical_cast<std::string>(i + 1); create_directory(server_path); create_directory(server_path + "/blob"); create_directory(server_path + "/history"); std::string remotes; for (size_t j = 0; j < configs.size(); ++j) { if (j == i) continue; remotes += create_remote(ports[j]); } config_data config = configs[i]; if (remotes.empty()) config("remote", NULL_VALUE); else config("remote", remotes); if (config.has_value("srw_config")) { create_directory(server_path + "/run"); const substitute_context cocaine_variables = { { "COCAINE_LOCATOR_PORT", cocaine_locator_ports[i] }, { "COCAINE_PLUGINS_PATH", COCAINE_PLUGINS_PATH }, { "ELLIPTICS_REMOTES", cocaine_remotes }, { "ELLIPTICS_GROUPS", "1" }, { "COCAINE_LOG_PATH", server_path + "/cocaine.log" }, { "COCAINE_RUN_PATH", run_path } }; create_cocaine_config(server_path + "/cocaine.conf", cocaine_config_template, cocaine_variables); config("srw_config", server_path + "/cocaine.conf"); } create_config(config, server_path + "/ioserv.conf") ("auth_cookie", auth_cookie) ("log", server_path + "/log.log") ("addr", create_remote(ports[i])) ("history", server_path + "/history") ("data", server_path + "/blob/data") ; server_node server(server_path + "/ioserv.conf", create_remote(ports[i])); server.start(); debug_stream << "Started server #" << (i + 1) << std::endl; data->nodes.emplace_back(std::move(server)); } { std::vector<std::string> remotes; for (size_t i = 0; i < data->nodes.size(); ++i) { remotes.push_back(data->nodes[i].remote()); } start_client_nodes(data, debug_stream, remotes); } return data; }
nodes_data::ptr start_nodes(std::ostream &debug_stream, const std::vector<server_config> &configs, const std::string &path) { nodes_data::ptr data = std::make_shared<nodes_data>(); std::string base_path; std::string auth_cookie; std::string cocaine_config_template = read_file(COCAINE_CONFIG_PATH); std::string run_path; { char buffer[1024]; snprintf(buffer, sizeof(buffer), "%04x%04x", rand(), rand()); buffer[sizeof(buffer) - 1] = 0; auth_cookie = buffer; snprintf(buffer, sizeof(buffer), "/tmp/elliptics-test-run-%04x/", rand()); buffer[sizeof(buffer) - 1] = 0; run_path = buffer; } std::set<std::string> all_ports; const auto ports = generate_ports(configs.size(), all_ports); const auto monitor_ports = generate_ports(configs.size(), all_ports); if (path.empty()) { char buffer[1024]; snprintf(buffer, sizeof(buffer), "/tmp/elliptics-test-%04x/", rand()); buffer[sizeof(buffer) - 1] = 0; base_path = buffer; create_directory(base_path); data->directory = directory_handler(base_path, true); } else { #if BOOST_VERSION >= 104600 boost::filesystem::path boost_path = boost::filesystem::absolute(path); #else boost::filesystem::path boost_path = boost::filesystem::complete(path, boost::filesystem::current_path()); #endif base_path = boost_path.string(); create_directory(base_path); data->directory = directory_handler(base_path, false); } debug_stream << "Set base directory: \"" << base_path << "\"" << std::endl; create_directory(run_path); data->run_directory = directory_handler(run_path, true); debug_stream << "Set cocaine run directory: \"" << run_path << "\"" << std::endl; std::set<std::string> cocaine_unique_groups; std::string cocaine_remotes; std::string cocaine_groups; for (size_t j = 0; j < configs.size(); ++j) { if (j > 0) cocaine_remotes += ", "; cocaine_remotes += "\"localhost:" + ports[j] + ":2\""; const std::string group = configs[j].options.string_value("group"); if (cocaine_unique_groups.find(group) == cocaine_unique_groups.end()) { if (!cocaine_groups.empty()) cocaine_groups += ", "; cocaine_groups += group; } } const auto cocaine_locator_ports = generate_ports(configs.size(), all_ports); // client only needs connection to one (any) locator service data->locator_port = std::stoul(cocaine_locator_ports[0]); debug_stream << "Starting " << configs.size() << " servers" << std::endl; for (size_t i = 0; i < configs.size(); ++i) { debug_stream << "Starting server #" << (i + 1) << std::endl; const std::string server_suffix = "/server-" + boost::lexical_cast<std::string>(i + 1); const std::string server_path = base_path + server_suffix; create_directory(server_path); create_directory(server_path + "/blob"); create_directory(server_path + "/history"); std::vector<std::string> remotes; for (size_t j = 0; j < configs.size(); ++j) { if (j == i) continue; remotes.push_back(create_remote(ports[j])); } server_config config = configs[i]; if (!remotes.empty()) config.options("remote", remotes); if (config.options.has_value("srw_config")) { const std::string server_run_path = run_path + server_suffix; create_directory(server_run_path); const substitute_context cocaine_variables = { { "COCAINE_LOCATOR_PORT", cocaine_locator_ports[i] }, { "COCAINE_PLUGINS_PATH", COCAINE_PLUGINS_PATH }, { "ELLIPTICS_REMOTES", cocaine_remotes }, { "ELLIPTICS_GROUPS", cocaine_groups }, { "COCAINE_LOG_PATH", server_path + "/cocaine.log" }, { "COCAINE_RUN_PATH", server_run_path } }; create_cocaine_config(server_path + "/cocaine.conf", cocaine_config_template, cocaine_variables); config.options("srw_config", server_path + "/cocaine.conf"); } if (config.log_path.empty()) config.log_path = server_path + "/log.log"; config.options ("auth_cookie", auth_cookie) ("address", std::vector<std::string>(1, create_remote(ports[i]))) ("monitor_port", boost::lexical_cast<int>(monitor_ports[i])) ; config.backends[0] ("history", server_path + "/history") ("data", server_path + "/blob/data") ; config.write(server_path + "/ioserv.conf"); server_node server(server_path + "/ioserv.conf", create_remote(ports[i]), boost::lexical_cast<int>(monitor_ports[i])); try { server.start(); } catch (...) { std::ifstream in; in.open(config.log_path.c_str()); try { if (in) { std::string line; while (std::getline(in, line)) debug_stream << line << std::endl; } } catch (...) { } throw; } debug_stream << "Started server #" << (i + 1) << std::endl; data->nodes.emplace_back(std::move(server)); } { std::vector<std::string> remotes; for (size_t i = 0; i < data->nodes.size(); ++i) { remotes.push_back(data->nodes[i].remote()); } start_client_nodes(data, debug_stream, remotes); } return data; }