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
|
@ -56,15 +56,6 @@ class service_runner {
|
|||||||
std::string healthmark();
|
std::string healthmark();
|
||||||
|
|
||||||
public:
|
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)
|
// 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
|
// 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
|
// 2. check if service_name is valid for the server_name
|
||||||
|
Loading…
x
Reference in New Issue
Block a user