This commit is contained in:
Your Name 2025-04-28 21:12:02 +12:00
parent 1d6986cda0
commit 76efe77e85
10 changed files with 140 additions and 141 deletions

View File

@ -11,12 +11,6 @@
void dropshell::autocomplete(const std::vector<std::string> &args) void dropshell::autocomplete(const std::vector<std::string> &args)
{ {
auto cfg = dropshell::get_global_config();
// std::cerr << "[ "<<args.size()<<" ] : ";
// for (const auto& arg : args)
// std::cerr << arg << " ";
// std::cerr << std::endl;
if (args.size() < 3) // dropshell autocomplete ??? if (args.size() < 3) // dropshell autocomplete ???
{ {
autocomplete_list_commands(); autocomplete_list_commands();
@ -32,7 +26,7 @@ void dropshell::autocomplete(const std::vector<std::string> &args)
if (std::find(std::begin(noargcmds), std::end(noargcmds), cmd) != std::end(noargcmds)) if (std::find(std::begin(noargcmds), std::end(noargcmds), cmd) != std::end(noargcmds))
return; return;
if (!cfg->is_config_set()) if (!dropshell::gConfig().is_config_set())
return; // can't help without working config. return; // can't help without working config.
if (args.size()==3) // we have the command but nothing else. dropshell autocomplete command <server> if (args.size()==3) // we have the command but nothing else. dropshell autocomplete command <server>
@ -89,7 +83,7 @@ void dropshell::autocomplete_list_commands()
commands.merge(std::set<std::string>{ commands.merge(std::set<std::string>{
"help","init" // these are always available. "help","init" // these are always available.
}); });
if (dropshell::get_global_config()->is_config_set()) if (dropshell::gConfig().is_config_set())
commands.merge(std::set<std::string>{ commands.merge(std::set<std::string>{
"server","templates","create-service","create-template","create-server","edit","ssh", "server","templates","create-service","create-template","create-server","edit","ssh",
"list" // only if we have a config. "list" // only if we have a config.

View File

@ -30,7 +30,7 @@ void print_help() {
std::cout << " help Show this help message" << std::endl; std::cout << " help Show this help message" << std::endl;
std::cout << " init DIR Add DIR as a local server config directory (can add several)" << std::endl; std::cout << " init DIR Add DIR as a local server config directory (can add several)" << std::endl;
if (get_global_config()->is_config_set()) { if (gConfig().is_config_set()) {
std::cout << " server NAME Show details for specific server" << std::endl; std::cout << " server NAME Show details for specific server" << std::endl;
std::cout << " templates List all available templates" << std::endl; std::cout << " templates List all available templates" << std::endl;
std::cout << std::endl; std::cout << std::endl;
@ -86,9 +86,8 @@ std::string safearg(int argc, char *argv[], int index)
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
try { try {
dropshell::config *cfg = dropshell::get_global_config();
// silently attempt to load the config file. // silently attempt to load the config file.
cfg->load_config(); dropshell::gConfig().load_config();
if (argc < 2) { if (argc < 2) {
dropshell::print_help(); dropshell::print_help();
@ -115,17 +114,18 @@ int main(int argc, char* argv[]) {
} }
if (cmd == "edit" && argc < 3) { if (cmd == "edit" && argc < 3) {
std::filesystem::create_directories(dropshell::get_local_dropshell_config_parent_path()); std::string config_file = dropshell::localfile::dropshell_conf();
dropshell::edit_file(dropshell::get_local_dropshell_config_file(), "Please ensure any directories you have introduced in the config file exist."); std::filesystem::create_directories( dropshell::get_parent(config_file) );
dropshell::edit_file(config_file, "Please ensure any directories you have introduced in the config file exist.");
return 0; return 0;
} }
// ------------------------------------------------------------ // ------------------------------------------------------------
// from here we require the config file to be loaded. // from here we require the config file to be loaded.
if (!cfg->is_config_set()) if (!dropshell::gConfig().is_config_set())
return die("Please run 'dropshell init <path>' to initialise the user directory and create a configuration file."); return die("Please run 'dropshell init <path>' to initialise the user directory and create a configuration file.");
const std::vector<std::string> & local_config_directories = cfg->get_local_config_directories(); const std::vector<std::string> & local_config_directories = dropshell::gConfig().get_local_config_directories();
std::cout << "Config directories: "; std::cout << "Config directories: ";
for (auto & dir : local_config_directories) for (auto & dir : local_config_directories)
std::cout << "["<< dir << "] "; std::cout << "["<< dir << "] ";

View File

@ -6,7 +6,7 @@
#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 "server_env_manager.hpp"
#include <iostream> #include <iostream>
#include <filesystem> #include <filesystem>
@ -22,7 +22,6 @@ static const std::string magic_string = "-_-";
int init(const std::vector<std::string> &args) int init(const std::vector<std::string> &args)
{ {
dropshell::config *cfg = dropshell::get_global_config();
std::string lcd; std::string lcd;
if (args.size() < 3) { if (args.size() < 3) {
@ -30,28 +29,28 @@ int init(const std::vector<std::string> &args)
return 1; return 1;
} }
try { try {
if (!cfg->add_local_config_directory(args[2])) if (!gConfig().add_local_config_directory(args[2]))
return 1; // error already reported return 1; // error already reported
cfg->save_config(); gConfig().save_config();
std::cout << "Config directory added: " << cfg->get_local_config_directories().back() << std::endl; std::cout << "Config directory added: " << gConfig().get_local_config_directories().back() << std::endl;
dropshell::create_readme_local_config_dir(cfg->get_local_config_directories().back()); dropshell::create_readme_local_config_dir(gConfig().get_local_config_directories().back());
if (cfg->get_local_config_directories().size() ==1) if (gConfig().get_local_config_directories().size() ==1)
std::cout << "DropShell is now initialised and you can add a server with 'dropshell create-server <server-name>'" << std::endl; std::cout << "DropShell is now initialised and you can add a server with 'dropshell create-server <server-name>'" << std::endl;
else else
{ {
std::cout << "DropShell will now use all of the following directories for configuration:" << std::endl; std::cout << "DropShell will now use all of the following directories for configuration:" << std::endl;
for (const auto& dir : cfg->get_local_config_directories()) { for (const auto& dir : gConfig().get_local_config_directories()) {
std::cout << " " << dir << std::endl; std::cout << " " << dir << std::endl;
} }
std::cout << "You can edit the config file manually with: dropshell edit" << std::endl; std::cout << "You can edit the config file manually with: dropshell edit" << std::endl;
} }
return 0;
} catch (const std::exception& e) { } catch (const std::exception& e) {
std::cerr << "Error in init: " << e.what() << std::endl; std::cerr << "Error in init: " << e.what() << std::endl;
return 1; return 1;
} }
return 0;
} }
int restore(const std::vector<std::string> &args, bool silent) int restore(const std::vector<std::string> &args, bool silent)
@ -71,13 +70,13 @@ int restore(const std::vector<std::string> &args, bool silent)
return 1; return 1;
} }
server_env env(server_name); server_env_manager env(server_name);
if (!env.is_valid()) { if (!env.is_valid()) {
std::cerr << "Error: Invalid server environment" << std::endl; std::cerr << "Error: Invalid server environment" << std::endl;
return 1; return 1;
} }
std::string local_backups_dir = get_local_backup_path(); std::string local_backups_dir = localpath::backups_path();
std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_file).string(); std::string local_backup_file_path = (std::filesystem::path(local_backups_dir) / backup_file).string();
if (! std::filesystem::exists(local_backup_file_path)) { if (! std::filesystem::exists(local_backup_file_path)) {
@ -135,7 +134,7 @@ int restore(const std::vector<std::string> &args, bool silent)
{ // restore service from backup { // restore service from backup
std::cout << "2) Restoring service from backup..." << std::endl; std::cout << "2) Restoring service from backup..." << std::endl;
std::string remote_backups_dir = get_remote_backups_path(server_name); std::string remote_backups_dir = remotepath::backups(server_name);
std::string remote_backup_file_path = remote_backups_dir + "/" + backup_file; std::string remote_backup_file_path = remote_backups_dir + "/" + backup_file;
// Copy backup file from local to server // Copy backup file from local to server
@ -189,7 +188,7 @@ int backup(const std::vector<std::string> & args, bool silent) {
return 1; return 1;
} }
server_env env(server_name); server_env_manager env(server_name);
if (!env.is_valid()) { if (!env.is_valid()) {
std::cerr << "Error: Invalid server environment" << std::endl; std::cerr << "Error: Invalid server environment" << std::endl;
return 1; return 1;
@ -203,13 +202,13 @@ int backup(const std::vector<std::string> & args, bool silent) {
} }
// Check if basic installed stuff is in place. // Check if basic installed stuff is in place.
std::string remote_service_template_path = get_remote_service_template_path(server_name, service_name); std::string remote_service_template_path = remotepath::service_template(server_name, service_name);
std::string remote_command_script_file = remote_service_template_path + "/" + command + ".sh"; std::string remote_command_script_file = remote_service_template_path + "/" + command + ".sh";
std::string remote_service_config_path = get_remote_service_config_path(server_name, service_name); std::string remote_service_config_path = remotepath::service_config(server_name, service_name);
if (!env.check_remote_items_exist({ if (!env.check_remote_items_exist({
get_remote_service_path(server_name, service_name), remotepath::service(server_name, service_name),
remote_command_script_file, remote_command_script_file,
get_remote_service_env_file(server_name, service_name)}) remotefile::service_env(server_name, service_name)})
) )
{ {
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;
@ -218,7 +217,7 @@ int backup(const std::vector<std::string> & args, bool silent) {
} }
// Create backups directory on server if it doesn't exist // Create backups directory on server if it doesn't exist
std::string remote_backups_dir = get_remote_backups_path(server_name); std::string remote_backups_dir = remotepath::backups(server_name);
if (!silent) std::cout << "Remote backups directory on "<< server_name <<": " << remote_backups_dir << std::endl; if (!silent) 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 (!env.execute_ssh_command(mkdir_cmd)) { if (!env.execute_ssh_command(mkdir_cmd)) {
@ -227,7 +226,7 @@ int backup(const std::vector<std::string> & args, bool silent) {
} }
// Create backups directory locally if it doesn't exist // Create backups directory locally if it doesn't exist
std::string local_backups_dir = get_local_backup_path(); std::string local_backups_dir = localpath::backups_path();
if (local_backups_dir.empty()) { if (local_backups_dir.empty()) {
std::cerr << "Error: Local backups directory not found - is DropShell initialised?" << std::endl; std::cerr << "Error: Local backups directory not found - is DropShell initialised?" << std::endl;
return false; return false;

View File

@ -1,6 +1,6 @@
#include "config.hpp" #include "config.hpp"
#include "service_runner.hpp" #include "service_runner.hpp"
#include "server_env.hpp" #include "server_env_manager.hpp"
#include "templates.hpp" #include "templates.hpp"
#include "services.hpp" #include "services.hpp"
#include "utils/directories.hpp" #include "utils/directories.hpp"
@ -19,46 +19,43 @@ namespace fs = std::filesystem;
namespace dropshell { namespace dropshell {
service_runner::service_runner(const std::string& server_name, const std::string& service_name) : 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) mServerEnv(server_name), mServer(server_name), mService(service_name), mValid(false)
{ {
if (server_name.empty() || service_name.empty()) if (server_name.empty() || service_name.empty())
return; return;
// Initialize server environment // Initialize server environment
if (!m_server_env.is_valid()) if (!mServerEnv.is_valid())
return; return;
m_service_info = get_service_info(server_name, service_name); mServiceInfo = get_service_info(server_name, service_name);
mService = mServiceInfo.service_name;
mRemote_service_path = get_remote_service_path(m_server_name, m_service_info.service_name); mValid = !mServiceInfo.local_template_path.empty();
mRemote_service_config_path = get_remote_service_config_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);
mValid = !m_service_info.local_template_path.empty();
} }
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 " + mService + " (" + mServiceInfo.template_name + ") on " + mServer);
if (!m_server_env.is_valid()) return false; // should never hit this. if (!mServerEnv.is_valid()) return false; // should never hit this.
// Check if template exists // Check if template exists
template_info tinfo; template_info tinfo;
if (!get_template_info(m_service_info.template_name, tinfo)) if (!get_template_info(mServiceInfo.template_name, tinfo))
return false; return false;
// Create service directory // Create service directory
std::string mkdir_cmd = "mkdir -p " + quote(mRemote_service_path); std::string remote_service_path = remotepath::service(mServer, mService);
if (!m_server_env.execute_ssh_command(mkdir_cmd)) std::string mkdir_cmd = "mkdir -p " + quote(remote_service_path);
if (!mServerEnv.execute_ssh_command(mkdir_cmd))
{ {
std::cerr << "Failed to create service directory " << mRemote_service_path << std::endl; std::cerr << "Failed to create service directory " << remote_service_path << std::endl;
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 (!m_server_env.execute_ssh_command(check_rsync_cmd)) if (!mServerEnv.execute_ssh_command(check_rsync_cmd))
{ {
std::cerr << "rsync is not installed on the remote host" << std::endl; std::cerr << "rsync is not installed on the remote host" << std::endl;
return false; return false;
@ -66,13 +63,13 @@ bool service_runner::install() {
// Copy template files // Copy template files
{ {
std::cout << "Copying: [LOCAL] " << tinfo.local_template_path << std::endl << std::string(8,' ')<<"[REMOTE] " << mRemote_service_template_path << "/" << std::endl; std::cout << "Copying: [LOCAL] " << tinfo.local_template_path << std::endl << std::string(8,' ')<<"[REMOTE] " << remotepath::service_template(mServer, mService) << "/" << 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 " + mServerEnv.get_SSH_PORT() + "' " +
quote(tinfo.local_template_path + "/") + " "+ quote(tinfo.local_template_path + "/") + " "+
m_server_env.get_SSH_USER() + "@" + m_server_env.get_SSH_HOST() + ":" + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" +
quote(mRemote_service_template_path+"/"); quote(remotepath::service_template(mServer, mService)+"/");
//std::cout << std::endl << rsync_cmd << std::endl << std::endl; //std::cout << std::endl << rsync_cmd << std::endl << std::endl;
if (!m_server_env.execute_local_command(rsync_cmd)) if (!mServerEnv.execute_local_command(rsync_cmd))
{ {
std::cerr << "Failed to copy template files using rsync" << std::endl; std::cerr << "Failed to copy template files using rsync" << std::endl;
std::cerr << "Is rsync installed on the remote host?" << std::endl; std::cerr << "Is rsync installed on the remote host?" << std::endl;
@ -82,17 +79,17 @@ bool service_runner::install() {
// Copy service files (including service.env) // Copy service files (including service.env)
{ {
std::string local_service_path = get_local_service_path(m_server_name, m_service_info.service_name); std::string local_service_path = localpath::service(mServer,mService);
if (local_service_path.empty() || !fs::exists(local_service_path)) { if (local_service_path.empty() || !fs::exists(local_service_path)) {
std::cerr << "Error: Service directory not found: " << local_service_path << std::endl; std::cerr << "Error: Service directory not found: " << local_service_path << std::endl;
return false; return false;
} }
std::cout << "Copying: [LOCAL] " << local_service_path << std::endl <<std::string(8,' ')<<"[REMOTE] " << mRemote_service_config_path << std::endl; std::cout << "Copying: [LOCAL] " << local_service_path << std::endl <<std::string(8,' ')<<"[REMOTE] " << remotepath::service_config(mServer,mService) << 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 " + mServerEnv.get_SSH_PORT() + "' " +
quote(local_service_path + "/") + " "+ quote(local_service_path + "/") + " "+
m_server_env.get_SSH_USER() + "@" + m_server_env.get_SSH_HOST() + ":" + mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" +
quote(mRemote_service_config_path + "/"); quote(remotepath::service_config(mServer,mService) + "/");
if (!m_server_env.execute_local_command(rsync_cmd)) if (!mServerEnv.execute_local_command(rsync_cmd))
{ {
std::cerr << "Failed to copy service files using rsync" << std::endl; std::cerr << "Failed to copy service files using rsync" << std::endl;
return false; return false;
@ -101,8 +98,7 @@ bool service_runner::install() {
// Run install script // Run install script
{ {
std::vector<std::string> args; // not passed through yet. mServerEnv.run_remote_template_command(mService, "install", {});
m_server_env.run_remote_template_command(m_service_info.service_name, "install", args);
} }
// print health tick // print health tick
@ -111,23 +107,22 @@ 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 " + mService + " (" + mServiceInfo.template_name + ") on " + mServer);
if (!m_server_env.is_valid()) return false; // should never hit this. if (!mServerEnv.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 (!m_server_env.check_remote_dir_exists(mRemote_service_path)) { if (!mServerEnv.check_remote_dir_exists(remotepath::service(mServer, mService))) {
std::cerr << "Service is not installed: " << m_service_info.service_name << std::endl; std::cerr << "Service is not installed: " << mService << 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 = remotepath::service_template(mServer, mService) + "/_uninstall.sh";
bool script_exists = m_server_env.check_remote_file_exists(uninstall_script); bool script_exists = mServerEnv.check_remote_file_exists(uninstall_script);
if (script_exists) { if (script_exists) {
std::vector<std::string> args; // not passed through yet. if (!mServerEnv.run_remote_template_command(mService, "uninstall", {})) {
if (!m_server_env.run_remote_template_command(m_service_info.service_name, "uninstall", args)) {
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;
} }
@ -137,13 +132,13 @@ 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(remotepath::service(mServer, mService)) + "'";
if (!m_server_env.execute_ssh_command(rm_cmd)) { if (!mServerEnv.execute_ssh_command(rm_cmd)) {
std::cerr << "Failed to remove service directory" << std::endl; std::cerr << "Failed to remove service directory" << std::endl;
return false; return false;
} }
std::cout << "Service " << m_service_info.service_name << " successfully uninstalled from " << m_server_name << std::endl; std::cout << "Service " << mService << " successfully uninstalled from " << mServer << std::endl;
return true; return true;
} }
@ -152,13 +147,13 @@ 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.is_valid()) { if (!mServerEnv.is_valid()) {
std::cerr << "Error: Server service not initialized" << std::endl; std::cerr << "Error: Server service not initialized" << std::endl;
return false; return false;
} }
template_info tinfo; template_info tinfo;
if (!get_template_info(m_service_info.template_name, tinfo)) { if (!get_template_info(mServiceInfo.template_name, tinfo)) {
std::cerr << "Error: Template '" << m_service_info.template_name << "' not found" << std::endl; std::cerr << "Error: Template '" << mServiceInfo.template_name << "' not found" << std::endl;
return false; return false;
} }
@ -168,8 +163,8 @@ bool service_runner::run_command(const std::string& command) {
return true; return true;
} }
if (!template_command_exists(m_service_info.template_name, command)) { if (!template_command_exists(mServiceInfo.template_name, command)) {
std::cout << "No command script for " << m_service_info.template_name << " : " << command << std::endl; std::cout << "No command script for " << mServiceInfo.template_name << " : " << command << std::endl;
return true; // nothing to run. return true; // nothing to run.
} }
@ -177,20 +172,20 @@ bool service_runner::run_command(const std::string& command) {
if (command == "install") if (command == "install")
return install(); return install();
std::string script_path = mRemote_service_template_path + "/" + command + ".sh"; std::string script_path = remotepath::service_template(mServer, mService) + "/" + command + ".sh";
// Check if service directory exists // Check if service directory exists
if (!m_server_env.check_remote_dir_exists(mRemote_service_path)) { if (!mServerEnv.check_remote_dir_exists(remotepath::service(mServer, mService))) {
return false; return false;
} }
// Check if command script exists // Check if command script exists
if (!m_server_env.check_remote_file_exists(script_path)) { if (!mServerEnv.check_remote_file_exists(script_path)) {
return false; return false;
} }
// Check if env file exists // Check if env file exists
if (!m_server_env.check_remote_file_exists(mRemote_service_env_file)) { if (!mServerEnv.check_remote_file_exists(remotefile::service_env(mServer, mService))) {
return false; return false;
} }
@ -203,7 +198,7 @@ bool service_runner::run_command(const std::string& command) {
// Run the generic command // Run the generic command
std::vector<std::string> args; // not passed through yet. std::vector<std::string> args; // not passed through yet.
return m_server_env.run_remote_template_command(m_service_info.service_name, command, args); return mServerEnv.run_remote_template_command(mService, command, args);
} }
@ -220,7 +215,7 @@ std::map<std::string, ServiceStatus> service_runner::get_all_services_status(std
return status; return status;
} }
server_env env(server_name); server_env_manager env(server_name);
if (!env.is_valid()) { if (!env.is_valid()) {
std::cerr << "Error: Invalid server environment" << std::endl; std::cerr << "Error: Invalid server environment" << std::endl;
return status; return status;
@ -266,22 +261,22 @@ 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.is_valid()) { if (!mServerEnv.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;
} }
if (!m_server_env.check_remote_dir_exists(mRemote_service_path)) { if (!mServerEnv.check_remote_dir_exists(remotepath::service(mServer, mService))) {
return HealthStatus::NOTINSTALLED; return HealthStatus::NOTINSTALLED;
} }
std::string script_path = get_remote_service_template_path(m_server_name, m_service_info.service_name) + "/status.sh"; std::string script_path = remotepath::service_template(mServer, mService) + "/status.sh";
if (!m_server_env.check_remote_file_exists(script_path)) { if (!mServerEnv.check_remote_file_exists(script_path)) {
return HealthStatus::UNKNOWN; return HealthStatus::UNKNOWN;
} }
// Run status script, does not display output. // Run status script, does not display output.
if (!m_server_env.run_remote_template_command(m_service_info.service_name, "status", {}, true)) if (!mServerEnv.run_remote_template_command(mService, "status", {}, true))
return HealthStatus::UNHEALTHY; return HealthStatus::UNHEALTHY;
return HealthStatus::HEALTHY; return HealthStatus::HEALTHY;
} }
@ -320,13 +315,13 @@ std::string service_runner::HealthStatus2String(HealthStatus status)
bool service_runner::ensure_service_dropshell_files_up_to_date() bool service_runner::ensure_service_dropshell_files_up_to_date()
{ {
if (!m_server_env.is_valid()) { if (!mServerEnv.is_valid()) {
std::cerr << "Error: Server service not initialized" << std::endl; std::cerr << "Error: Server service not initialized" << std::endl;
return false; return false;
} }
// check if the service template and config are up to date on the remote server. // check if the service template and config are up to date on the remote server.
service_versions versions(m_server_name, m_service_info.service_name); service_versions versions(mServer, mService);
if (versions.remote_up_to_date()) if (versions.remote_up_to_date())
return true; return true;
@ -353,13 +348,13 @@ std::string service_runner::healthmark()
} }
void interactive_ssh(const std::string & server_name, const std::string & command) { void interactive_ssh(const std::string & server_name, const std::string & command) {
std::string serverpath = get_local_server_path(server_name); std::string serverpath = localpath::server(server_name);
if (serverpath.empty()) { if (serverpath.empty()) {
std::cerr << "Error: Server not found: " << server_name << std::endl; std::cerr << "Error: Server not found: " << server_name << std::endl;
return; return;
} }
server_env env(server_name); server_env_manager env(server_name);
if (!env.is_valid()) { if (!env.is_valid()) {
std::cerr << "Error: Invalid server environment file: " << server_name << std::endl; std::cerr << "Error: Invalid server environment file: " << server_name << std::endl;
return; return;
@ -384,7 +379,7 @@ void interactive_ssh(const std::string & server_name, const std::string & comman
void edit_server(const std::string &server_name) void edit_server(const std::string &server_name)
{ {
std::string serverpath = get_local_server_path(server_name); std::string serverpath = localpath::server(server_name);
if (serverpath.empty()) { if (serverpath.empty()) {
std::cerr << "Error: Server not found: " << server_name << std::endl; std::cerr << "Error: Server not found: " << server_name << std::endl;
return; return;
@ -412,9 +407,9 @@ void edit_file(const std::string &file_path, const std::string & aftertext)
bool service_runner::restore(std::string backup_file) bool service_runner::restore(std::string backup_file)
{ {
std::string command = "restore"; std::string command = "restore";
std::string script_path = mRemote_service_template_path + "/" + command + ".sh"; std::string script_path = remotepath::service_template(mServer, mService) + "/" + command + ".sh";
if (!template_command_exists(m_service_info.template_name, command)) { if (!template_command_exists(mServiceInfo.template_name, command)) {
std::cout << "No restore script for " << m_service_info.template_name << std::endl; std::cout << "No restore script for " << mServiceInfo.template_name << std::endl;
return true; // nothing to restore. return true; // nothing to restore.
} }
@ -428,25 +423,25 @@ bool service_runner::restore(std::string backup_file)
void service_runner::interactive_ssh_service() void service_runner::interactive_ssh_service()
{ {
std::set<std::string> used_commands = get_used_commands(m_server_name, m_service_info.service_name); std::set<std::string> used_commands = get_used_commands(mServer, mService);
if (used_commands.find("ssh") == used_commands.end()) { if (used_commands.find("ssh") == used_commands.end()) {
std::cerr << "Error: "<< m_service_info.service_name <<" does not support ssh" << std::endl; std::cerr << "Error: "<< mService <<" does not support ssh" << std::endl;
return; return;
} }
std::vector<std::string> args; // not passed through yet. std::vector<std::string> args; // not passed through yet.
m_server_env.run_remote_template_command(m_service_info.service_name, "ssh", args); mServerEnv.run_remote_template_command(mService, "ssh", args);
} }
void service_runner::edit_service_config() void service_runner::edit_service_config()
{ {
std::string config_file = get_local_service_env_path(m_server_name, m_service_info.service_name); std::string config_file = localfile::service_env(mServer,mService);
if (!fs::exists(config_file)) { if (!fs::exists(config_file)) {
std::cerr << "Error: Service config file not found: " << config_file << std::endl; std::cerr << "Error: Service config file not found: " << config_file << std::endl;
return; return;
} }
std::string aftertext = "To apply your changes, run:\n dropshell install " + m_server_name + " " + m_service_info.service_name; std::string aftertext = "To apply your changes, run:\n dropshell install " + mServer + " " + mService;
edit_file(config_file, aftertext); edit_file(config_file, aftertext);
} }

View File

@ -92,16 +92,12 @@ class service_runner {
void edit_service_config(); void edit_service_config();
private: private:
std::string m_server_name; std::string mServer;
server_env_manager m_server_env; server_env_manager mServerEnv;
ServiceInfo m_service_info; ServiceInfo mServiceInfo;
std::string mService;
bool mValid; bool mValid;
std::string mRemote_service_path;
std::string mRemote_service_config_path;
std::string mRemote_service_template_path;
std::string mRemote_service_env_file;
// Helper methods // Helper methods
public: public:
}; };

View File

@ -28,7 +28,7 @@ XXH64_hash_t service_versions::calculate_version_local_service_template()
XXH64_hash_t service_versions::calculate_version_local_config() XXH64_hash_t service_versions::calculate_version_local_config()
{ {
std::string config_path = get_local_service_path(m_server_name, m_service_name); std::string config_path = localpath::service(m_server_name, m_service_name);
if (config_path.empty() || !fs::exists(config_path)) { if (config_path.empty() || !fs::exists(config_path)) {
return 0; return 0;
} }

View File

@ -4,7 +4,7 @@
#include "templates.hpp" #include "templates.hpp"
#include "config.hpp" #include "config.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "server_env.hpp" #include "server_env_manager.hpp"
#include <iostream> #include <iostream>
#include <filesystem> #include <filesystem>
@ -18,15 +18,15 @@ std::vector<ServiceInfo> get_server_services_info(const std::string& server_name
if (server_name.empty()) if (server_name.empty())
return services; return services;
std::vector<std::string> local_config_directories = get_global_config()->get_local_config_directories(); std::vector<std::string> local_config_directories = gConfig().get_local_config_directories();
if (local_config_directories.empty()) { if (local_config_directories.empty()) {
std::cerr << "Error: No local config directories found" << std::endl; std::cerr << "Error: No local config directories found" << std::endl;
std::cerr << "Run 'dropshell init' to initialise DropShell" << std::endl; std::cerr << "Run 'dropshell init' to initialise DropShell" << std::endl;
return services; return services;
} }
for (int i = 0; i < getNumConfigDirectories(); i++) { for (int i = 0; i < localpath::num_config_directories(); i++) {
std::string serverpath = get_local_config_servers_path(i); std::string serverpath = localpath::config_servers(i);
if (serverpath.empty()) { if (serverpath.empty()) {
std::cerr << "Error: Server directory not found: " << serverpath << std::endl; std::cerr << "Error: Server directory not found: " << serverpath << std::endl;
return services; return services;
@ -58,16 +58,16 @@ ServiceInfo get_service_info(const std::string &server_name, const std::string &
service.service_name = service_name; service.service_name = service_name;
service.local_service_path = get_local_service_path(server_name, service_name); service.local_service_path = localpath::service(server_name, service_name);
if (service.local_service_path.empty()) if (service.local_service_path.empty())
return ServiceInfo(); return ServiceInfo();
// 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 = localfile::service_env(server_name, service_name);
envmanager env(local_service_env_path); envmanager env(local_service_env_path);
if (!env.load()) { if (!env.load()) {
if (std::filesystem::exists(get_local_service_path(server_name, service_name))) if (std::filesystem::exists(localpath::service(server_name, service_name)))
std::cerr << "Error: service malformed - service.env missing from " << local_service_env_path << std::endl; std::cerr << "Error: service malformed - service.env missing from " << local_service_env_path << std::endl;
else else
{ {
@ -129,7 +129,7 @@ std::set<std::string> list_backups(const std::string &service_name)
if (service_name.empty()) if (service_name.empty())
return backups; return backups;
std::string backups_dir = get_local_backup_path(); std::string backups_dir = localpath::backups_path();
if (backups_dir.empty()) if (backups_dir.empty())
return backups; return backups;
@ -150,7 +150,7 @@ bool create_service(const std::string &server_name, const std::string &template_
if (server_name.empty() || template_name.empty() || service_name.empty()) if (server_name.empty() || template_name.empty() || service_name.empty())
return false; return false;
std::string service_dir = get_local_service_path(server_name, service_name); std::string service_dir = localpath::service(server_name, service_name);
if (service_dir.empty()) if (service_dir.empty())
{ {

View File

@ -101,7 +101,7 @@
void create_template(const std::string& template_name) { void create_template(const std::string& template_name) {
// 1. Create a new directory in the user templates directory // 1. Create a new directory in the user templates directory
std::vector<std::string> local_config_directories = get_global_config()->get_local_config_directories(); std::vector<std::string> local_config_directories = gConfig().get_local_config_directories();
if (local_config_directories.empty()) { if (local_config_directories.empty()) {
std::cerr << "Error: No local config directories found" << std::endl; std::cerr << "Error: No local config directories found" << std::endl;
@ -115,15 +115,14 @@
return; return;
} }
std::string user_templates_dir = get_primary_local_config_path() + "/templates"; std::string new_template_path = localpath::config_templates() + "/" + template_name;
std::string new_template_path = user_templates_dir + "/" + template_name;
// Create the new template directory // Create the new template directory
std::filesystem::create_directories(new_template_path); std::filesystem::create_directories(new_template_path);
// 2. Copy the example template from the system templates directory // 2. Copy the example template from the system templates directory
std::string system_templates_dir = get_local_system_templates_path(); std::string system_templates_dir = localpath::system_templates();
std::string example_template_path = system_templates_dir + "/example"; std::string example_template_path = system_templates_dir + "/example-nginx";
if (!std::filesystem::exists(example_template_path)) { if (!std::filesystem::exists(example_template_path)) {
std::cerr << "Error: Example template not found at " << example_template_path << std::endl; std::cerr << "Error: Example template not found at " << example_template_path << std::endl;
@ -178,15 +177,15 @@
bool get_all_template_config_directories(std::vector<std::string> &template_config_directories) bool get_all_template_config_directories(std::vector<std::string> &template_config_directories)
{ {
template_config_directories.clear(); template_config_directories.clear();
for (int i = 0; i < getNumConfigDirectories(); i++) { for (int i = 0; i < localpath::num_config_directories(); i++) {
std::string config_templates_path = get_local_config_templates_path(i); std::string config_templates_path = localpath::config_templates(i);
if (config_templates_path.empty()) { if (config_templates_path.empty()) {
std::cerr << "Error: Templates directory not found: " << config_templates_path << std::endl; std::cerr << "Error: Templates directory not found: " << config_templates_path << std::endl;
return false; return false;
} }
template_config_directories.push_back(config_templates_path); template_config_directories.push_back(config_templates_path);
} }
template_config_directories.push_back(get_local_system_templates_path()); template_config_directories.push_back(localpath::system_templates());
return true; return true;
} }

View File

@ -105,6 +105,16 @@ namespace localpath {
// |-- (script files) // |-- (script files)
// |-- backups // |-- backups
namespace remotefile {
std::string service_env(const std::string &server_name, const std::string &service_name)
{
return remotepath::service_config(server_name, service_name) + "/service.env";
}
}
namespace remotepath { namespace remotepath {
std::string DROPSHELL_DIR(const std::string &server_name) std::string DROPSHELL_DIR(const std::string &server_name)
{ {
@ -147,6 +157,11 @@ namespace remotepath {
return (service_path.empty() ? "" : (service_path + "/service.env")); return (service_path.empty() ? "" : (service_path + "/service.env"));
} }
} // namespace remotepath } // namespace remotepath
// ------------------------------------------------------------------------------------------
// Utility functions
std::string get_parent(std::string path) std::string get_parent(std::string path)
{ {
if (path.empty()) if (path.empty())

View File

@ -57,13 +57,14 @@ namespace dropshell {
// |-- backups // |-- backups
// |-- services // |-- services
// |-- service name // |-- service name
// |-- config <-- this is passed as argument to all scripts // |-- config
// |-- service.env // |-- service.env
// |-- template // |-- template
// |-- (script files) // |-- (script files)
// |-- example // |-- example
// |-- service.env // |-- service.env
// |-- (other config files for specific server&service) // |-- (other config files for specific server&service)
namespace remotefile { namespace remotefile {
std::string service_env(const std::string &server_name, const std::string &service_name); std::string service_env(const std::string &server_name, const std::string &service_name);
} // namespace remotefile } // namespace remotefile