Servers
This commit is contained in:
parent
0eacb838ce
commit
a718f23375
@ -7,15 +7,15 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
# Find required packages
|
||||
find_package(Boost REQUIRED COMPONENTS program_options filesystem system)
|
||||
|
||||
# Auto-detect source files
|
||||
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||
file(GLOB_RECURSE HEADERS "src/*.hpp")
|
||||
|
||||
# Add executable
|
||||
add_executable(dropshell
|
||||
src/main.cpp
|
||||
src/version.cpp
|
||||
src/status.cpp
|
||||
src/servers.cpp
|
||||
src/help.cpp
|
||||
src/config.cpp
|
||||
)
|
||||
add_executable(dropshell ${SOURCES})
|
||||
|
||||
# Set include directories
|
||||
target_include_directories(dropshell PRIVATE src)
|
||||
|
||||
# Link libraries
|
||||
target_link_libraries(dropshell PRIVATE
|
||||
|
@ -7,7 +7,7 @@ _dropshell_completions() {
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
# List of main commands
|
||||
opts="help version status servers"
|
||||
opts="help version status servers templates"
|
||||
|
||||
# If we're completing the first argument, show all commands
|
||||
if [[ ${COMP_CWORD} -eq 1 ]] ; then
|
||||
@ -36,6 +36,10 @@ _dropshell_completions() {
|
||||
COMPREPLY=( $(compgen -W "${servers[@]}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
templates)
|
||||
# No additional completions for templates
|
||||
COMPREPLY=()
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
27
src/dropshell.cpp
Normal file
27
src/dropshell.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "dropshell.hpp"
|
||||
#include "templates.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
void dropshell::list_templates() {
|
||||
template_manager tm;
|
||||
std::vector<template_info> templates;
|
||||
|
||||
if (!tm.get_templates(templates)) {
|
||||
std::cerr << "Error: Failed to get templates" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (templates.empty()) {
|
||||
std::cout << "No templates found." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Available templates:" << std::endl;
|
||||
std::cout << std::left << std::setw(20) << "Name" << "Path" << std::endl;
|
||||
std::cout << std::string(60, '-') << std::endl;
|
||||
|
||||
for (const auto& t : templates) {
|
||||
std::cout << std::left << std::setw(20) << t.name << t.path << std::endl;
|
||||
}
|
||||
}
|
@ -24,6 +24,8 @@ void print_help(const boost::program_options::options_description& desc);
|
||||
void print_version();
|
||||
void check_status();
|
||||
void list_servers();
|
||||
void list_templates();
|
||||
void show_server_details(const std::string& server_name);
|
||||
|
||||
// Utility functions
|
||||
std::vector<ServerInfo> get_configured_servers();
|
||||
|
@ -15,10 +15,14 @@ void print_help(const boost::program_options::options_description& desc) {
|
||||
std::cout << std::endl;
|
||||
std::cout << " status Check system status" << std::endl;
|
||||
std::cout << " servers List configured servers" << std::endl;
|
||||
std::cout << " servers NAME Show details for specific server" << std::endl;
|
||||
std::cout << " templates List available templates" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Examples:" << std::endl;
|
||||
std::cout << " dropshell servers" << std::endl;
|
||||
std::cout << " dropshell servers myserver" << std::endl;
|
||||
std::cout << " dropshell init /path/to/directory" << std::endl;
|
||||
std::cout << " dropshell templates" << std::endl;
|
||||
}
|
||||
|
||||
} // namespace dropshell
|
11
src/main.cpp
11
src/main.cpp
@ -51,7 +51,16 @@ int main(int argc, char* argv[]) {
|
||||
dropshell::check_status();
|
||||
return 0;
|
||||
} else if (cmd == "servers") {
|
||||
dropshell::list_servers();
|
||||
if (argc > 2) {
|
||||
// Show details for specific server
|
||||
dropshell::show_server_details(argv[2]);
|
||||
} else {
|
||||
// List all servers
|
||||
dropshell::list_servers();
|
||||
}
|
||||
return 0;
|
||||
} else if (cmd == "templates") {
|
||||
dropshell::list_templates();
|
||||
return 0;
|
||||
} else if (cmd == "init") {
|
||||
if (!vm.count("directory")) {
|
||||
|
74
src/server_env.cpp
Normal file
74
src/server_env.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include "server_env.hpp"
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/ini_parser.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
server_env::server_env(const std::string& path) {
|
||||
// Construct the full path to _server.env
|
||||
boost::filesystem::path env_path = boost::filesystem::path(path) / "_server.env";
|
||||
|
||||
// Check if file exists
|
||||
if (!boost::filesystem::exists(env_path)) {
|
||||
throw std::runtime_error("Server environment file not found: " + env_path.string());
|
||||
}
|
||||
|
||||
try {
|
||||
// Read the INI file
|
||||
boost::property_tree::ptree pt;
|
||||
boost::property_tree::ini_parser::read_ini(env_path.string(), pt);
|
||||
|
||||
// Store all variables
|
||||
for (const auto& section : pt) {
|
||||
for (const auto& key_value : section.second) {
|
||||
variables[key_value.first] = key_value.second.get_value<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
// Verify required variables exist
|
||||
if (variables.find("SSH_HOST") == variables.end() ||
|
||||
variables.find("SSH_USER") == variables.end() ||
|
||||
variables.find("SSH_PORT") == variables.end()) {
|
||||
throw std::runtime_error("Missing required variables in server environment file");
|
||||
}
|
||||
} catch (const boost::property_tree::ini_parser_error& e) {
|
||||
throw std::runtime_error("Failed to parse server environment file: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
std::string server_env::get_variable(const std::string& name) {
|
||||
auto it = variables.find(name);
|
||||
if (it == variables.end()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string value = it->second;
|
||||
|
||||
// Replace ${USER} with actual username
|
||||
const char* username = std::getenv("USER");
|
||||
if (username) {
|
||||
std::string user_var = "${USER}";
|
||||
size_t pos = value.find(user_var);
|
||||
if (pos != std::string::npos) {
|
||||
value.replace(pos, user_var.length(), username);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string server_env::get_SSH_HOST() {
|
||||
return get_variable("SSH_HOST");
|
||||
}
|
||||
|
||||
std::string server_env::get_SSH_USER() {
|
||||
return get_variable("SSH_USER");
|
||||
}
|
||||
|
||||
std::string server_env::get_SSH_PORT() {
|
||||
return get_variable("SSH_PORT");
|
||||
}
|
||||
|
||||
} // namespace dropshell
|
32
src/server_env.hpp
Normal file
32
src/server_env.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
// server_env.hpp
|
||||
//
|
||||
// read the _server.env file and provide a class to access the variables
|
||||
//
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
// reads path / _server.env and provides a class to access the variables.
|
||||
// each env file is required to have the following variables:
|
||||
// SSH_HOST
|
||||
// SSH_USER
|
||||
// SSH_PORT
|
||||
// the following replacements are made in the values:
|
||||
// ${USER} -> the username of the user running dropshell
|
||||
class server_env {
|
||||
public:
|
||||
server_env(const std::string& path);
|
||||
std::string get_variable(const std::string& name);
|
||||
|
||||
std::string get_SSH_HOST();
|
||||
std::string get_SSH_USER();
|
||||
std::string get_SSH_PORT();
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> variables;
|
||||
};
|
||||
|
||||
} // namespace dropshell
|
||||
|
@ -86,4 +86,67 @@ void list_servers() {
|
||||
}
|
||||
}
|
||||
|
||||
void show_server_details(const std::string& server_name) {
|
||||
std::string user_dir;
|
||||
if (!get_user_directory(user_dir)) {
|
||||
std::cerr << "Error: User directory not set" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
fs::path server_dir = fs::path(user_dir) / "servers" / server_name;
|
||||
if (!fs::exists(server_dir)) {
|
||||
std::cerr << "Error: Server '" << server_name << "' not found" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
fs::path env_file = server_dir / "_server.env";
|
||||
if (!fs::exists(env_file)) {
|
||||
std::cerr << "Error: Server configuration file not found" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Server Details: " << server_name << std::endl;
|
||||
std::cout << std::string(40, '-') << std::endl;
|
||||
|
||||
std::ifstream file(env_file.string());
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
if (!line.empty() && line[0] != '#') {
|
||||
std::cout << line << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if server is reachable via SSH
|
||||
std::string ssh_address;
|
||||
file.clear();
|
||||
file.seekg(0);
|
||||
while (std::getline(file, line)) {
|
||||
if (boost::starts_with(line, "SSH_ADDRESS=")) {
|
||||
ssh_address = line.substr(12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ssh_address.empty()) {
|
||||
std::cout << std::endl << "Server Status:" << std::endl;
|
||||
std::cout << std::string(40, '-') << std::endl;
|
||||
|
||||
// Try to connect to the server
|
||||
std::string cmd = "ssh -o ConnectTimeout=5 " + ssh_address + " 'echo connected' 2>/dev/null";
|
||||
int result = system(cmd.c_str());
|
||||
if (result == 0) {
|
||||
std::cout << "Status: Online" << std::endl;
|
||||
|
||||
// Get uptime if possible
|
||||
cmd = "ssh " + ssh_address + " 'uptime' 2>/dev/null";
|
||||
int rval = system(cmd.c_str());
|
||||
if (rval != 0) {
|
||||
std::cout << "Error: Failed to get uptime" << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << "Status: Offline" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dropshell
|
@ -5,6 +5,8 @@
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
template_manager::template_manager() {
|
||||
// Constructor implementation
|
||||
}
|
||||
@ -74,3 +76,4 @@ bool template_manager::get_template_info(const std::string& name, template_info&
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace dropshell
|
@ -1,4 +1,9 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace dropshell {
|
||||
|
||||
class template_info {
|
||||
public:
|
||||
std::string name;
|
||||
@ -20,3 +25,5 @@ class template_manager {
|
||||
bool get_templates(std::vector<template_info>& templates);
|
||||
bool get_template_info(const std::string& name, template_info& info);
|
||||
};
|
||||
|
||||
} // namespace dropshell
|
||||
|
Loading…
x
Reference in New Issue
Block a user