.
This commit is contained in:
parent
ac20fcec3d
commit
ce5a64a4c7
58
src/main.cpp
58
src/main.cpp
@ -40,14 +40,17 @@ bool print_help() {
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "Service commands: (if no service is specified, all services for the server are affected)" << std::endl;
|
std::cout << "Service commands: (if no service is specified, all services for the server are affected)" << std::endl;
|
||||||
std::cout << " install SERVER [SERVICE] Install/reinstall/update service(s). Non-destructive." << std::endl;
|
|
||||||
std::cout << " list [SERVER] [SERVICE] List status/details of all servers/server/service." << std::endl;
|
std::cout << " list [SERVER] [SERVICE] List status/details of all servers/server/service." << std::endl;
|
||||||
std::cout << " edit [SERVER] [SERVICE] Edit the configuration of dropshell/server/service." << std::endl;
|
std::cout << " edit [SERVER] [SERVICE] Edit the configuration of dropshell/server/service." << std::endl;
|
||||||
std::cout << " COMMAND SERVER [SERVICE] Run a command on service(s)." << std::endl;
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "Standard commands: install, uninstall, backup, restore, start, stop" << std::endl;
|
std::cout << " install SERVER [SERVICE] Install/reinstall/update service(s). Safe/non-destructive." << std::endl;
|
||||||
|
std::cout << " uninstall SERVER [SERVICE] Uninstalls the service on the remote server. Leaves data intact." << std::endl;
|
||||||
|
std::cout << " nuke SERVER SERVICE Nuke the service on the remote server, deleting all remote data." << std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << " ssh SERVER [SERVICE] Launch an interactive shell on a server or service" << std::endl;
|
std::cout << " COMMAND SERVER [SERVICE] Run a command on service(s), e.g." << std::endl;
|
||||||
|
std::cout << " backup, restore, start, stop, logs" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << " ssh SERVER SERVICE Launch an interactive shell on a server or service" << std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "Creation commands: (apply to the first local config directory)"<<std::endl;
|
std::cout << "Creation commands: (apply to the first local config directory)"<<std::endl;
|
||||||
std::cout << " create-template TEMPLATE" << std::endl;
|
std::cout << " create-template TEMPLATE" << std::endl;
|
||||||
@ -116,18 +119,17 @@ int main(int argc, char* argv[]) {
|
|||||||
if (gConfig().is_config_set())
|
if (gConfig().is_config_set())
|
||||||
gTemplateManager().load_sources();
|
gTemplateManager().load_sources();
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2)
|
||||||
print_help();
|
return print_help() ? 0 : 1;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
std::string cmd = argv[1];
|
std::string cmd = argv[1];
|
||||||
|
|
||||||
|
if (cmd == "autocomplete") {
|
||||||
std::vector<std::string> argvec;
|
std::vector<std::string> argvec;
|
||||||
for (int i=0; i<argc; i++)
|
for (int i=0; i<argc; i++)
|
||||||
argvec.push_back(argv[i]);
|
argvec.push_back(argv[i]);
|
||||||
|
|
||||||
|
|
||||||
if (cmd == "autocomplete")
|
|
||||||
return autocomplete(argvec) ? 0 : 1;
|
return autocomplete(argvec) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd == "help" || cmd == "-h" || cmd == "--help" || cmd== "h" || cmd=="halp")
|
if (cmd == "help" || cmd == "-h" || cmd == "--help" || cmd== "h" || cmd=="halp")
|
||||||
return print_help() ? 0 : 1;
|
return print_help() ? 0 : 1;
|
||||||
@ -216,31 +218,33 @@ int main(int argc, char* argv[]) {
|
|||||||
std::set<std::string> commands;
|
std::set<std::string> commands;
|
||||||
get_all_used_commands(commands);
|
get_all_used_commands(commands);
|
||||||
commands.merge(std::set<std::string>{"ssh","edit","_allservicesstatus"}); // handled by service_runner, but not in template_shell_commands.
|
commands.merge(std::set<std::string>{"ssh","edit","_allservicesstatus"}); // handled by service_runner, but not in template_shell_commands.
|
||||||
for (const auto& command : commands) {
|
|
||||||
if (cmd == command) {
|
|
||||||
ServerAndServices server_and_services;
|
|
||||||
if (!getCLIServices(safearg(argc, argv, 2), safearg(argc, argv, 3), server_and_services)) {
|
|
||||||
std::cerr << "Error: " << command << " command requires server name and optionally service name" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (commands.count(cmd)) {
|
||||||
|
std::set<std::string> safe_commands = {"nuke", "fullnuke"};
|
||||||
|
if (safe_commands.count(cmd) && argc < 4)
|
||||||
|
return die("Error: "+cmd+" requires a server name and service name. For safety, can't run on all services.");
|
||||||
|
|
||||||
|
// get all the services to run the command on.
|
||||||
|
ServerAndServices server_and_services;
|
||||||
|
if (!getCLIServices(safearg(argc, argv, 2), safearg(argc, argv, 3), server_and_services))
|
||||||
|
return die("Error: "+cmd+" command requires server name and optionally service name");
|
||||||
|
|
||||||
|
// run the command on each service.
|
||||||
for (const auto& service_info : server_and_services.servicelist) {
|
for (const auto& service_info : server_and_services.servicelist) {
|
||||||
service_runner runner(server_and_services.server_name, service_info.service_name);
|
service_runner runner(server_and_services.server_name, service_info.service_name);
|
||||||
if (!runner.isValid()) {
|
if (!runner.isValid())
|
||||||
std::cerr << "Error: Failed to initialize service" << std::endl;
|
return die("Error: Failed to initialize service");
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
std::vector<std::string> additional_args;
|
std::vector<std::string> additional_args;
|
||||||
for (int i=4; i<argc; i++)
|
for (int i=4; i<argc; i++)
|
||||||
additional_args.push_back(argv[i]);
|
additional_args.push_back(argv[i]);
|
||||||
if (!runner.run_command(command, additional_args)) {
|
if (!runner.run_command(cmd, additional_args))
|
||||||
std::cerr << command +" failed." << std::endl;
|
return die(cmd+" failed.");
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// success!
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Unknown command
|
// Unknown command
|
||||||
std::cerr << "Error: Unknown command '" << cmd << "'" << std::endl;
|
std::cerr << "Error: Unknown command '" << cmd << "'" << std::endl;
|
||||||
|
@ -167,26 +167,35 @@ bool service_runner::nuke()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Service " << mService << " successfully nuked from " << mServer << std::endl;
|
std::cout << "Service " << mService << " successfully nuked from " << mServer << std::endl;
|
||||||
std::cout << "Now deleteing local files..." << std::endl;
|
|
||||||
|
|
||||||
|
std::cout << "There's nothing left on the remote server." << std::endl;
|
||||||
|
std::cout << "You can remove the local files with:" << std::endl;
|
||||||
|
std::cout << " rm -rf " << localpath::service(mServer,mService) << std::endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool service_runner::fullnuke()
|
||||||
|
{
|
||||||
|
if (!mServerEnv.is_valid()) return false; // should never hit this.
|
||||||
|
|
||||||
std::string local_service_path = localpath::service(mServer,mService);
|
std::string local_service_path = localpath::service(mServer,mService);
|
||||||
if (local_service_path.empty() || !fs::exists(local_service_path)) {
|
if (local_service_path.empty() || !fs::exists(local_service_path)) {
|
||||||
std::cerr << "Error: Service directory not found: " << local_service_path << std::endl;
|
std::cerr << "Error: Service directory not found: " << local_service_path << std::endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string rm_cmd = "rm -rf " + quote(local_service_path);
|
std::string rm_cmd = "rm -rf " + quote(local_service_path);
|
||||||
if (!mServerEnv.execute_local_command(rm_cmd)) {
|
if (!mServerEnv.execute_local_command(rm_cmd)) {
|
||||||
std::cerr << "Failed to remove service directory" << std::endl;
|
std::cerr << "Failed to remove service directory" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Service " << mService << " successfully nuked from " << mServer << std::endl;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Run a command on the service.
|
// Run a command on the service.
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -78,7 +78,8 @@ class service_runner {
|
|||||||
bool restore(std::string backup_file, bool silent=false);
|
bool restore(std::string backup_file, bool silent=false);
|
||||||
|
|
||||||
// nuke the service
|
// nuke the service
|
||||||
bool nuke();
|
bool nuke(); // nukes all data for this service on the remote server
|
||||||
|
bool fullnuke(); // nuke all data for this service on the remote server, and then nukes all the local service definitionfiles
|
||||||
|
|
||||||
// launch an interactive ssh session on a server or service
|
// launch an interactive ssh session on a server or service
|
||||||
// replaces the current dropshell process with the ssh process
|
// replaces the current dropshell process with the ssh process
|
||||||
|
@ -42,12 +42,22 @@ _autocommandrun_path() {
|
|||||||
;;
|
;;
|
||||||
nuke)
|
nuke)
|
||||||
echo "Nuking path ${path}"
|
echo "Nuking path ${path}"
|
||||||
rm -rf ${path}
|
PATHPARENT=$(dirname ${path})
|
||||||
|
PATHCHILD=$(basename ${path})
|
||||||
|
if [ -d "${PATHPARENT}/${PATHCHILD}" ]; then
|
||||||
|
docker run --rm -v ${PATHPARENT}:/volume debian bash -c "rm -rf /volume/${PATHCHILD}"
|
||||||
|
else
|
||||||
|
echo "Path ${path} does not exist - nothing to nuke"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
backup)
|
backup)
|
||||||
local backup_folder="$3"
|
local backup_folder="$3"
|
||||||
echo "Backing up path ${path}"
|
echo "Backing up path ${path}"
|
||||||
tar -czvf ${backup_folder}/backup.tgz -C ${path} .
|
if [ -d "${path}" ]; then
|
||||||
|
docker run --rm -v ${path}:/path -v ${backup_folder}:/backup debian bash -c "tar -czvf /backup/backup.tgz -C /path . && chown -R $MYID:$MYGRP /backup"
|
||||||
|
else
|
||||||
|
echo "Path ${path} does not exist - nothing to backup"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
restore)
|
restore)
|
||||||
local backup_folder="$3"
|
local backup_folder="$3"
|
||||||
@ -70,9 +80,14 @@ _autocommandrun_file() {
|
|||||||
backup)
|
backup)
|
||||||
local backup_folder="$3"
|
local backup_folder="$3"
|
||||||
echo "Backing up file ${value}"
|
echo "Backing up file ${value}"
|
||||||
# get filename from path
|
|
||||||
local filename=$(basename ${value})
|
FILEPARENT=$(dirname ${value})
|
||||||
cp ${value} ${backup_folder}/${filename}
|
FILENAME=$(basename ${value})
|
||||||
|
if [ -f "${FILEPARENT}/${FILENAME}" ]; then
|
||||||
|
docker run --rm-v ${FILEPARENT}:/volume -v ${backup_folder}:/backup debian bash -c "cp /volume/${FILENAME} /backup/${FILENAME} && chown -R $MYID:$MYGRP /backup"
|
||||||
|
else
|
||||||
|
echo "File ${value} does not exist - nothing to backup"
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
restore)
|
restore)
|
||||||
local backup_folder="$3"
|
local backup_folder="$3"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user