diff --git a/src/server_service.cpp b/src/server_service.cpp index 69cad8d..10eb211 100644 --- a/src/server_service.cpp +++ b/src/server_service.cpp @@ -41,252 +41,259 @@ std::vector get_server_services(const std::string& server_name) { return services; } -server_service::server_service() : m_server_name(""), m_service_name(""), m_server_env(nullptr) {} +class server_service { +private: + std::string m_server_name; + std::string m_service_name; + std::unique_ptr m_server_env; -bool server_service::init(const std::string& server_name, const std::string& service_name) { - std::string user_dir; - if (!get_user_directory(user_dir)) { - std::cerr << "Error: User directory not set" << std::endl; - return false; - } - - // Check if server exists - fs::path server_dir = fs::path(user_dir) / "servers" / server_name; - if (!fs::exists(server_dir)) { - std::cerr << "Error: Server '" << server_name << "' not found" << std::endl; - return false; - } - - // Check if service env file exists - fs::path service_env = server_dir / (service_name + ".env"); - if (!fs::exists(service_env)) { - std::cerr << "Error: Service environment file not found: " << service_env.string() << std::endl; - return false; - } - - // Initialize server environment - try { - m_server_env = std::make_unique(server_dir.string()); - if (!m_server_env->is_valid()) { - std::cerr << "Error: Invalid server environment" << std::endl; + bool check_initialized() const { + if (!m_server_env) { + std::cerr << "Error: Server service not initialized" << std::endl; 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_name = service_name; - return true; -} - -bool server_service::install() { - if (!m_server_env) { - std::cerr << "Error: Server service not initialized" << std::endl; - return false; - } - - // Check if template exists - template_manager tm; - template_info info; - if (!tm.get_template_info(m_service_name, info)) { - std::cerr << "Error: Template '" << m_service_name << "' not found" << std::endl; - return false; - } - - // Construct SSH command - std::stringstream ssh_cmd; - ssh_cmd << "ssh -p " << m_server_env->get_SSH_PORT() << " " - << m_server_env->get_SSH_USER() << "@" << m_server_env->get_SSH_HOST() << " "; - - // Create service directory - std::string service_dir = m_server_env->get_DROPSHELL_DIR() + "/" + m_service_name; - std::string mkdir_cmd = ssh_cmd.str() + "'mkdir -p " + service_dir + "/template'"; - if (system(mkdir_cmd.c_str()) != 0) { - std::cerr << "Error: Failed to create service directory" << std::endl; - return false; - } - - // Check if rsync is installed on remote host - std::string check_rsync_cmd = ssh_cmd.str() + "'which rsync > /dev/null 2>&1'"; - if (system(check_rsync_cmd.c_str()) != 0) { - std::cerr << "Error: rsync is not installed on the remote host" << std::endl; - return false; + return true; } - // Copy template files, preserving the directory structure and file permissions - std::cout << "Copying template files from " << info.path << " to " << service_dir << "/template/" << std::endl; - std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env->get_SSH_PORT() + "' " + - info.path + "/ " + - m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" + - service_dir + "/template/"; - if (system(rsync_cmd.c_str()) != 0) { - std::cerr << "Error: Failed to copy template files" << std::endl; - return false; - } - - // Copy service env file - std::string user_dir; - if (!get_user_directory(user_dir)) { - std::cerr << "Error: User directory not set" << std::endl; - return false; - } - fs::path service_env = fs::path(user_dir) / "servers" / m_server_name / (m_service_name + ".env"); - std::string scp_cmd = "scp -P " + m_server_env->get_SSH_PORT() + " " + - service_env.string() + " " + - m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" + - service_dir + "/" + m_service_name + ".env"; - if (system(scp_cmd.c_str()) != 0) { - std::cerr << "Error: Failed to copy service environment file" << std::endl; - return false; - } - - // Run install script - std::string install_cmd = ssh_cmd.str() + "'cd " + service_dir + "/template && /bin/bash install.sh " + - service_dir + "/" + m_service_name + ".env'"; - if (system(install_cmd.c_str()) != 0) { - std::cerr << "Error: Failed to run install script" << std::endl; - return false; - } - - return true; -} - -bool server_service::run_command(const std::string& command) { - if (!m_server_env) { - std::cerr << "Error: Server service not initialized" << std::endl; - return false; - } - - // Check if service directory exists - std::string service_dir = m_server_env->get_DROPSHELL_DIR() + "/" + m_service_name; - std::stringstream ssh_cmd; - ssh_cmd << "ssh -p " << m_server_env->get_SSH_PORT() << " " - << m_server_env->get_SSH_USER() << "@" << m_server_env->get_SSH_HOST() << " "; - - std::string script_dir = service_dir + "/template"; - std::string script_path_and_command = script_dir + "/" + command + ".sh"; - std::string env_path = service_dir + "/" + m_service_name + ".env"; - - // Check if service directory exists - std::string check_dir_cmd = ssh_cmd.str() + "'test -d " + service_dir + "'"; - if (system(check_dir_cmd.c_str()) != 0) { - std::cerr << "Error: Service directory not found on server - has it been installed?" << std::endl; - return false; - } - - // Check if command script exists - std::string check_script_cmd = ssh_cmd.str() + "'test -f " + script_path_and_command + "'"; - if (system(check_script_cmd.c_str()) != 0) { - std::cerr << "Error: Command script '" << command << ".sh' not found" << std::endl; - return false; - } - - // Check if env file exists - std::string check_env_cmd = ssh_cmd.str() + "'test -f " + env_path + "'"; - if (system(check_env_cmd.c_str()) != 0) { - std::cerr << "Error: Service environment file not found on server" << std::endl; - return false; - } - - // Run the command - std::string run_cmd = ssh_cmd.str() + "'cd " + script_dir + - " && /bin/bash " + script_path_and_command + " "+ env_path + "'"; - if (system(run_cmd.c_str()) != 0) { - std::cerr << "Command returned error code: " << script_path_and_command << std::endl; - return false; - } - - return true; -} - -bool server_service::backup() { - if (!m_server_env) { - std::cerr << "Error: Server service not initialized" << std::endl; - return false; - } - - // Check if service directory exists - std::string service_dir = m_server_env->get_DROPSHELL_DIR() + "/" + m_service_name; - std::stringstream ssh_cmd; - ssh_cmd << "ssh -p " << m_server_env->get_SSH_PORT() << " " - << m_server_env->get_SSH_USER() << "@" << m_server_env->get_SSH_HOST() << " "; - - std::string script_dir = service_dir + "/template"; - std::string script_path = script_dir + "/backup.sh"; - std::string env_path = service_dir + "/" + m_service_name + ".env"; - - // Check if service directory exists - std::string check_dir_cmd = ssh_cmd.str() + "'test -d " + service_dir + "'"; - if (system(check_dir_cmd.c_str()) != 0) { - std::cerr << "Error: Service directory not found on server - has it been installed?" << std::endl; - return false; - } - - // Check if backup script exists - std::string check_script_cmd = ssh_cmd.str() + "'test -f " + script_path + "'"; - if (system(check_script_cmd.c_str()) != 0) { - std::cerr << "Error: Backup script not found" << std::endl; - return false; - } - - // Check if env file exists - std::string check_env_cmd = ssh_cmd.str() + "'test -f " + env_path + "'"; - if (system(check_env_cmd.c_str()) != 0) { - std::cerr << "Error: Service environment file not found on server" << std::endl; - return false; + std::string construct_ssh_command() const { + std::stringstream ssh_cmd; + ssh_cmd << "ssh -p " << m_server_env->get_SSH_PORT() << " " + << m_server_env->get_SSH_USER() << "@" << m_server_env->get_SSH_HOST() << " "; + return ssh_cmd.str(); } - // Create backups directory on server if it doesn't exist - std::string server_backups_dir = m_server_env->get_DROPSHELL_DIR() + "/backups"; - std::string mkdir_cmd = ssh_cmd.str() + "'mkdir -p " + server_backups_dir + "'"; - if (system(mkdir_cmd.c_str()) != 0) { - std::cerr << "Error: Failed to create backups directory on server" << std::endl; - return false; + std::string get_service_dir() const { + return m_server_env->get_DROPSHELL_DIR() + "/" + m_service_name; } - // Create backups directory locally if it doesn't exist - std::string user_dir; - if (!get_user_directory(user_dir)) { - std::cerr << "Error: User directory not set" << std::endl; - return false; - } - fs::path local_backups_dir = fs::path(user_dir) / "backups"; - if (!fs::exists(local_backups_dir)) { - fs::create_directories(local_backups_dir); + std::string get_script_dir() const { + return get_service_dir() + "/template"; } - // Get current datetime for backup filename - auto now = std::chrono::system_clock::now(); - auto time = std::chrono::system_clock::to_time_t(now); - std::stringstream datetime; - datetime << std::put_time(std::localtime(&time), "%Y-%m-%d_%H-%M-%S"); - - // Construct backup filename - std::string backup_filename = m_server_name + "-" + m_service_name + "-" + datetime.str() + ".tgz"; - std::string server_backup_path = server_backups_dir + "/" + backup_filename; - std::string local_backup_path = (local_backups_dir / backup_filename).string(); - - // Run backup script - std::string backup_cmd = ssh_cmd.str() + "'cd " + script_dir + - " && /bin/bash backup.sh " + env_path + " " + server_backup_path + "'"; - if (system(backup_cmd.c_str()) != 0) { - std::cerr << "Error: Backup script failed" << std::endl; - return false; + std::string get_env_path() const { + return get_service_dir() + "/" + m_service_name + ".env"; } - // Copy backup file from server to local - std::string scp_cmd = "scp -P " + m_server_env->get_SSH_PORT() + " " + - m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" + - server_backup_path + " " + local_backup_path; - if (system(scp_cmd.c_str()) != 0) { - std::cerr << "Error: Failed to copy backup file from server" << std::endl; - return false; + bool check_service_dir_exists(const std::string& ssh_cmd) const { + std::string check_dir_cmd = ssh_cmd + "'test -d " + get_service_dir() + "'"; + if (system(check_dir_cmd.c_str()) != 0) { + std::cerr << "Error: Service directory not found on server - has it been installed?" << std::endl; + return false; + } + return true; } - std::cout << "Backup created successfully: " << local_backup_path << std::endl; - return true; -} + bool check_env_file_exists(const std::string& ssh_cmd) const { + std::string check_env_cmd = ssh_cmd + "'test -f " + get_env_path() + "'"; + if (system(check_env_cmd.c_str()) != 0) { + std::cerr << "Error: Service environment file not found on server" << std::endl; + return false; + } + return true; + } + + bool run_remote_command(const std::string& ssh_cmd, const std::string& command, const std::string& error_msg) const { + if (system(command.c_str()) != 0) { + std::cerr << "Error: " << error_msg << std::endl; + return false; + } + return true; + } + +public: + server_service() : m_server_name(""), m_service_name(""), m_server_env(nullptr) {} + + bool init(const std::string& server_name, const std::string& service_name) { + std::string user_dir; + if (!get_user_directory(user_dir)) { + std::cerr << "Error: User directory not set" << std::endl; + return false; + } + + // Check if server exists + fs::path server_dir = fs::path(user_dir) / "servers" / server_name; + if (!fs::exists(server_dir)) { + std::cerr << "Error: Server '" << server_name << "' not found" << std::endl; + return false; + } + + // Check if service env file exists + fs::path service_env = server_dir / (service_name + ".env"); + if (!fs::exists(service_env)) { + std::cerr << "Error: Service environment file not found: " << service_env.string() << std::endl; + return false; + } + + // Initialize server environment + try { + m_server_env = std::make_unique(server_dir.string()); + if (!m_server_env->is_valid()) { + std::cerr << "Error: Invalid server environment" << std::endl; + 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_name = service_name; + return true; + } + + bool install() { + if (!check_initialized()) return false; + + // Check if template exists + template_manager tm; + template_info info; + if (!tm.get_template_info(m_service_name, info)) { + std::cerr << "Error: Template '" << m_service_name << "' not found" << std::endl; + return false; + } + + std::string ssh_cmd = construct_ssh_command(); + std::string service_dir = get_service_dir(); + + // Create service directory + std::string mkdir_cmd = ssh_cmd + "'mkdir -p " + service_dir + "/template'"; + if (!run_remote_command(ssh_cmd, mkdir_cmd, "Failed to create service directory")) { + return false; + } + + // Check if rsync is installed on remote host + std::string check_rsync_cmd = ssh_cmd + "'which rsync > /dev/null 2>&1'"; + if (!run_remote_command(ssh_cmd, check_rsync_cmd, "rsync is not installed on the remote host")) { + return false; + } + + // Copy template files + std::cout << "Copying template files from " << info.path << " to " << service_dir << "/template/" << std::endl; + std::string rsync_cmd = "rsync --delete -zrpc -e 'ssh -p " + m_server_env->get_SSH_PORT() + "' " + + info.path + "/ " + + m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" + + service_dir + "/template/"; + if (!run_remote_command(ssh_cmd, rsync_cmd, "Failed to copy template files")) { + return false; + } + + // Copy service env file + std::string user_dir; + if (!get_user_directory(user_dir)) { + std::cerr << "Error: User directory not set" << std::endl; + return false; + } + fs::path service_env = fs::path(user_dir) / "servers" / m_server_name / (m_service_name + ".env"); + std::string scp_cmd = "scp -P " + m_server_env->get_SSH_PORT() + " " + + service_env.string() + " " + + m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" + + service_dir + "/" + m_service_name + ".env"; + if (!run_remote_command(ssh_cmd, scp_cmd, "Failed to copy service environment file")) { + return false; + } + + // Run install script + std::string install_cmd = ssh_cmd + "'cd " + service_dir + "/template && /bin/bash _install.sh " + + service_dir + "/" + m_service_name + ".env'"; + if (!run_remote_command(ssh_cmd, install_cmd, "Failed to run install script")) { + return false; + } + + return true; + } + + bool run_command(const std::string& command) { + if (!check_initialized()) return false; + + std::string ssh_cmd = construct_ssh_command(); + std::string script_dir = get_script_dir(); + std::string script_path_and_command = script_dir + "/" + command + ".sh"; + + if (!check_service_dir_exists(ssh_cmd)) return false; + + // Check if command script exists + std::string check_script_cmd = ssh_cmd + "'test -f " + script_path_and_command + "'"; + if (!run_remote_command(ssh_cmd, check_script_cmd, "Command script '" + command + ".sh' not found")) { + return false; + } + + if (!check_env_file_exists(ssh_cmd)) return false; + + // Run the command + std::string run_cmd = ssh_cmd + "'cd " + script_dir + + " && /bin/bash " + script_path_and_command + " " + get_env_path() + "'"; + if (!run_remote_command(ssh_cmd, run_cmd, "Command returned error code: " + script_path_and_command)) { + return false; + } + + return true; + } + + bool backup() { + if (!check_initialized()) return false; + + std::string ssh_cmd = construct_ssh_command(); + std::string script_dir = get_script_dir(); + std::string script_path = script_dir + "/_backup.sh"; + + if (!check_service_dir_exists(ssh_cmd)) return false; + + // Check if backup script exists + std::string check_script_cmd = ssh_cmd + "'test -f " + script_path + "'"; + if (!run_remote_command(ssh_cmd, check_script_cmd, "Backup script not found")) { + return false; + } + + if (!check_env_file_exists(ssh_cmd)) return false; + + // Create backups directory on server if it doesn't exist + std::string server_backups_dir = m_server_env->get_DROPSHELL_DIR() + "/backups"; + std::string mkdir_cmd = ssh_cmd + "'mkdir -p " + server_backups_dir + "'"; + if (!run_remote_command(ssh_cmd, mkdir_cmd, "Failed to create backups directory on server")) { + return false; + } + + // Create backups directory locally if it doesn't exist + std::string user_dir; + if (!get_user_directory(user_dir)) { + std::cerr << "Error: User directory not set" << std::endl; + return false; + } + fs::path local_backups_dir = fs::path(user_dir) / "backups"; + if (!fs::exists(local_backups_dir)) { + fs::create_directories(local_backups_dir); + } + + // Get current datetime for backup filename + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + std::stringstream datetime; + datetime << std::put_time(std::localtime(&time), "%Y-%m-%d_%H-%M-%S"); + + // Construct backup filename + std::string backup_filename = m_server_name + "-" + m_service_name + "-" + datetime.str() + ".tgz"; + std::string server_backup_path = server_backups_dir + "/" + backup_filename; + std::string local_backup_path = (fs::path(user_dir) / "backups" / backup_filename).string(); + + // Run backup script + std::string backup_cmd = ssh_cmd + "'cd " + script_dir + + " && /bin/bash backup.sh " + get_env_path() + " " + server_backup_path + "'"; + if (!run_remote_command(ssh_cmd, backup_cmd, "Backup script failed")) { + return false; + } + + // Copy backup file from server to local + std::string scp_cmd = "scp -P " + m_server_env->get_SSH_PORT() + " " + + m_server_env->get_SSH_USER() + "@" + m_server_env->get_SSH_HOST() + ":" + + server_backup_path + " " + local_backup_path; + if (system(scp_cmd.c_str()) != 0) { + std::cerr << "Error: Failed to copy backup file from server" << std::endl; + return false; + } + + std::cout << "Backup created successfully: " << local_backup_path << std::endl; + return true; + } +}; } // namespace dropshell \ No newline at end of file diff --git a/templates/squashkiwi/backup.sh b/templates/squashkiwi/_backup.sh similarity index 100% rename from templates/squashkiwi/backup.sh rename to templates/squashkiwi/_backup.sh diff --git a/templates/squashkiwi/install.sh b/templates/squashkiwi/_install.sh similarity index 92% rename from templates/squashkiwi/install.sh rename to templates/squashkiwi/_install.sh index 9841d76..3ed5962 100755 --- a/templates/squashkiwi/install.sh +++ b/templates/squashkiwi/_install.sh @@ -32,8 +32,9 @@ if ! docker pull "$IMAGE_REGISTRY/$IMAGE_REPO:$IMAGE_TAG"; then fi echo "Successfully pulled the docker image from the registry" -# start the container +# remove and restart, as the env may have changed. _stop_container $CONTAINER_NAME +_remove_container $CONTAINER_NAME create_and_start_container || die "Failed to start container ${CONTAINER_NAME}" echo "Installation complete"