150 lines
4.2 KiB
C++
150 lines
4.2 KiB
C++
#include "server.hpp"
|
|
#include "config.hpp"
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <csignal>
|
|
#include <atomic>
|
|
#include <memory>
|
|
#include <thread>
|
|
#include <drogon/drogon.h>
|
|
|
|
#include "version.hpp"
|
|
|
|
namespace simple_object_storage {
|
|
|
|
std::atomic<bool> g_running{true};
|
|
std::unique_ptr<Server> g_server;
|
|
std::thread g_server_thread;
|
|
|
|
std::filesystem::path get_executable_path() {
|
|
return std::filesystem::read_symlink("/proc/self/exe");
|
|
}
|
|
|
|
std::filesystem::path get_config_path() {
|
|
const std::filesystem::path _home = std::getenv("HOME");
|
|
const std::filesystem::path _exe = get_executable_path().parent_path();
|
|
|
|
// check for config in the following paths:
|
|
std::vector<std::filesystem::path> config_paths = {
|
|
"/data/sos_config.json",
|
|
_home / ".config/simple-object-server/sos_config.json",
|
|
_home / ".config/simple-object-server/config.json",
|
|
_home / ".config/simple_object_storage/sos_config.json",
|
|
_exe / "sos_config.json",
|
|
"/testing/sos_config.json"
|
|
};
|
|
|
|
for (const auto& path : config_paths) {
|
|
if (std::filesystem::exists(path)) {
|
|
return path;
|
|
}
|
|
}
|
|
std::cout << "No config file found. Checked: " << std::endl;
|
|
for (const auto& path : config_paths) {
|
|
std::cout << " " << path << std::endl;
|
|
}
|
|
return std::filesystem::path();
|
|
}
|
|
|
|
bool initialize_server() {
|
|
std::filesystem::path config_path = get_config_path();
|
|
if (config_path.empty()) {
|
|
return false;
|
|
}
|
|
std::cout << "Config file: " << config_path << std::endl;
|
|
|
|
ServerConfig config;
|
|
if (!simple_object_storage::load_config(config_path, config)) {
|
|
std::cout << "Config file at " << config_path << " is not valid." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
std::cout << "Starting server at " << config.host << ":" << config.port << std::endl;
|
|
std::cout << "Object store path: " << config.object_store_path << std::endl;
|
|
|
|
if (!std::filesystem::exists(config.object_store_path)) {
|
|
std::cout << "Object store path does not exist: " << config.object_store_path << std::endl;
|
|
return false;
|
|
}
|
|
|
|
g_server = std::make_unique<Server>(config);
|
|
return true;
|
|
}
|
|
|
|
void stop_server() {
|
|
if (g_server) {
|
|
std::cout << "Stopping server..." << std::endl;
|
|
g_server->stop();
|
|
if (g_server_thread.joinable()) {
|
|
g_server_thread.join();
|
|
}
|
|
g_server.reset();
|
|
}
|
|
}
|
|
|
|
void signal_handler(int signal) {
|
|
switch (signal) {
|
|
case SIGHUP:
|
|
std::cout << "Received SIGHUP signal - reloading configuration" << std::endl;
|
|
stop_server();
|
|
if (!initialize_server()) {
|
|
std::cerr << "Failed to restart server with new configuration" << std::endl;
|
|
g_running = false;
|
|
}
|
|
break;
|
|
case SIGTERM:
|
|
case SIGINT:
|
|
std::cout << "Received termination signal" << std::endl;
|
|
g_running = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
if (argc > 1) {
|
|
if (std::string(argv[1]) == "version") {
|
|
std::cout << dropshell::VERSION << std::endl;
|
|
return 0;
|
|
}
|
|
std::cout << "simple_object_storage version: " << dropshell::VERSION << std::endl;
|
|
}
|
|
|
|
// Set up signal handlers
|
|
struct sigaction sa;
|
|
sa.sa_handler = signal_handler;
|
|
sigemptyset(&sa.sa_mask);
|
|
sa.sa_flags = 0;
|
|
|
|
if (sigaction(SIGHUP, &sa, nullptr) == -1) {
|
|
std::cerr << "Failed to set up SIGHUP handler" << std::endl;
|
|
return 1;
|
|
}
|
|
if (sigaction(SIGTERM, &sa, nullptr) == -1) {
|
|
std::cerr << "Failed to set up SIGTERM handler" << std::endl;
|
|
return 1;
|
|
}
|
|
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
|
std::cerr << "Failed to set up SIGINT handler" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
// Initial server startup
|
|
if (!initialize_server()) {
|
|
return 1;
|
|
}
|
|
|
|
// Start server in main thread
|
|
if (!g_server->start()) {
|
|
std::cerr << "Failed to start server" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
} // namespace simple_object_storage
|
|
|
|
int main(int argc, char* argv[]) {
|
|
return simple_object_storage::main(argc, argv);
|
|
} |