106 lines
4.7 KiB
C++
106 lines
4.7 KiB
C++
#include "command_registry.hpp"
|
|
#include "directories.hpp"
|
|
#include "shared_commands.hpp"
|
|
#include "templates.hpp"
|
|
|
|
#include "utils/assert.hpp"
|
|
#include "utils/utils.hpp"
|
|
#include "services.hpp"
|
|
|
|
namespace dropshell
|
|
{
|
|
|
|
int uninstall_handler(const CommandContext &ctx);
|
|
|
|
static std::vector<std::string> uninstall_name_list = {"uninstall", "remove"};
|
|
|
|
// Static registration
|
|
struct UninstallCommandRegister
|
|
{
|
|
UninstallCommandRegister()
|
|
{
|
|
CommandRegistry::instance().register_command({uninstall_name_list,
|
|
uninstall_handler,
|
|
shared_commands::std_autocomplete_allowall,
|
|
false, // hidden
|
|
true, // requires_config
|
|
true, // requires_install
|
|
2, // min_args (after command)
|
|
2, // max_args (after command)
|
|
"uninstall SERVER SERVICE|all",
|
|
"Uninstall a service on a server. Does not remove configuration or user data.",
|
|
// heredoc
|
|
R"(
|
|
Uninstall a service, leaving all configuration and data intact.
|
|
|
|
uninstall SERVER SERVICE Uninstall the given service on the given server.
|
|
uninstall SERVER all Uninstall all services on the given server.
|
|
|
|
Update and reinstall the service with install, or delete all configuration and data with destroy.
|
|
)"});
|
|
}
|
|
} uninstall_command_register;
|
|
|
|
namespace shared_commands {
|
|
bool uninstall_service(const ServerConfig & server_env, const std::string &service)
|
|
{
|
|
ASSERT(server_env.is_valid(), "Invalid server environment for " + server_env.get_server_name());
|
|
std::string server = server_env.get_server_name();
|
|
maketitle("Uninstalling " + service + " on " + server);
|
|
|
|
std::string user = server_env.get_user_for_service(service);
|
|
|
|
// 2. Check if service directory exists on server
|
|
if (!server_env.check_remote_dir_exists(remotepath(server, user).service(service), user))
|
|
{
|
|
error << "Service is not installed: " << service << std::endl;
|
|
return true; // Nothing to uninstall
|
|
}
|
|
|
|
// 3. Run uninstall script if it exists
|
|
std::string uninstall_script = remotepath(server, user).service_template(service) + "/uninstall.sh";
|
|
if (!server_env.run_remote_template_command(service, "uninstall", {}, false, {}))
|
|
warning << "Uninstall script failed, but continuing with directory removal" << std::endl;
|
|
|
|
// 4. Remove the service directory from the server, running in a docker container as root.
|
|
if (server_env.remove_remote_dir(remotepath(server, user).service(service), false, user))
|
|
{
|
|
ASSERT(!server_env.check_remote_dir_exists(remotepath(server, user).service(service), user), "Service directory still found on server after uninstall");
|
|
info << "Removed remote service directory " << remotepath(server, user).service(service) << std::endl;
|
|
}
|
|
else
|
|
warning << "Failed to remove remote service directory" << std::endl;
|
|
|
|
info << "Completed service " << service << " uninstall on " << server << std::endl;
|
|
return true;
|
|
}
|
|
} // namespace shared_commands
|
|
|
|
int uninstall_handler(const CommandContext &ctx)
|
|
{
|
|
if (ctx.args.size() < 1)
|
|
{
|
|
error << "uninstall requires a server and a service (or all)" << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
std::string server = safearg(ctx.args, 0);
|
|
|
|
if (safearg(ctx.args, 1) == "all")
|
|
{
|
|
// uninstall all services on the server
|
|
bool okay = true;
|
|
std::vector<LocalServiceInfo> services = get_server_services_info(server);
|
|
for (const auto &service : services)
|
|
{
|
|
if (!shared_commands::uninstall_service(server, service.service_name))
|
|
okay = false;
|
|
}
|
|
return okay ? 0 : 1;
|
|
}
|
|
|
|
std::string service = safearg(ctx.args, 1);
|
|
return shared_commands::uninstall_service(server, service) ? 0 : 1;
|
|
}
|
|
|
|
} // namespace dropshell
|