.
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 18s

This commit is contained in:
Your Name 2025-05-11 13:40:40 +12:00
parent 92b80d6bb7
commit 72df234290
2 changed files with 130 additions and 10 deletions

129
src/commands/install.cpp Normal file
View File

@ -0,0 +1,129 @@
#include "command_registry.hpp"
#include "config.hpp"
#include "utils/utils.hpp"
#include "service_runner.hpp"
#include "utils/directories.hpp"
#include "standard_autocomplete.hpp"
#include "templates.hpp"
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <sstream>
#include <filesystem>
#include <libassert/assert.hpp>
namespace dropshell {
void install_autocomplete(const CommandContext& ctx);
int install_handler(const CommandContext& ctx);
static std::vector<std::string> install_name_list={"install"};
// Static registration
struct InstallCommandRegister {
InstallCommandRegister() {
CommandRegistry::instance().register_command({
install_name_list,
install_handler,
install_autocomplete,
false, // hidden
false, // requires_config
2, // min_args (after command)
2, // max_args (after command)
"install SERVER SERVICE",
"Install/reinstall/update service(s). Safe/non-destructive.",
// heredoc
R"(
Install a service on a server.
install <server> <service> install the given service on the given server.
Note you need to create the service first with:
dropshell create-service <server> <template> <service>
)"
});
}
} install_command_register;
// ------------------------------------------------------------------------------------------------
// install service over ssh
// ------------------------------------------------------------------------------------------------
bool install_service(const std::string& server, const std::string& service, bool silent) {
maketitle("Installing " + mService + " (" + mServiceInfo.template_name + ") on " + mServer);
if (!mServerEnv.is_valid()) return false; // should never hit this.
// Check if template exists
template_info tinfo = gTemplateManager().get_template_info(mServiceInfo.template_name);
if (!tinfo.is_set())
return false;
// Create service directory
std::string remote_service_path = remotepath::service(mServer, mService);
std::string mkdir_cmd = "mkdir -p " + quote(remote_service_path);
if (!execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand(mkdir_cmd), cMode::Silent))
{
std::cerr << "Failed to create service directory " << remote_service_path << std::endl;
return false;
}
// Check if rsync is installed on remote host
std::string check_rsync_cmd = "which rsync";
if (!execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand(check_rsync_cmd), cMode::Silent))
{
std::cerr << "rsync is not installed on the remote host" << std::endl;
return false;
}
// Copy template files
std::cout << "Copying: [LOCAL] " << tinfo.local_template_path() << std::endl << std::string(8,' ')<<"[REMOTE] " << remotepath::service_template(mServer, mService) << "/" << std::endl;
if (!rsync_tree_to_remote(tinfo.local_template_path().string(), remotepath::service_template(mServer, mService), silent))
{
std::cerr << "Failed to copy template files using rsync" << std::endl;
return false;
}
// Copy service files
std::cout << "Copying: [LOCAL] " << localpath::service(mServer,mService) << std::endl << std::string(8,' ')<<"[REMOTE] " << remotepath::service_config(mServer,mService) << std::endl;
if (!rsync_tree_to_remote(localpath::service(mServer,mService), remotepath::service_config(mServer,mService), silent))
{
std::cerr << "Failed to copy service files using rsync" << std::endl;
return false;
}
// Run install script
{
mServerEnv.run_remote_template_command(mService, "install", {}, silent, {});
}
// print health tick
std::cout << "Health: " << healthtick() << std::endl;
return true;
}
// ------------------------------------------------------------------------------------------------
// install command implementation
// ------------------------------------------------------------------------------------------------
int install_handler(const CommandContext& ctx) {
if (ctx.args.size() < 2) {
std::cerr << "Error: install requires a server and service" << std::endl;
return 1;
}
std::string server = safearg(ctx.args,0);
std::string service = safearg(ctx.args,1);
return install_service(server, service, false) ? 0 : 1;
}
// ------------------------------------------------------------------------------------------------
// install command autocomplete
// ------------------------------------------------------------------------------------------------
void install_autocomplete(const CommandContext& ctx) {
std_autocomplete(install_name_list, ctx);
}
} // namespace dropshell

View File

@ -56,15 +56,6 @@ class service_runner {
std::string healthmark();
public:
// install the service over ssh, using the credentials from server.env (via server_env.hpp), by:
// 1. check if the server_name exists, and the service_name refers to a valid template
// 2. check if service_name is valid for the server_name
// 3. create the service directory on the server at {DROPSHELL_DIR}/{service_name}
// 3. copy the template files into {DROPSHELL_DIR}/{service_name}/template (from the templates directory for the specified server, using templates.hpp to identify the path)
// 4. copying the local service directory into {DROPSHELL_DIR}/{service_name}/config (from the server directory for the specified server)
// 5. running the install.sh script on the server, passing the {service_name}.env file as an argument
bool install(bool silent=false);
// uninstall the service over ssh, using the credentials from server.env (via server_env.hpp)
// 1. check if the server_name exists, and the service_name refers to a valid template
// 2. check if service_name is valid for the server_name