From 2bcf6c530d0e1f3af8c3b97b65331723ff9bd103 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 9 May 2025 18:44:43 +1200 Subject: [PATCH] Compiles but no good --- src/server_env_manager.cpp | 13 ++- src/server_env_manager.hpp | 6 +- src/service_runner.cpp | 26 +++-- src/service_runner.hpp | 2 +- templates/dropshell-agent/nuke.sh | 1 - .../dropshell-agent/shared/_autocommands.sh | 99 +++++++------------ templates/example-nginx/backup.sh | 6 +- templates/example-nginx/restore.sh | 6 +- templates/simple-object-storage/backup.sh | 4 +- templates/simple-object-storage/restore.sh | 4 +- templates/squashkiwi/backup.sh | 4 +- templates/squashkiwi/restore.sh | 4 +- 12 files changed, 76 insertions(+), 99 deletions(-) delete mode 100644 templates/dropshell-agent/nuke.sh diff --git a/src/server_env_manager.cpp b/src/server_env_manager.cpp index b9ec6a8..85a7a51 100644 --- a/src/server_env_manager.cpp +++ b/src/server_env_manager.cpp @@ -161,21 +161,30 @@ bool server_env_manager::check_remote_items_exist(const std::vector return true; } -bool server_env_manager::run_remote_template_command(const std::string &service_name, const std::string &command, std::vector args, bool silent) const +bool server_env_manager::run_remote_template_command(const std::string &service_name, const std::string &command, std::vector args, bool silent, std::map extra_env_vars) const { sCommand scommand = construct_standard_template_run_cmd(service_name, command, args, silent); + + // add the extra env vars to the command + for (const auto& [key, value] : extra_env_vars) + scommand.add_env_var(key, value); + if (scommand.get_command_to_run().empty()) return false; cMode mode = (command=="ssh") ? (cMode::Interactive | cMode::RawCommand) : cMode::Silent; return execute_ssh_command(get_SSH_INFO(), scommand, mode); } -bool server_env_manager::run_remote_template_command_and_capture_output(const std::string &service_name, const std::string &command, std::vector args, std::string &output, bool silent) const +bool server_env_manager::run_remote_template_command_and_capture_output(const std::string &service_name, const std::string &command, std::vector args, std::string &output, bool silent, std::map extra_env_vars) const { sCommand scommand = construct_standard_template_run_cmd(service_name, command, args, false); if (scommand.get_command_to_run().empty()) return false; + // add the extra env vars to the command + for (const auto& [key, value] : extra_env_vars) + scommand.add_env_var(key, value); + cMode mode = cMode::CaptureOutput | cMode::RawCommand; return execute_ssh_command(get_SSH_INFO(), scommand, mode, &output); } diff --git a/src/server_env_manager.hpp b/src/server_env_manager.hpp index 41387c4..8964bbc 100644 --- a/src/server_env_manager.hpp +++ b/src/server_env_manager.hpp @@ -53,8 +53,10 @@ class server_env_manager { bool check_remote_file_exists(const std::string& file_path) const; bool check_remote_items_exist(const std::vector& file_paths) const; - bool run_remote_template_command(const std::string& service_name, const std::string& command, std::vector args, bool silent=false) const; - bool run_remote_template_command_and_capture_output(const std::string& service_name, const std::string& command, std::vector args, std::string & output, bool silent=false) const; + bool run_remote_template_command(const std::string& service_name, const std::string& command, + std::vector args, bool silent, std::map extra_env_vars) const; + bool run_remote_template_command_and_capture_output(const std::string& service_name, const std::string& command, + std::vector args, std::string & output, bool silent, std::map extra_env_vars) const; private: sCommand construct_standard_template_run_cmd(const std::string& service_name, const std::string& command, std::vector args, bool silent) const; diff --git a/src/service_runner.cpp b/src/service_runner.cpp index ea0d7ec..8229443 100644 --- a/src/service_runner.cpp +++ b/src/service_runner.cpp @@ -107,7 +107,7 @@ bool service_runner::install(bool silent) { // Run install script { - mServerEnv.run_remote_template_command(mService, "install", {}); + mServerEnv.run_remote_template_command(mService, "install", {}, silent, {}); } // print health tick @@ -131,7 +131,7 @@ bool service_runner::uninstall(bool silent) { bool script_exists = mServerEnv.check_remote_file_exists(uninstall_script); if (script_exists) { - if (!mServerEnv.run_remote_template_command(mService, "uninstall", {})) { + if (!mServerEnv.run_remote_template_command(mService, "uninstall", {}, silent, {})) { std::cerr << "Warning: Uninstall script failed, but continuing with directory removal" << std::endl; } @@ -156,13 +156,9 @@ bool service_runner::nuke(bool silent) maketitle("Nuking " + mService + " (" + mServiceInfo.template_name + ") on " + mServer); if (!mServerEnv.is_valid()) return false; // should never hit this. - - std::map env_vars; - if (!get_all_service_env_vars(mServer, mService, env_vars)) - std::cerr << "Warning: Failed to get all service env vars for " << mService << std::endl; std::string remote_service_path = remotepath::service(mServer, mService); - bool okay = mServerEnv.run_remote_template_command("dropshell-agent", "_nuke_other", {mService, remote_service_path}, silent); + bool okay = mServerEnv.run_remote_template_command("dropshell-agent", "_nuke_other", {mService, remote_service_path}, silent, {}); if (!okay) { std::cerr << "Warning: Nuke script failed" << std::endl; @@ -206,7 +202,7 @@ bool service_runner::fullnuke() // ------------------------------------------------------------------------------------------------ // Run a command on the service. // ------------------------------------------------------------------------------------------------ -bool service_runner::run_command(const std::string& command, std::vector additional_args) { +bool service_runner::run_command(const std::string& command, std::vector additional_args, std::map env_vars) { if (!mServerEnv.is_valid()) { std::cerr << "Error: Server service not initialized" << std::endl; return false; @@ -282,7 +278,7 @@ bool service_runner::run_command(const std::string& command, std::vector args; // not passed through yet. - return mServerEnv.run_remote_template_command(mService, command, args); + return mServerEnv.run_remote_template_command(mService, command, args, false, env_vars); } @@ -306,7 +302,7 @@ std::map service_runner::get_all_services_status(std } std::string output; - if (!env.run_remote_template_command_and_capture_output(service_name, command, {}, output)) + if (!env.run_remote_template_command_and_capture_output(service_name, command, {}, output, true, {})) return status; std::stringstream ss(output); @@ -360,7 +356,7 @@ HealthStatus service_runner::is_healthy() } // Run status script, does not display output. - if (!mServerEnv.run_remote_template_command(mService, "status", {}, true)) + if (!mServerEnv.run_remote_template_command(mService, "status", {}, true, {})) return HealthStatus::UNHEALTHY; return HealthStatus::HEALTHY; } @@ -477,7 +473,7 @@ bool service_runner::interactive_ssh_service() } std::vector args; // not passed through yet. - return mServerEnv.run_remote_template_command(mService, "ssh", args); + return mServerEnv.run_remote_template_command(mService, "ssh", args, false, {}); } void service_runner::edit_service_config() @@ -578,7 +574,7 @@ bool service_runner::restore(std::string backup_file, bool silent) } cRemoteTempFolder remote_temp_folder(mServerEnv); - mServerEnv.run_remote_template_command(mService, "restore", {remote_backup_file_path, remote_temp_folder.path()}, silent); + mServerEnv.run_remote_template_command(mService, "restore", {}, silent, {{"BACKUP_FILE", remote_backup_file_path}, {"TEMP_DIR", remote_temp_folder.path()}}); } // dtor of remote_temp_folder will clean up the temp folder on the server @@ -593,7 +589,7 @@ bool service_runner::restore(std::string backup_file, bool silent) maketitle("6) Healthchecking service..."); std::string green_tick = "\033[32m✓\033[0m"; std::string red_cross = "\033[31m✗\033[0m"; - healthy= (mServerEnv.run_remote_template_command(mService, "status", {}, silent)); + healthy= (mServerEnv.run_remote_template_command(mService, "status", {}, silent, {})); if (!silent) std::cout << (healthy ? green_tick : red_cross) << " Service is " << (healthy ? "healthy" : "NOT healthy") << std::endl; } @@ -685,7 +681,7 @@ bool service_runner::backup(bool silent) { { // Run backup script cRemoteTempFolder remote_temp_folder(mServerEnv); - if (!mServerEnv.run_remote_template_command(mService, command, {remote_backup_file_path, remote_temp_folder.path()}, silent)) { + if (!mServerEnv.run_remote_template_command(mService, command, {}, silent, {{"BACKUP_FILE", remote_backup_file_path}, {"TEMP_DIR", remote_temp_folder.path()}})) { std::cerr << "Backup script failed on remote server: " << remote_backup_file_path << std::endl; return false; } diff --git a/src/service_runner.hpp b/src/service_runner.hpp index d21ddb9..53eeaf9 100644 --- a/src/service_runner.hpp +++ b/src/service_runner.hpp @@ -44,7 +44,7 @@ class service_runner { // checking that the command exists in the service directory. // checking that the command is a valid .sh file. // checking that the {service_name}.env file exists in the service directory. - bool run_command(const std::string& command, std::vector additional_args={}); + bool run_command(const std::string& command, std::vector additional_args={}, std::map env_vars={}); // check health of service. Silent. // 1. run status.sh on the server diff --git a/templates/dropshell-agent/nuke.sh b/templates/dropshell-agent/nuke.sh deleted file mode 100644 index a9bf588..0000000 --- a/templates/dropshell-agent/nuke.sh +++ /dev/null @@ -1 +0,0 @@ -#!/bin/bash diff --git a/templates/dropshell-agent/shared/_autocommands.sh b/templates/dropshell-agent/shared/_autocommands.sh index c338757..226ec97 100644 --- a/templates/dropshell-agent/shared/_autocommands.sh +++ b/templates/dropshell-agent/shared/_autocommands.sh @@ -1,11 +1,17 @@ #!/bin/bash +# This script contains the common code for the autocommands. +_check_required_env_vars "BACKUP_FILE" "TEMP_DIR" + MYID=$(id -u) MYGRP=$(id -g) +BACKUP_TEMP_PATH="$TEMP_DIR/backup" + _autocommandrun_volume() { - command="$1" - volume_name="$2" + local command="$1" + local volume_name="$2" + local backup_folder="$3" case "$command" in create) @@ -17,12 +23,10 @@ _autocommandrun_volume() { docker volume rm ${volume_name} ;; backup) - local backup_folder="$3" echo "Backing up volume ${volume_name}" docker run --rm -v ${volume_name}:/volume -v ${backup_folder}:/backup debian bash -c "tar -czvf /backup/backup.tgz -C /volume . && chown -R $MYID:$MYGRP /backup" ;; restore) - local backup_folder="$3" echo "Restoring volume ${volume_name}" docker volume rm ${volume_name} docker volume create ${volume_name} @@ -32,8 +36,9 @@ _autocommandrun_volume() { } _autocommandrun_path() { - command="$1" - path="$2" + local command="$1" + local path="$2" + local backup_folder="$3" case "$command" in create) @@ -51,7 +56,6 @@ _autocommandrun_path() { fi ;; backup) - local backup_folder="$3" echo "Backing up path ${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" @@ -60,7 +64,6 @@ _autocommandrun_path() { fi ;; restore) - local backup_folder="$3" echo "Restoring path ${path}" tar -xzvf ${backup_folder}/backup.tgz -C ${path} --strip-components=1 ;; @@ -68,32 +71,30 @@ _autocommandrun_path() { } _autocommandrun_file() { - command="$1" - value="$2" + local command="$1" + local filepath="$2" + local backup_folder="$3" case "$command" in create) ;; nuke) - rm -f ${value} + rm -f ${filepath} ;; backup) - local backup_folder="$3" - echo "Backing up file ${value}" - - FILEPARENT=$(dirname ${value}) - FILENAME=$(basename ${value}) + echo "Backing up file ${filepath}" + FILEPARENT=$(dirname ${filepath}) + FILENAME=$(basename ${filepath}) 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" + echo "File ${filepath} does not exist - nothing to backup" fi ;; restore) - local backup_folder="$3" - echo "Restoring file ${value}" - local filename=$(basename ${value}) - cp ${backup_folder}/${filename} ${value} + echo "Restoring file ${filepath}" + local FILENAME=$(basename ${filepath}) + cp ${backup_folder}/${FILENAME} ${filepath} ;; esac } @@ -111,11 +112,7 @@ _autocommandparse() { local command="$1" shift - - local temp_path="$1" - shift - - echo "autocommandparse: command=$command temp_path=$temp_path" + echo "autocommandparse: command=$command" # Extract the backup file and temp path (last two arguments) local args=("$@") @@ -134,15 +131,9 @@ _autocommandparse() { local value="${pair#*=}" # create backup folder unique to key/value. - local bfolder="${key}_${value}" - - # remove any non-alphanumeric characters, that aren't dash or underscore from the bfile - targetpath="" - if [ ! "$temp_path" == "-" ]; then - bfolder=$(echo "$bfolder" | tr -cd '[:alnum:]_-') - mkdir -p ${temp_path}/${bfolder} - targetpath="${temp_path}/${bfolder}" - fi + local bfolder=$(echo "${key}_${value}" | tr -cd '[:alnum:]_-') + local targetpath="${BACKUP_TEMP_PATH}/${bfolder}" + mkdir -p ${targetpath} # Key must be one of volume, path or file case "$key" in @@ -164,49 +155,31 @@ _autocommandparse() { autocreate() { - _autocommandparse create "-" "$@" + _autocommandparse create "$@" } autonuke() { - _autocommandparse nuke "-" "$@" + _autocommandparse nuke "$@" } autobackup() { - local backup_file="$1" - shift - local temp_path="$1" - shift + mkdir -p "$BACKUP_TEMP_PATH" + echo "_autocommandparse [backup] [$@]" + _autocommandparse backup "$@" - [ -f "$backup_file" ] && _die "Backup file $backup_file already exists" - [ -d "$temp_path" ] || _die "Temp path $temp_path does not exist" - - local backup_temp_path="$temp_path/backup" - - mkdir -p "$backup_temp_path" - echo "_autocommandparse [backup] [$backup_temp_path] [$@]" - _autocommandparse backup "$backup_temp_path" "$@" - - tar zcvf "$backup_file" -C "$backup_temp_path" . + tar zcvf "$BACKUP_FILE" -C "$BACKUP_TEMP_PATH" . } autorestore() { - local backup_file="$1" - shift - local temp_path="$1" - shift + echo "_autocommandparse [restore] [$@]" - [ -f "$backup_file" ] || _die "Backup file $backup_file does not exist" - [ -d "$temp_path" ] || _die "Temp path $temp_path does not exist" + mkdir -p "$BACKUP_TEMP_PATH" + tar zxvf "$BACKUP_FILE" -C "$BACKUP_TEMP_PATH" --strip-components=1 - local restore_temp_path="$temp_path/restore" - - mkdir -p "$restore_temp_path" - tar zxvf "$backup_file" -C "$restore_temp_path" --strip-components=1 - - _autocommandparse restore "$restore_temp_path" "$@" + _autocommandparse restore "$@" } diff --git a/templates/example-nginx/backup.sh b/templates/example-nginx/backup.sh index 46e9593..5a97acd 100644 --- a/templates/example-nginx/backup.sh +++ b/templates/example-nginx/backup.sh @@ -1,10 +1,10 @@ #!/bin/bash source "${AGENT_PATH}/_common.sh" -_check_required_env_vars "LOCAL_DATA_FOLDER" +_check_required_env_vars "LOCAL_DATA_FOLDER" "BACKUP_FILE" "TEMP_DIR" "CONTAINER_NAME" # Nginx Example Backup Script # hot backup is fine for nginx website content. -autobackup "$1" "$2" "path=${LOCAL_DATA_FOLDER}" || _die "Failed to create backup" +autobackup "path=${LOCAL_DATA_FOLDER}" || _die "Failed to create backup" -echo "Backup complete" +echo "Backup complete for ${CONTAINER_NAME}" diff --git a/templates/example-nginx/restore.sh b/templates/example-nginx/restore.sh index fca14ee..1f5a0c3 100644 --- a/templates/example-nginx/restore.sh +++ b/templates/example-nginx/restore.sh @@ -1,15 +1,13 @@ #!/bin/bash source "${AGENT_PATH}/_common.sh" -_check_required_env_vars "LOCAL_DATA_FOLDER" +_check_required_env_vars "LOCAL_DATA_FOLDER" "BACKUP_FILE" "TEMP_DIR" "CONTAINER_NAME" # Nginx Example Restore Script -BACKUP_FILE="$1" - echo "Uninstalling service before restore..." bash ./uninstall.sh || _die "Failed to uninstall service before restore" -autorestore "$1" "$2" "path=${LOCAL_DATA_FOLDER}" || _die "Failed to restore data folder from backup" +autorestore "path=${LOCAL_DATA_FOLDER}" || _die "Failed to restore data folder from backup" echo "Restore complete. Reinstalling service..." bash ./install.sh || _die "Failed to reinstall service after restore" diff --git a/templates/simple-object-storage/backup.sh b/templates/simple-object-storage/backup.sh index 56dad4c..330afce 100644 --- a/templates/simple-object-storage/backup.sh +++ b/templates/simple-object-storage/backup.sh @@ -1,6 +1,6 @@ #!/bin/bash source "${AGENT_PATH}/_common.sh" -_check_required_env_vars "VOLUME_NAME" +_check_required_env_vars "VOLUME_NAME" "BACKUP_FILE" "TEMP_DIR" # Simple Object Storage Backup Script # Creates a backup tarball of the volume contents. @@ -8,6 +8,6 @@ _check_required_env_vars "VOLUME_NAME" # HOT backup is fine for simple-object-storage -autobackup "$1" "$2" "volume=${VOLUME_NAME}" || _die "Failed to create backup" +autobackup "volume=${VOLUME_NAME}" || _die "Failed to create backup" echo "Backup complete: ${BACKUP_FILE}" diff --git a/templates/simple-object-storage/restore.sh b/templates/simple-object-storage/restore.sh index 20c47ec..4cf61e4 100644 --- a/templates/simple-object-storage/restore.sh +++ b/templates/simple-object-storage/restore.sh @@ -1,6 +1,6 @@ #!/bin/bash source "${AGENT_PATH}/_common.sh" || _die "Failed to source _common.sh" -_check_required_env_vars +_check_required_env_vars "BACKUP_FILE" "TEMP_DIR" "VOLUME_NAME" "CONTAINER_NAME" # Simple Object Storage Restore Script # Restores data from a backup file. @@ -12,7 +12,7 @@ bash ./uninstall.sh || _die "Failed to uninstall service before restore" echo "Restoring data for ${CONTAINER_NAME} from ${BACKUP_FILE}..." -autorestore "$1" "$2" "volume=${VOLUME_NAME}" || _die "Failed to restore data from backup file" +autorestore "volume=${VOLUME_NAME}" || _die "Failed to restore data from backup file" echo "Restore complete. Reinstalling service..." diff --git a/templates/squashkiwi/backup.sh b/templates/squashkiwi/backup.sh index 028fdad..cede869 100644 --- a/templates/squashkiwi/backup.sh +++ b/templates/squashkiwi/backup.sh @@ -1,11 +1,11 @@ #!/bin/bash source "${AGENT_PATH}/_common.sh" -_check_required_env_vars "CONTAINER_NAME" "LOCAL_DATA_FOLDER" +_check_required_env_vars "CONTAINER_NAME" "LOCAL_DATA_FOLDER" "BACKUP_FILE" "TEMP_DIR" # Stop container before backup _stop_container "$CONTAINER_NAME" -autobackup "$1" "$2" "path=${LOCAL_DATA_FOLDER}" || _die "Failed to create backup" +autobackup "path=${LOCAL_DATA_FOLDER}" || _die "Failed to create backup" # Start container after backup _start_container "$CONTAINER_NAME" diff --git a/templates/squashkiwi/restore.sh b/templates/squashkiwi/restore.sh index 2623a49..5d59bf9 100644 --- a/templates/squashkiwi/restore.sh +++ b/templates/squashkiwi/restore.sh @@ -1,6 +1,6 @@ #!/bin/bash source "${AGENT_PATH}/_common.sh" -_check_required_env_vars "CONTAINER_NAME" "LOCAL_DATA_FOLDER" +_check_required_env_vars "CONTAINER_NAME" "LOCAL_DATA_FOLDER" "BACKUP_FILE" "TEMP_DIR" # RESTORE SCRIPT # The restore script is OPTIONAL. @@ -10,7 +10,7 @@ _check_required_env_vars "CONTAINER_NAME" "LOCAL_DATA_FOLDER" # # Stop container before backup bash ./uninstall.sh || _die "Failed to uninstall service before restore" -autorestore "$1" "$2" "path=${LOCAL_DATA_FOLDER}" || _die "Failed to restore data folder from backup" +autorestore "path=${LOCAL_DATA_FOLDER}" || _die "Failed to restore data folder from backup" # reinstall service bash ./install.sh || _die "Failed to reinstall service after restore"