diff --git a/src/main.cpp b/src/main.cpp index 90f42e3..5462e7e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,6 +29,7 @@ void print_help() { std::cout << std::endl; std::cout << "Service commands: (if no service is specified, all services for the server are affected)" << std::endl; std::cout << " install SERVER [SERVICE] Install/reinstall/update service(s). Non-destructive." << std::endl; + std::cout << " edit SERVER [SERVICE] Edit the configuration of the server/service." << std::endl; std::cout << " COMMAND SERVER [SERVICE] Run a command on service(s)." << std::endl; std::cout << std::endl; std::cout << "Standard commands: install, uninstall, backup, restore, start, stop" << std::endl; @@ -114,25 +115,26 @@ int main(int argc, char* argv[]) { } // auto completion stuff. - std::set commands; + std::set template_shell_commands, full_command_set; std::vector servers = dropshell::get_configured_servers(); for (const auto& server : servers) { std::vector services = dropshell::get_server_services_info(server.name); for (const auto& service : services) - commands.merge(dropshell::get_used_commands(server.name, service.service_name)); + template_shell_commands.merge(dropshell::get_used_commands(server.name, service.service_name)); } - if (cmd == "autocomplete_list_commands") { - commands.merge(std::set{ - "help","init" + if (cmd == "autocomplete_list_commands") { // add in commands handled here, not by the template shell scripts. + std::set full_command_set = template_shell_commands; + full_command_set.merge(std::set{ + "help","init" // these are always available. }); if (cfg->is_config_set()) - commands.merge(std::set{ - "server","templates","create-service","create-template","create-server","ssh" + full_command_set.merge(std::set{ + "server","templates","create-service","create-template","create-server","edit","ssh" // only if we have a config. }); - for (const auto& command : commands) { + for (const auto& command : full_command_set) { std::cout << command << std::endl; } return 0; @@ -233,7 +235,19 @@ int main(int argc, char* argv[]) { return 0; } + if (cmd == "edit" && argc < 4) { + if (argc < 3) + { + std::cerr << "Error: edit requires a server name and optionally service name" << std::endl; + return 1; + } + dropshell::edit_server(argv[2]); + return 0; + } + // handle running a command. + std::set commands = template_shell_commands; + commands.merge(std::set{"ssh","edit"}); // handled by service_runner, but not in template_shell_commands. for (const auto& command : commands) { if (cmd == command) { std::string server_name; @@ -260,6 +274,12 @@ int main(int argc, char* argv[]) { // Unknown command std::cerr << "Error: Unknown command '" << cmd << "'" << std::endl; + std::cerr << "Valid commands: "; + for (const auto& command : commands) { + std::cerr << command << " "; + } + std::cerr << std::endl; + // print help dropshell::print_help(); return 1; diff --git a/src/servers.cpp b/src/servers.cpp index 0b8ff3d..a121c7c 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -157,8 +157,8 @@ void create_server(const std::string &server_name) } // 2. create a new directory in the user config directory - std::string config_dir = get_local_config_path(0); - std::string server_dir = config_dir + "/" + server_name; + std::string config_servers_dir = get_local_config_servers_path(0); + std::string server_dir = config_servers_dir + "/" + server_name; fs::create_directory(server_dir); // 3. create a template server.env file in the server directory @@ -169,21 +169,21 @@ void create_server(const std::string &server_name) server_env_file << "SSH_USER=" << user << std::endl; server_env_file << "SSH_PORT=" << 22 << std::endl; server_env_file << std::endl; - server_env_file << "DROPSHELL_PATH=/home/"+user+"/.dropshell" << std::endl; + server_env_file << "DROPSHELL_DIR=/home/"+user+"/.dropshell" << std::endl; server_env_file.close(); // 4. add dropshell-agent service to server std::string service_dir = server_dir + "/dropshell-agent"; fs::create_directory(service_dir); std::string service_env_path = service_dir + "/service.env"; - std::filesystem::copy(get_local_system_templates_path() + "/dropshell-agent/service.env", service_env_path); + std::filesystem::copy(get_local_system_templates_path() + "/dropshell-agent/example/service.env", service_env_path); std::cout << "Server created successfully: " << server_name << std::endl; - std::cout << "Please edit the server.env file to configure the server, it is located at: "< used_commands = get_used_commands(m_server_name, m_service_info.service_name); @@ -526,6 +569,17 @@ void service_runner::interactive_ssh_service() interactive_ssh(m_server_name, "/bin/bash -c '"+command+"'"); } +void service_runner::edit_service_config() +{ + std::string config_file = get_local_service_env_path(m_server_name, m_service_info.service_name); + if (!fs::exists(config_file)) { + std::cerr << "Error: Service config file not found: " << config_file << std::endl; + return; + } + std::string aftertext = "To apply your changes, run:\n dropshell install " + m_server_name + " " + m_service_info.service_name; + + edit_file(config_file, aftertext); +} } // namespace dropshell \ No newline at end of file diff --git a/src/service_runner.hpp b/src/service_runner.hpp index 7f6e8ca..ddfeb62 100644 --- a/src/service_runner.hpp +++ b/src/service_runner.hpp @@ -84,6 +84,9 @@ class service_runner { // replaces the current dropshell process with the ssh process void interactive_ssh_service(); + // edit the service configuration file + void edit_service_config(); + private: std::string m_server_name; ServiceInfo m_service_info; @@ -108,7 +111,11 @@ class service_runner { static bool execute_local_command_and_capture_output(const std::string& command, std::string & output); }; - void interactive_ssh(const std::string & server_name, const std::string & command); + +// other utility routines (not specific to service_runner) +void interactive_ssh(const std::string & server_name, const std::string & command); +void edit_server(const std::string & server_name); +void edit_file(const std::string & file_path, const std::string & aftertext); } // namespace dropshell diff --git a/src/services.cpp b/src/services.cpp index 63cdb06..4e02ace 100644 --- a/src/services.cpp +++ b/src/services.cpp @@ -149,11 +149,11 @@ bool create_service(const std::string &server_name, const std::string &service_n // copy the template example files to the service directory recursive_copy(tinfo.path+"/example", service_dir); - std::cout << "Service created successfully: " << service_name << std::endl; - std::cout << "Please edit the service.env file to configure the service, it is located at: "< get_used_commands(const std::string& server_name, const std::string& service_name); bool create_service(const std::string& server_name, const std::string& service_name); - - void interactive_ssh(const std::string & server_name, const std::string & service_name, const std::string & command); - } // namespace dropshell