This commit is contained in:
parent
92b80d6bb7
commit
72df234290
129
src/commands/install.cpp
Normal file
129
src/commands/install.cpp
Normal 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
|
@ -55,16 +55,7 @@ class service_runner {
|
||||
std::string healthtick();
|
||||
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);
|
||||
|
||||
public:
|
||||
// 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user