Refactor! Compiles...
This commit is contained in:
@ -52,7 +52,7 @@ void dropshell::autocomplete(const std::vector<std::string> &args)
|
|||||||
std::vector<template_info> templates;
|
std::vector<template_info> templates;
|
||||||
get_templates(templates);
|
get_templates(templates);
|
||||||
for (const auto& t : templates)
|
for (const auto& t : templates)
|
||||||
std::cout << t.name << std::endl;
|
std::cout << t.template_name << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,12 +210,12 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& service_info : servicelist) {
|
for (const auto& service_info : servicelist) {
|
||||||
dropshell::service_runner service;
|
dropshell::service_runner runner(server_name, service_info.service_name);
|
||||||
if (!service.init(server_name, service_info.service_name)) {
|
if (!runner.isValid) {
|
||||||
std::cerr << "Error: Failed to initialize service" << std::endl;
|
std::cerr << "Error: Failed to initialize service" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!service.run_command(command)) {
|
if (!runner.run_command(command)) {
|
||||||
std::cerr << command +" failed." << std::endl;
|
std::cerr << command +" failed." << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "service_runner.hpp"
|
#include "service_runner.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "templates.hpp"
|
#include "templates.hpp"
|
||||||
|
#include "server_env.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -59,9 +61,8 @@ int restore(const std::vector<std::string> &args)
|
|||||||
std::string service_name = args[3];
|
std::string service_name = args[3];
|
||||||
std::string backup_file = args[4];
|
std::string backup_file = args[4];
|
||||||
|
|
||||||
|
|
||||||
ServiceInfo service_info = get_service_info(server_name, service_name);
|
ServiceInfo service_info = get_service_info(server_name, service_name);
|
||||||
if (service_info.path.empty()) {
|
if (service_info.local_service_path.empty()) {
|
||||||
std::cerr << "Error: Service not found" << std::endl;
|
std::cerr << "Error: Service not found" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -113,10 +114,9 @@ int backup(const std::vector<std::string> & args) {
|
|||||||
std::string server_name = args[2];
|
std::string server_name = args[2];
|
||||||
std::string service_name = args[3];
|
std::string service_name = args[3];
|
||||||
|
|
||||||
service_runner runner;
|
ServiceInfo service_info = get_service_info(server_name, service_name);
|
||||||
if (!runner.init(server_name, service_name))
|
if (service_info.local_service_path.empty()) {
|
||||||
{
|
std::cerr << "Error: Service not found" << std::endl;
|
||||||
std::cerr << "Error: Failed to initialise service runner" << std::endl;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,17 +125,23 @@ int backup(const std::vector<std::string> & args) {
|
|||||||
std::cerr << "Error: Invalid server environment" << std::endl;
|
std::cerr << "Error: Invalid server environment" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string command = "backup";
|
std::string command = "backup";
|
||||||
|
|
||||||
std::string script_path = runner.sr_get_local_service_template_path() + "/" + command + ".sh";
|
if (!template_command_exists(service_info.template_name, command)) {
|
||||||
if (!template_command_exists(runner.sr_get_service_template_name(), command)) {
|
std::cout << "No backup script for " << service_info.template_name << std::endl;
|
||||||
std::cout << "No backup script for " << runner.sr_get_service_template_name() << std::endl;
|
|
||||||
return true; // nothing to back up.
|
return true; // nothing to back up.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if basic installed stuff is in place.
|
// Check if basic installed stuff is in place.
|
||||||
if (!runner.check_remote_items_exist({runner.sr_get_remote_service_path(),script_path,runner.sr_get_remote_service_env_file()}))
|
std::string remote_service_template_path = get_remote_service_template_path(server_name, service_name);
|
||||||
|
std::string remote_script_path = remote_service_template_path + "/" + command + ".sh";
|
||||||
|
std::string remote_service_env_file = get_remote_service_env_file(server_name, service_name);
|
||||||
|
if (!env.check_remote_items_exist({
|
||||||
|
get_remote_service_path(server_name, service_name),
|
||||||
|
remote_script_path,
|
||||||
|
remote_service_env_file})
|
||||||
|
)
|
||||||
{
|
{
|
||||||
std::cerr << "Error: Required service directories not found on remote server" << std::endl;
|
std::cerr << "Error: Required service directories not found on remote server" << std::endl;
|
||||||
std::cerr << "Is the service installed?" << std::endl;
|
std::cerr << "Is the service installed?" << std::endl;
|
||||||
@ -146,7 +152,7 @@ int backup(const std::vector<std::string> & args) {
|
|||||||
std::string remote_backups_dir = get_remote_backups_path(server_name);
|
std::string remote_backups_dir = get_remote_backups_path(server_name);
|
||||||
std::cout << "Remote backups directory on "<< server_name <<": " << remote_backups_dir << std::endl;
|
std::cout << "Remote backups directory on "<< server_name <<": " << remote_backups_dir << std::endl;
|
||||||
std::string mkdir_cmd = "'mkdir -p " + quote(remote_backups_dir) + "'";
|
std::string mkdir_cmd = "'mkdir -p " + quote(remote_backups_dir) + "'";
|
||||||
if (!runner.execute_ssh_command(mkdir_cmd, "Failed to create backups directory on server")) {
|
if (!env.execute_ssh_command(mkdir_cmd, "Failed to create backups directory on server")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,10 +173,10 @@ int backup(const std::vector<std::string> & args) {
|
|||||||
|
|
||||||
if (name_breaks_backups(server_name)) {std::cerr << "Error: Server name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
|
if (name_breaks_backups(server_name)) {std::cerr << "Error: Server name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
|
||||||
if (name_breaks_backups(service_name)) {std::cerr << "Error: Service name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
|
if (name_breaks_backups(service_name)) {std::cerr << "Error: Service name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
|
||||||
if (name_breaks_backups(runner.sr_get_service_template_name())) {std::cerr << "Error: Service template name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
|
if (name_breaks_backups(service_info.template_name)) {std::cerr << "Error: Service template name contains invalid character sequence ( -_- ) that would break backup naming scheme" << std::endl; return 1;}
|
||||||
|
|
||||||
// Construct backup filename
|
// Construct backup filename
|
||||||
std::string backup_filename = server_name + "-_-" + runner.sr_get_service_template_name() + "-_-" + service_name + "-_-" + datetime.str() + ".tgz";
|
std::string backup_filename = server_name + "-_-" + service_info.template_name + "-_-" + service_name + "-_-" + datetime.str() + ".tgz";
|
||||||
std::string remote_backup_file_path = remote_backups_dir + "/" + backup_filename;
|
std::string remote_backup_file_path = remote_backups_dir + "/" + backup_filename;
|
||||||
std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_filename).string();
|
std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_filename).string();
|
||||||
|
|
||||||
@ -178,20 +184,21 @@ int backup(const std::vector<std::string> & args) {
|
|||||||
ASSERT(3 == count_substring("-_-", local_backup_file_path));
|
ASSERT(3 == count_substring("-_-", local_backup_file_path));
|
||||||
|
|
||||||
// Run backup script
|
// Run backup script
|
||||||
std::string backup_cmd = "'cd " + quote(runner.sr_get_remote_service_template_path()) +
|
std::string backup_cmd = "'cd " + quote(remote_service_template_path) +
|
||||||
" && /bin/bash "+quote(script_path)+" "+quote(runner.sr_get_remote_service_config_path())+" "+
|
" && /bin/bash "+quote(remote_script_path)+" "+quote(remote_service_env_file)+" "+
|
||||||
quote(remote_backup_file_path)+"'";
|
quote(remote_backup_file_path)+"'";
|
||||||
|
|
||||||
if (!runner.execute_ssh_command(backup_cmd, "Backup script failed")) {
|
if (!env.execute_ssh_command(backup_cmd, "Backup script failed")) {
|
||||||
std::cerr << "Backup script failed: " << backup_cmd << std::endl;
|
std::cerr << "Backup script failed: " << backup_cmd << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
} std::cout << "Remote backups directory on "<< server_name <<": " << get_remote_backups_path(server_name) << std::endl;
|
||||||
|
|
||||||
|
|
||||||
// Copy backup file from server to local
|
// Copy backup file from server to local
|
||||||
std::string scp_cmd = "scp -P " + runner.sr_get_server_env().get_SSH_PORT() + " " +
|
std::string scp_cmd = "scp -P " + env.get_SSH_PORT() + " " +
|
||||||
runner.sr_get_server_env().get_SSH_USER() + "@" + runner.sr_get_server_env().get_SSH_HOST() + ":" +
|
env.get_SSH_USER() + "@" + env.get_SSH_HOST() + ":" +
|
||||||
quote(remote_backup_file_path) + " " + quote(local_backup_file_path);
|
quote(remote_backup_file_path) + " " + quote(local_backup_file_path);
|
||||||
if (!runner.execute_local_command(scp_cmd, "Failed to copy backup file from server")) {
|
if (!env.execute_local_command(scp_cmd, "Failed to copy backup file from server")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#include "server_env.hpp"
|
#include "server_env.hpp"
|
||||||
#include "utils/envmanager.hpp"
|
#include "utils/envmanager.hpp"
|
||||||
#include "utils/directories.hpp"
|
#include "utils/directories.hpp"
|
||||||
|
#include "utils/utils.hpp"
|
||||||
|
#include "services.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@ -10,7 +13,7 @@ bool server_env::is_valid() const {
|
|||||||
return mValid;
|
return mValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
server_env::server_env(const std::string& server_name) : mValid(false) {
|
server_env::server_env(const std::string& server_name) : mValid(false), mServer_name(server_name) {
|
||||||
if (server_name.empty())
|
if (server_name.empty())
|
||||||
{
|
{
|
||||||
std::cerr << "Warning: Server name is empty, passed to server_env constructor." << std::endl;
|
std::cerr << "Warning: Server name is empty, passed to server_env constructor." << std::endl;
|
||||||
@ -22,7 +25,8 @@ server_env::server_env(const std::string& server_name) : mValid(false) {
|
|||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
if (!std::filesystem::exists(env_path)) {
|
if (!std::filesystem::exists(env_path)) {
|
||||||
throw std::runtime_error("Server environment file not found: " + env_path);
|
std::cerr << "Server environment file not found: " + env_path << std::endl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -47,8 +51,8 @@ server_env::server_env(const std::string& server_name) : mValid(false) {
|
|||||||
mValid = true;
|
mValid = true;
|
||||||
|
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
throw std::runtime_error("Failed to parse server environment file: " + std::string(e.what()));
|
std::cerr << "Failed to parse server environment file: " + std::string(e.what()) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string server_env::get_variable(const std::string& name) const {
|
std::string server_env::get_variable(const std::string& name) const {
|
||||||
@ -79,4 +83,90 @@ std::string server_env::get_DROPSHELL_DIR() const {
|
|||||||
return get_variable("DROPSHELL_DIR");
|
return get_variable("DROPSHELL_DIR");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper method implementations
|
||||||
|
std::string server_env::construct_ssh_cmd() const {
|
||||||
|
std::stringstream ssh_cmd;
|
||||||
|
ssh_cmd << "ssh -p " << get_SSH_PORT() << " "
|
||||||
|
<< get_SSH_USER() << "@" << get_SSH_HOST() << " ";
|
||||||
|
return ssh_cmd.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string server_env::construct_standard_command_run_cmd(const std::string &service_name, const std::string &command) const
|
||||||
|
{
|
||||||
|
std::string remote_service_template_path = get_remote_service_template_path(mServer_name,service_name);
|
||||||
|
std::string remote_service_config_path = get_remote_service_config_path(mServer_name,service_name);
|
||||||
|
|
||||||
|
std::string script_path = remote_service_template_path + "/" + command + ".sh";
|
||||||
|
std::string run_cmd = "'cd " + quote(remote_service_template_path) +
|
||||||
|
" && /bin/bash "+quote(script_path)+" "+quote(remote_service_config_path)+"'";
|
||||||
|
return run_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool server_env::check_remote_dir_exists(const std::string &dir_path) const
|
||||||
|
{
|
||||||
|
std::string check_dir_cmd = construct_ssh_cmd() + "'test -d " + quote(dir_path) + "'";
|
||||||
|
if (system(check_dir_cmd.c_str()) != 0) {
|
||||||
|
std::cerr << "Error: Directory not found on remote server:" << std::filesystem::path(dir_path).filename().string() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool server_env::check_remote_file_exists(const std::string& file_path) const {
|
||||||
|
std::string check_cmd = construct_ssh_cmd() + "'test -f " + quote(file_path) + "'";
|
||||||
|
if (system(check_cmd.c_str()) != 0) {
|
||||||
|
std::cerr << "Error: File not found on remote server: " << std::filesystem::path(file_path).filename().string() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool server_env::check_remote_items_exist(const std::vector<std::string> &file_paths) const
|
||||||
|
{
|
||||||
|
// convert file_paths to a single string, separated by spaces
|
||||||
|
std::string file_paths_str;
|
||||||
|
std::string file_names_str;
|
||||||
|
for (const auto& file_path : file_paths) {
|
||||||
|
file_paths_str += quote(file_path) + " ";
|
||||||
|
file_names_str += std::filesystem::path(file_path).filename().string() + " ";
|
||||||
|
}
|
||||||
|
// check if all items in the vector exist on the remote server, in a single command.
|
||||||
|
std::string check_cmd = construct_ssh_cmd() + "'for item in " + file_paths_str + "; do test -f $item; done'";
|
||||||
|
if (system(check_cmd.c_str()) != 0) {
|
||||||
|
std::cerr << "Error: Required items not found on remote server: " << file_names_str << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool server_env::execute_ssh_command(const std::string& command, const std::string& error_msg) const {
|
||||||
|
std::string full_cmd = construct_ssh_cmd() + command;
|
||||||
|
return execute_local_command(full_cmd, error_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool server_env::execute_local_command(const std::string& command, const std::string& error_msg) {
|
||||||
|
bool okay = (system(command.c_str()) == 0);
|
||||||
|
|
||||||
|
if (!okay && !error_msg.empty())
|
||||||
|
std::cerr << "Error: " << error_msg << std::endl;
|
||||||
|
return okay;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool server_env::execute_local_command_and_capture_output(const std::string &command, std::string &output)
|
||||||
|
{
|
||||||
|
std::string full_cmd = command + " 2>&1";
|
||||||
|
FILE *pipe = popen(full_cmd.c_str(), "r");
|
||||||
|
if (!pipe) {
|
||||||
|
std::cerr << "Error: Failed to execute command: " << command << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char buffer[128];
|
||||||
|
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
|
||||||
|
output += buffer;
|
||||||
|
}
|
||||||
|
pclose(pipe);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace dropshell
|
} // namespace dropshell
|
@ -32,7 +32,21 @@ class server_env {
|
|||||||
|
|
||||||
bool is_valid() const;
|
bool is_valid() const;
|
||||||
|
|
||||||
|
// helper functions
|
||||||
|
public:
|
||||||
|
std::string construct_ssh_cmd() const;
|
||||||
|
std::string construct_standard_command_run_cmd(const std::string& service_name, const std::string& command) const;
|
||||||
|
bool check_remote_items_exist(const std::vector<std::string>& file_paths) const;
|
||||||
|
bool execute_ssh_command(const std::string& command, const std::string& error_msg) const;
|
||||||
|
|
||||||
|
static bool execute_local_command(const std::string& command, const std::string& error_msg);
|
||||||
|
static bool execute_local_command_and_capture_output(const std::string& command, std::string & output);
|
||||||
|
|
||||||
|
bool check_remote_dir_exists(const std::string &dir_path) const;
|
||||||
|
bool check_remote_file_exists(const std::string& file_path) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string mServer_name;
|
||||||
std::map<std::string, std::string> variables;
|
std::map<std::string, std::string> variables;
|
||||||
bool mValid;
|
bool mValid;
|
||||||
std::unique_ptr<envmanager> m_env_manager;
|
std::unique_ptr<envmanager> m_env_manager;
|
||||||
|
@ -19,26 +19,16 @@ namespace fs = std::filesystem;
|
|||||||
namespace dropshell {
|
namespace dropshell {
|
||||||
|
|
||||||
|
|
||||||
service_runner::service_runner() : m_server_name(""), m_server_env(nullptr) {}
|
service_runner::service_runner(const std::string& server_name, const std::string& service_name) :
|
||||||
|
m_server_env(server_name), m_server_name(server_name), mValid(false)
|
||||||
bool service_runner::init(const std::string& server_name, const std::string& service_name) {
|
{
|
||||||
if (server_name.empty() || service_name.empty())
|
if (server_name.empty() || service_name.empty())
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
// Initialize server environment
|
// Initialize server environment
|
||||||
try {
|
if (!m_server_env.is_valid())
|
||||||
m_server_env = std::make_unique<server_env>(server_name);
|
return;
|
||||||
if (!m_server_env->is_valid()) {
|
|
||||||
std::cerr << "Error: Invalid server environment" << std::endl;
|
|
||||||
m_server_env.reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << "Error: Failed to initialize server environment: " << e.what() << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_server_name = server_name;
|
|
||||||
m_service_info = get_service_info(server_name, service_name);
|
m_service_info = get_service_info(server_name, service_name);
|
||||||
|
|
||||||
mRemote_service_path = get_remote_service_path(m_server_name, m_service_info.service_name);
|
mRemote_service_path = get_remote_service_path(m_server_name, m_service_info.service_name);
|
||||||
@ -46,101 +36,13 @@ bool service_runner::init(const std::string& server_name, const std::string& ser
|
|||||||
mRemote_service_template_path = get_remote_service_template_path(m_server_name, m_service_info.service_name);
|
mRemote_service_template_path = get_remote_service_template_path(m_server_name, m_service_info.service_name);
|
||||||
mRemote_service_env_file = get_remote_service_env_file(m_server_name, m_service_info.service_name);
|
mRemote_service_env_file = get_remote_service_env_file(m_server_name, m_service_info.service_name);
|
||||||
|
|
||||||
return !m_service_info.path.empty();
|
mValid = !m_service_info.local_template_path.empty();
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method implementations
|
|
||||||
std::string service_runner::construct_ssh_cmd(const server_env &env) {
|
|
||||||
std::stringstream ssh_cmd;
|
|
||||||
ssh_cmd << "ssh -p " << env.get_SSH_PORT() << " "
|
|
||||||
<< env.get_SSH_USER() << "@" << env.get_SSH_HOST() << " ";
|
|
||||||
return ssh_cmd.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string service_runner::construct_ssh_cmd() const
|
|
||||||
{
|
|
||||||
if (!m_server_env)
|
|
||||||
return std::string();
|
|
||||||
return construct_ssh_cmd(*m_server_env);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string service_runner::construct_standard_command_run_cmd(const std::string &command) const
|
|
||||||
{
|
|
||||||
std::string script_path = mRemote_service_template_path + "/" + command + ".sh";
|
|
||||||
std::string run_cmd = "'cd " + quote(mRemote_service_template_path) +
|
|
||||||
" && /bin/bash "+quote(script_path)+" "+quote(mRemote_service_config_path)+"'";
|
|
||||||
return run_cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool service_runner::check_remote_dir_exists(const std::string &dir_path) const
|
|
||||||
{
|
|
||||||
std::string check_dir_cmd = construct_ssh_cmd() + "'test -d " + quote(dir_path) + "'";
|
|
||||||
if (system(check_dir_cmd.c_str()) != 0) {
|
|
||||||
std::cerr << "Error: Directory not found on remote server:" << fs::path(dir_path).filename().string() << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool service_runner::check_remote_file_exists(const std::string& file_path) const {
|
|
||||||
std::string check_cmd = construct_ssh_cmd() + "'test -f " + quote(file_path) + "'";
|
|
||||||
if (system(check_cmd.c_str()) != 0) {
|
|
||||||
std::cerr << "Error: File not found on remote server: " << fs::path(file_path).filename().string() << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool service_runner::check_remote_items_exist(const std::vector<std::string> &file_paths) const
|
|
||||||
{
|
|
||||||
// convert file_paths to a single string, separated by spaces
|
|
||||||
std::string file_paths_str;
|
|
||||||
std::string file_names_str;
|
|
||||||
for (const auto& file_path : file_paths) {
|
|
||||||
file_paths_str += quote(file_path) + " ";
|
|
||||||
file_names_str += fs::path(file_path).filename().string() + " ";
|
|
||||||
}
|
|
||||||
// check if all items in the vector exist on the remote server, in a single command.
|
|
||||||
std::string check_cmd = construct_ssh_cmd() + "'for item in " + file_paths_str + "; do test -f $item; done'";
|
|
||||||
if (system(check_cmd.c_str()) != 0) {
|
|
||||||
std::cerr << "Error: Required items not found on remote server: " << file_names_str << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool service_runner::execute_ssh_command(const std::string& command, const std::string& error_msg) const {
|
|
||||||
std::string full_cmd = construct_ssh_cmd() + command;
|
|
||||||
return execute_local_command(full_cmd, error_msg);
|
|
||||||
}
|
|
||||||
bool service_runner::execute_local_command(const std::string& command, const std::string& error_msg) const {
|
|
||||||
bool okay = (system(command.c_str()) == 0);
|
|
||||||
|
|
||||||
if (!okay && !error_msg.empty())
|
|
||||||
std::cerr << "Error: " << error_msg << std::endl;
|
|
||||||
return okay;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool service_runner::execute_local_command_and_capture_output(const std::string &command, std::string &output)
|
|
||||||
{
|
|
||||||
std::string full_cmd = command + " 2>&1";
|
|
||||||
FILE *pipe = popen(full_cmd.c_str(), "r");
|
|
||||||
if (!pipe) {
|
|
||||||
std::cerr << "Error: Failed to execute command: " << command << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
char buffer[128];
|
|
||||||
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
|
|
||||||
output += buffer;
|
|
||||||
}
|
|
||||||
pclose(pipe);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool service_runner::install() {
|
bool service_runner::install() {
|
||||||
maketitle("Installing " + m_service_info.service_name + " (" + m_service_info.template_name + ") on " + m_server_name);
|
maketitle("Installing " + m_service_info.service_name + " (" + m_service_info.template_name + ") on " + m_server_name);
|
||||||
|
|
||||||
if (!m_server_env) return false; // should never hit this.
|
if (!m_server_env.is_valid()) return false; // should never hit this.
|
||||||
|
|
||||||
// Check if template exists
|
// Check if template exists
|
||||||
template_info tinfo;
|
template_info tinfo;
|
||||||
@ -149,23 +51,23 @@ bool service_runner::install() {
|
|||||||
|
|
||||||
// Create service directory
|
// Create service directory
|
||||||
std::string mkdir_cmd = "'mkdir -p " + quote(mRemote_service_path) + "'";
|
std::string mkdir_cmd = "'mkdir -p " + quote(mRemote_service_path) + "'";
|
||||||
if (!execute_ssh_command(mkdir_cmd, "Failed to create service directory"))
|
if (!m_server_env.execute_ssh_command(mkdir_cmd, "Failed to create service directory"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check if rsync is installed on remote host
|
// Check if rsync is installed on remote host
|
||||||
std::string check_rsync_cmd = "'which rsync > /dev/null 2>&1'";
|
std::string check_rsync_cmd = "'which rsync > /dev/null 2>&1'";
|
||||||
if (!execute_ssh_command(check_rsync_cmd, "rsync is not installed on the remote host"))
|
if (!m_server_env.execute_ssh_command(check_rsync_cmd, "rsync is not installed on the remote host"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Copy template files
|
// Copy template files
|
||||||
{
|
{
|
||||||
std::cout << "Copying template files from [LOCAL] " << tinfo.path << std::endl << std::string(24,' ')<<"to [REMOTE] " << mRemote_service_template_path << "/" << std::endl;
|
std::cout << "Copying template files from [LOCAL] " << tinfo.local_template_path << std::endl << std::string(24,' ')<<"to [REMOTE] " << mRemote_service_template_path << "/" << std::endl;
|
||||||
std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env->get_SSH_PORT() + "' " +
|
std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env.get_SSH_PORT() + "' " +
|
||||||
quote(tinfo.path + "/") + " "+
|
quote(tinfo.local_template_path + "/") + " "+
|
||||||
m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" +
|
m_server_env.get_SSH_USER() + "@" + m_server_env.get_SSH_HOST() + ":" +
|
||||||
quote(mRemote_service_template_path+"/");
|
quote(mRemote_service_template_path+"/");
|
||||||
//std::cout << std::endl << rsync_cmd << std::endl << std::endl;
|
//std::cout << std::endl << rsync_cmd << std::endl << std::endl;
|
||||||
execute_local_command(rsync_cmd,"Failed to copy template files");
|
m_server_env.execute_local_command(rsync_cmd,"Failed to copy template files");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy service files (including service.env)
|
// Copy service files (including service.env)
|
||||||
@ -176,17 +78,17 @@ bool service_runner::install() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::cout << "Copying service files from [LOCAL] " << local_service_path << std::endl <<std::string(24,' ')<<"to [REMOTE] " << mRemote_service_config_path << std::endl;
|
std::cout << "Copying service files from [LOCAL] " << local_service_path << std::endl <<std::string(24,' ')<<"to [REMOTE] " << mRemote_service_config_path << std::endl;
|
||||||
std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env->get_SSH_PORT() + "' " +
|
std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env.get_SSH_PORT() + "' " +
|
||||||
quote(local_service_path + "/") + " "+
|
quote(local_service_path + "/") + " "+
|
||||||
m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" +
|
m_server_env.get_SSH_USER() + "@" + m_server_env.get_SSH_HOST() + ":" +
|
||||||
quote(mRemote_service_config_path + "/");
|
quote(mRemote_service_config_path + "/");
|
||||||
execute_local_command(rsync_cmd,"Failed to copy service files");
|
m_server_env.execute_local_command(rsync_cmd,"Failed to copy service files");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run install script
|
// Run install script
|
||||||
{
|
{
|
||||||
std::string install_cmd = construct_standard_command_run_cmd("install");
|
std::string install_cmd = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, "install");
|
||||||
bool ok= execute_ssh_command(install_cmd, "Failed to run install script");
|
bool ok= m_server_env.execute_ssh_command(install_cmd, "Failed to run install script");
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -199,21 +101,21 @@ bool service_runner::install() {
|
|||||||
bool service_runner::uninstall() {
|
bool service_runner::uninstall() {
|
||||||
maketitle("Uninstalling " + m_service_info.service_name + " (" + m_service_info.template_name + ") on " + m_server_name);
|
maketitle("Uninstalling " + m_service_info.service_name + " (" + m_service_info.template_name + ") on " + m_server_name);
|
||||||
|
|
||||||
if (!m_server_env) return false; // should never hit this.
|
if (!m_server_env.is_valid()) return false; // should never hit this.
|
||||||
|
|
||||||
// 2. Check if service directory exists on server
|
// 2. Check if service directory exists on server
|
||||||
if (!check_remote_dir_exists(mRemote_service_path)) {
|
if (!m_server_env.check_remote_dir_exists(mRemote_service_path)) {
|
||||||
std::cerr << "Service is not installed: " << m_service_info.service_name << std::endl;
|
std::cerr << "Service is not installed: " << m_service_info.service_name << std::endl;
|
||||||
return true; // Nothing to uninstall
|
return true; // Nothing to uninstall
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Run uninstall script if it exists
|
// 3. Run uninstall script if it exists
|
||||||
std::string uninstall_script = mRemote_service_template_path + "/_uninstall.sh";
|
std::string uninstall_script = mRemote_service_template_path + "/_uninstall.sh";
|
||||||
bool script_exists = check_remote_file_exists(uninstall_script);
|
bool script_exists = m_server_env.check_remote_file_exists(uninstall_script);
|
||||||
|
|
||||||
if (script_exists) {
|
if (script_exists) {
|
||||||
std::string uninstall_cmd = construct_standard_command_run_cmd("uninstall");
|
std::string uninstall_cmd = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, "uninstall");
|
||||||
if (!execute_ssh_command(uninstall_cmd, "Failed to run uninstall script")) {
|
if (!m_server_env.execute_ssh_command(uninstall_cmd, "Failed to run uninstall script")) {
|
||||||
std::cerr << "Warning: Uninstall script failed, but continuing with directory removal" << std::endl;
|
std::cerr << "Warning: Uninstall script failed, but continuing with directory removal" << std::endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -223,7 +125,7 @@ bool service_runner::uninstall() {
|
|||||||
|
|
||||||
// 4. Remove the service directory from the server
|
// 4. Remove the service directory from the server
|
||||||
std::string rm_cmd = "'rm -rf " + quote(mRemote_service_path) + "'";
|
std::string rm_cmd = "'rm -rf " + quote(mRemote_service_path) + "'";
|
||||||
if (!execute_ssh_command(rm_cmd, "Failed to remove service directory")) {
|
if (!m_server_env.execute_ssh_command(rm_cmd, "Failed to remove service directory")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +138,7 @@ bool service_runner::uninstall() {
|
|||||||
// Run a command on the service.
|
// Run a command on the service.
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool service_runner::run_command(const std::string& command) {
|
bool service_runner::run_command(const std::string& command) {
|
||||||
if (!m_server_env) {
|
if (!m_server_env.is_valid()) {
|
||||||
std::cerr << "Error: Server service not initialized" << std::endl;
|
std::cerr << "Error: Server service not initialized" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -264,17 +166,17 @@ bool service_runner::run_command(const std::string& command) {
|
|||||||
std::string script_path = mRemote_service_template_path + "/" + command + ".sh";
|
std::string script_path = mRemote_service_template_path + "/" + command + ".sh";
|
||||||
|
|
||||||
// Check if service directory exists
|
// Check if service directory exists
|
||||||
if (!check_remote_dir_exists(mRemote_service_path)) {
|
if (!m_server_env.check_remote_dir_exists(mRemote_service_path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if command script exists
|
// Check if command script exists
|
||||||
if (!check_remote_file_exists(script_path)) {
|
if (!m_server_env.check_remote_file_exists(script_path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if env file exists
|
// Check if env file exists
|
||||||
if (!check_remote_file_exists(mRemote_service_env_file)) {
|
if (!m_server_env.check_remote_file_exists(mRemote_service_env_file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,8 +188,8 @@ bool service_runner::run_command(const std::string& command) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the generic command
|
// Run the generic command
|
||||||
std::string run_cmd = construct_standard_command_run_cmd(command);
|
std::string run_cmd = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, command);
|
||||||
return execute_ssh_command(run_cmd, "Command returned error code: " + script_path);
|
return m_server_env.execute_ssh_command(run_cmd, "Command returned error code: " + script_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -316,11 +218,11 @@ std::map<std::string, ServiceStatus> service_runner::get_all_services_status(std
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string script_path = remote_service_template_path + "/" + command + ".sh";
|
std::string script_path = remote_service_template_path + "/" + command + ".sh";
|
||||||
std::string ssh_cmd = construct_ssh_cmd(env) + "'cd " + quote(remote_service_template_path) +
|
std::string ssh_cmd = env.construct_ssh_cmd() + "'cd " + quote(remote_service_template_path) +
|
||||||
" && /bin/bash "+quote(script_path)+" "+quote(remote_service_config_path)+"'";
|
" && /bin/bash "+quote(script_path)+" "+quote(remote_service_config_path)+"'";
|
||||||
|
|
||||||
std::string output;
|
std::string output;
|
||||||
if (!execute_local_command_and_capture_output(ssh_cmd, output))
|
if (!env.execute_local_command_and_capture_output(ssh_cmd, output))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
std::stringstream ss(output);
|
std::stringstream ss(output);
|
||||||
@ -359,7 +261,7 @@ std::map<std::string, ServiceStatus> service_runner::get_all_services_status(std
|
|||||||
|
|
||||||
HealthStatus service_runner::is_healthy()
|
HealthStatus service_runner::is_healthy()
|
||||||
{
|
{
|
||||||
if (!m_server_env) {
|
if (!m_server_env.is_valid()) {
|
||||||
std::cerr << "Error: Server service not initialized" << std::endl;
|
std::cerr << "Error: Server service not initialized" << std::endl;
|
||||||
return HealthStatus::ERROR;
|
return HealthStatus::ERROR;
|
||||||
}
|
}
|
||||||
@ -372,14 +274,14 @@ HealthStatus service_runner::is_healthy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string script_path = mRemote_service_template_path + "/" + command + ".sh";
|
std::string script_path = mRemote_service_template_path + "/" + command + ".sh";
|
||||||
if (!check_remote_file_exists(script_path)) {
|
if (!m_server_env.check_remote_file_exists(script_path)) {
|
||||||
std::cerr << "Service is not installed: " << m_service_info.service_name << std::endl;
|
std::cerr << "Service is not installed: " << m_service_info.service_name << std::endl;
|
||||||
return HealthStatus::NOTINSTALLED;
|
return HealthStatus::NOTINSTALLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run status script, does not display output.
|
// Run status script, does not display output.
|
||||||
std::string run_cmd = construct_standard_command_run_cmd("status");
|
std::string run_cmd = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, "status");
|
||||||
bool ok = execute_ssh_command(run_cmd, "");
|
bool ok = m_server_env.execute_ssh_command(run_cmd, "");
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return HealthStatus::UNHEALTHY;
|
return HealthStatus::UNHEALTHY;
|
||||||
|
|
||||||
@ -506,7 +408,7 @@ void service_runner::interactive_ssh_service()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string command = construct_standard_command_run_cmd("ssh");
|
std::string command = m_server_env.construct_standard_command_run_cmd(m_service_info.service_name, "ssh");
|
||||||
interactive_ssh(m_server_name, "/bin/bash -c '"+command+"'");
|
interactive_ssh(m_server_name, "/bin/bash -c '"+command+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ typedef struct ServiceStatus {
|
|||||||
|
|
||||||
class service_runner {
|
class service_runner {
|
||||||
public:
|
public:
|
||||||
service_runner();
|
service_runner(const std::string& server_name, const std::string& service_name);
|
||||||
bool init(const std::string& server_name, const std::string& service_name);
|
bool isValid;
|
||||||
|
|
||||||
// run a command over ssh, using the credentials from server.env (via server_env.hpp)
|
// run a command over ssh, using the credentials from server.env (via server_env.hpp)
|
||||||
// first check that the command corresponds to a valid .sh file in the service directory
|
// first check that the command corresponds to a valid .sh file in the service directory
|
||||||
@ -89,42 +89,17 @@ class service_runner {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_server_name;
|
std::string m_server_name;
|
||||||
|
server_env m_server_env;
|
||||||
ServiceInfo m_service_info;
|
ServiceInfo m_service_info;
|
||||||
std::unique_ptr<server_env> m_server_env;
|
bool mValid;
|
||||||
|
|
||||||
std::string mRemote_service_path;
|
std::string mRemote_service_path;
|
||||||
std::string mRemote_service_config_path;
|
std::string mRemote_service_config_path;
|
||||||
std::string mRemote_service_template_path;
|
std::string mRemote_service_template_path;
|
||||||
std::string mRemote_service_env_file;
|
std::string mRemote_service_env_file;
|
||||||
|
|
||||||
public:
|
|
||||||
std::string sr_get_server_name() const { return m_server_name; }
|
|
||||||
std::string sr_get_service_name() const { return m_service_info.service_name; }
|
|
||||||
std::string sr_get_service_path() const { return m_service_info.path; }
|
|
||||||
std::string sr_get_service_template_name() const { return m_service_info.template_name; }
|
|
||||||
std::string sr_get_local_service_template_path() const { return m_service_info.template_local_path; }
|
|
||||||
|
|
||||||
ServiceInfo sr_get_service_info() const { return m_service_info; }
|
|
||||||
const server_env& sr_get_server_env() const { ASSERT(m_server_env); return *m_server_env; }
|
|
||||||
|
|
||||||
const std::string& sr_get_remote_service_path() const { return mRemote_service_path; }
|
|
||||||
const std::string& sr_get_remote_service_config_path() const { return mRemote_service_config_path; }
|
|
||||||
const std::string& sr_get_remote_service_template_path() const { return mRemote_service_template_path; }
|
|
||||||
const std::string& sr_get_remote_service_env_file() const { return mRemote_service_env_file; }
|
|
||||||
|
|
||||||
// Helper methods
|
// Helper methods
|
||||||
public:
|
public:
|
||||||
static std::string construct_ssh_cmd(const server_env &env);
|
|
||||||
|
|
||||||
std::string construct_ssh_cmd() const;
|
|
||||||
std::string construct_standard_command_run_cmd(const std::string& command) const;
|
|
||||||
|
|
||||||
bool check_remote_dir_exists(const std::string& dir_path) const;
|
|
||||||
bool check_remote_file_exists(const std::string& file_path) const;
|
|
||||||
bool check_remote_items_exist(const std::vector<std::string>& file_paths) const;
|
|
||||||
bool execute_ssh_command(const std::string& command, const std::string& error_msg) const;
|
|
||||||
bool execute_local_command(const std::string& command, const std::string& error_msg) const;
|
|
||||||
static bool execute_local_command_and_capture_output(const std::string& command, std::string & output);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,16 +51,17 @@ std::vector<ServiceInfo> get_server_services_info(const std::string& server_name
|
|||||||
|
|
||||||
ServiceInfo get_service_info(const std::string &server_name, const std::string &service_name)
|
ServiceInfo get_service_info(const std::string &server_name, const std::string &service_name)
|
||||||
{
|
{
|
||||||
|
ServiceInfo service;
|
||||||
|
|
||||||
if (server_name.empty() || service_name.empty())
|
if (server_name.empty() || service_name.empty())
|
||||||
return ServiceInfo();
|
return ServiceInfo();
|
||||||
|
|
||||||
std::string service_dir = get_local_service_path(server_name, service_name);
|
service.service_name = service_name;
|
||||||
if (service_dir.empty())
|
|
||||||
|
service.local_service_path = get_local_service_path(server_name, service_name);
|
||||||
|
if (service.local_service_path.empty())
|
||||||
return ServiceInfo();
|
return ServiceInfo();
|
||||||
|
|
||||||
ServiceInfo service;
|
|
||||||
service.path = service_dir;
|
|
||||||
service.service_name = service_name;
|
|
||||||
|
|
||||||
// now set the template name and path.
|
// now set the template name and path.
|
||||||
std::string local_service_env_path = get_local_service_env_path(server_name, service_name);
|
std::string local_service_env_path = get_local_service_env_path(server_name, service_name);
|
||||||
@ -83,7 +84,7 @@ ServiceInfo get_service_info(const std::string &server_name, const std::string &
|
|||||||
}
|
}
|
||||||
|
|
||||||
// find the template path
|
// find the template path
|
||||||
service.template_local_path = tinfo.path;
|
service.local_template_path = tinfo.local_template_path;
|
||||||
|
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
@ -95,16 +96,15 @@ std::set<std::string> get_used_commands(const std::string &server_name, const st
|
|||||||
if (server_name.empty() || service_name.empty())
|
if (server_name.empty() || service_name.empty())
|
||||||
return commands;
|
return commands;
|
||||||
|
|
||||||
ServiceInfo service = get_service_info(server_name, service_name);
|
ServiceInfo service_info = get_service_info(server_name, service_name);
|
||||||
if (service.template_local_path.empty()) {
|
if (service_info.local_template_path.empty()) {
|
||||||
std::cerr << "Error: Service not found: " << service_name << std::endl;
|
std::cerr << "Error: Service not found: " << service_name << std::endl;
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate over all files in the template path, and add the command name to the set.
|
// iterate over all files in the template path, and add the command name to the set.
|
||||||
// commands are .sh files that don't begin with _
|
// commands are .sh files that don't begin with _
|
||||||
fs::path template_path = fs::path(service.template_local_path);
|
for (const auto& entry : fs::directory_iterator(service_info.local_template_path)) {
|
||||||
for (const auto& entry : fs::directory_iterator(template_path)) {
|
|
||||||
if (fs::is_regular_file(entry) && entry.path().extension() == ".sh" && (entry.path().filename().string().rfind("_", 0) != 0))
|
if (fs::is_regular_file(entry) && entry.path().extension() == ".sh" && (entry.path().filename().string().rfind("_", 0) != 0))
|
||||||
commands.insert(entry.path().stem().string());
|
commands.insert(entry.path().stem().string());
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ bool create_service(const std::string &server_name, const std::string &template_
|
|||||||
fs::create_directory(service_dir);
|
fs::create_directory(service_dir);
|
||||||
|
|
||||||
// copy the template example files to the service directory
|
// copy the template example files to the service directory
|
||||||
recursive_copy(tinfo.path+"/example", service_dir);
|
recursive_copy(tinfo.local_template_path+"/example", service_dir);
|
||||||
|
|
||||||
std::cout << "Service " << service_name <<" created successfully"<<std::endl;
|
std::cout << "Service " << service_name <<" created successfully"<<std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
namespace dropshell {
|
namespace dropshell {
|
||||||
|
|
||||||
struct ServiceInfo {
|
struct ServiceInfo {
|
||||||
std::string path;
|
|
||||||
std::string service_name;
|
std::string service_name;
|
||||||
std::string template_name;
|
std::string template_name;
|
||||||
std::string template_local_path;
|
std::string local_service_path;
|
||||||
|
std::string local_template_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<ServiceInfo> get_server_services_info(const std::string& server_name);
|
std::vector<ServiceInfo> get_server_services_info(const std::string& server_name);
|
||||||
|
@ -25,17 +25,17 @@ bool get_templates(std::vector<template_info>& templates) {
|
|||||||
for (const auto& entry : std::filesystem::directory_iterator(dir_path)) {
|
for (const auto& entry : std::filesystem::directory_iterator(dir_path)) {
|
||||||
if (entry.is_directory()) {
|
if (entry.is_directory()) {
|
||||||
template_info info;
|
template_info info;
|
||||||
info.name = entry.path().filename().string();
|
info.template_name = entry.path().filename().string();
|
||||||
info.path = entry.path().string();
|
info.local_template_path = entry.path().string();
|
||||||
|
|
||||||
// Check if template with same name already exists
|
// Check if template with same name already exists
|
||||||
bool found = false;
|
bool duplicate = false;
|
||||||
auto it = std::find_if(templates.begin(), templates.end(),
|
auto it = std::find_if(templates.begin(), templates.end(),
|
||||||
[&info](const template_info& t) { return t.name == info.name; });
|
[&info](const template_info& t) { return t.template_name == info.template_name; });
|
||||||
found = (it!=templates.end());
|
duplicate = (it!=templates.end());
|
||||||
found |= info.name=="example"; // don't include the example template!
|
duplicate |= (info.template_name=="example"); // don't include the example template!
|
||||||
|
|
||||||
if (!found) {
|
if (!duplicate) {
|
||||||
templates.push_back(info);
|
templates.push_back(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,14 +58,14 @@ bool get_templates(std::vector<template_info>& templates) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_template_info(const std::string& name, template_info& info) {
|
bool get_template_info(const std::string& template_name, template_info& info) {
|
||||||
std::vector<template_info> templates;
|
std::vector<template_info> templates;
|
||||||
if (!get_templates(templates)) {
|
if (!get_templates(templates)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = std::find_if(templates.begin(), templates.end(),
|
auto it = std::find_if(templates.begin(), templates.end(),
|
||||||
[&name](const template_info& t) { return t.name == name; });
|
[&template_name](const template_info& t) { return t.template_name == template_name; });
|
||||||
|
|
||||||
if (it != templates.end()) {
|
if (it != templates.end()) {
|
||||||
info = *it;
|
info = *it;
|
||||||
@ -82,7 +82,7 @@ bool template_command_exists(const std::string &template_name, const std::string
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string path = info.path + "/" + command + ".sh";
|
std::string path = info.local_template_path + "/" + command + ".sh";
|
||||||
return (std::filesystem::exists(path));
|
return (std::filesystem::exists(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ void list_templates() {
|
|||||||
std::cout << std::string(60, '-') << std::endl;
|
std::cout << std::string(60, '-') << std::endl;
|
||||||
|
|
||||||
for (const auto& t : templates) {
|
for (const auto& t : templates) {
|
||||||
std::cout << std::left << std::setw(20) << t.name << t.path << std::endl;
|
std::cout << std::left << std::setw(20) << t.template_name << t.local_template_path << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ void create_template(const std::string& template_name) {
|
|||||||
|
|
||||||
template_info info;
|
template_info info;
|
||||||
if (get_template_info(template_name, info)) {
|
if (get_template_info(template_name, info)) {
|
||||||
std::cerr << "Error: Template '" << template_name << "' already exists at " << info.path << std::endl;
|
std::cerr << "Error: Template '" << template_name << "' already exists at " << info.local_template_path << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ namespace dropshell {
|
|||||||
|
|
||||||
class template_info {
|
class template_info {
|
||||||
public:
|
public:
|
||||||
std::string name;
|
std::string template_name;
|
||||||
std::string path;
|
std::string local_template_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
// templates are stored in two locations:
|
// templates are stored in two locations:
|
||||||
@ -20,7 +20,7 @@ class template_info {
|
|||||||
|
|
||||||
|
|
||||||
bool get_templates(std::vector<template_info>& templates);
|
bool get_templates(std::vector<template_info>& templates);
|
||||||
bool get_template_info(const std::string& name, template_info& info);
|
bool get_template_info(const std::string& template_name, template_info& info);
|
||||||
bool template_command_exists(const std::string& template_name,const std::string& command);
|
bool template_command_exists(const std::string& template_name,const std::string& command);
|
||||||
void list_templates();
|
void list_templates();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user