Compiles but no good
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 25s

This commit is contained in:
Your Name 2025-05-09 18:44:43 +12:00
parent ed93fa1aaa
commit 2bcf6c530d
12 changed files with 76 additions and 99 deletions

View File

@ -161,21 +161,30 @@ bool server_env_manager::check_remote_items_exist(const std::vector<std::string>
return true; return true;
} }
bool server_env_manager::run_remote_template_command(const std::string &service_name, const std::string &command, std::vector<std::string> args, bool silent) const bool server_env_manager::run_remote_template_command(const std::string &service_name, const std::string &command, std::vector<std::string> args, bool silent, std::map<std::string, std::string> extra_env_vars) const
{ {
sCommand scommand = construct_standard_template_run_cmd(service_name, command, args, silent); 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()) if (scommand.get_command_to_run().empty())
return false; return false;
cMode mode = (command=="ssh") ? (cMode::Interactive | cMode::RawCommand) : cMode::Silent; cMode mode = (command=="ssh") ? (cMode::Interactive | cMode::RawCommand) : cMode::Silent;
return execute_ssh_command(get_SSH_INFO(), scommand, mode); 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<std::string> 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<std::string> args, std::string &output, bool silent, std::map<std::string, std::string> extra_env_vars) const
{ {
sCommand scommand = construct_standard_template_run_cmd(service_name, command, args, false); sCommand scommand = construct_standard_template_run_cmd(service_name, command, args, false);
if (scommand.get_command_to_run().empty()) if (scommand.get_command_to_run().empty())
return false; 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; cMode mode = cMode::CaptureOutput | cMode::RawCommand;
return execute_ssh_command(get_SSH_INFO(), scommand, mode, &output); return execute_ssh_command(get_SSH_INFO(), scommand, mode, &output);
} }

View File

@ -53,8 +53,10 @@ class server_env_manager {
bool check_remote_file_exists(const std::string& file_path) const; bool check_remote_file_exists(const std::string& file_path) const;
bool check_remote_items_exist(const std::vector<std::string>& file_paths) const; bool check_remote_items_exist(const std::vector<std::string>& file_paths) const;
bool run_remote_template_command(const std::string& service_name, const std::string& command, std::vector<std::string> args, bool silent=false) const; bool run_remote_template_command(const std::string& service_name, const std::string& command,
bool run_remote_template_command_and_capture_output(const std::string& service_name, const std::string& command, std::vector<std::string> args, std::string & output, bool silent=false) const; std::vector<std::string> args, bool silent, std::map<std::string, std::string> extra_env_vars) const;
bool run_remote_template_command_and_capture_output(const std::string& service_name, const std::string& command,
std::vector<std::string> args, std::string & output, bool silent, std::map<std::string, std::string> extra_env_vars) const;
private: private:
sCommand construct_standard_template_run_cmd(const std::string& service_name, const std::string& command, std::vector<std::string> args, bool silent) const; sCommand construct_standard_template_run_cmd(const std::string& service_name, const std::string& command, std::vector<std::string> args, bool silent) const;

View File

@ -107,7 +107,7 @@ bool service_runner::install(bool silent) {
// Run install script // Run install script
{ {
mServerEnv.run_remote_template_command(mService, "install", {}); mServerEnv.run_remote_template_command(mService, "install", {}, silent, {});
} }
// print health tick // print health tick
@ -131,7 +131,7 @@ bool service_runner::uninstall(bool silent) {
bool script_exists = mServerEnv.check_remote_file_exists(uninstall_script); bool script_exists = mServerEnv.check_remote_file_exists(uninstall_script);
if (script_exists) { 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; std::cerr << "Warning: Uninstall script failed, but continuing with directory removal" << std::endl;
} }
@ -157,12 +157,8 @@ bool service_runner::nuke(bool silent)
if (!mServerEnv.is_valid()) return false; // should never hit this. if (!mServerEnv.is_valid()) return false; // should never hit this.
std::map<std::string, std::string> 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); 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) if (!okay)
{ {
std::cerr << "Warning: Nuke script failed" << std::endl; std::cerr << "Warning: Nuke script failed" << std::endl;
@ -206,7 +202,7 @@ bool service_runner::fullnuke()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Run a command on the service. // Run a command on the service.
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool service_runner::run_command(const std::string& command, std::vector<std::string> additional_args) { bool service_runner::run_command(const std::string& command, std::vector<std::string> additional_args, std::map<std::string, std::string> env_vars) {
if (!mServerEnv.is_valid()) { if (!mServerEnv.is_valid()) {
std::cerr << "Error: Server service not initialized" << std::endl; std::cerr << "Error: Server service not initialized" << std::endl;
return false; return false;
@ -282,7 +278,7 @@ bool service_runner::run_command(const std::string& command, std::vector<std::st
// Run the generic command // Run the generic command
std::vector<std::string> args; // not passed through yet. std::vector<std::string> 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<std::string, ServiceStatus> service_runner::get_all_services_status(std
} }
std::string output; 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; return status;
std::stringstream ss(output); std::stringstream ss(output);
@ -360,7 +356,7 @@ HealthStatus service_runner::is_healthy()
} }
// Run status script, does not display output. // 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::UNHEALTHY;
return HealthStatus::HEALTHY; return HealthStatus::HEALTHY;
} }
@ -477,7 +473,7 @@ bool service_runner::interactive_ssh_service()
} }
std::vector<std::string> args; // not passed through yet. std::vector<std::string> 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() 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); 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 } // 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..."); maketitle("6) Healthchecking service...");
std::string green_tick = "\033[32m✓\033[0m"; std::string green_tick = "\033[32m✓\033[0m";
std::string red_cross = "\033[31m✗\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) if (!silent)
std::cout << (healthy ? green_tick : red_cross) << " Service is " << (healthy ? "healthy" : "NOT healthy") << std::endl; 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 { // Run backup script
cRemoteTempFolder remote_temp_folder(mServerEnv); 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; std::cerr << "Backup script failed on remote server: " << remote_backup_file_path << std::endl;
return false; return false;
} }

View File

@ -44,7 +44,7 @@ class service_runner {
// checking that the command exists in the service directory. // checking that the command exists in the service directory.
// checking that the command is a valid .sh file. // checking that the command is a valid .sh file.
// checking that the {service_name}.env file exists in the service directory. // checking that the {service_name}.env file exists in the service directory.
bool run_command(const std::string& command, std::vector<std::string> additional_args={}); bool run_command(const std::string& command, std::vector<std::string> additional_args={}, std::map<std::string, std::string> env_vars={});
// check health of service. Silent. // check health of service. Silent.
// 1. run status.sh on the server // 1. run status.sh on the server

View File

@ -1 +0,0 @@
#!/bin/bash

View File

@ -1,11 +1,17 @@
#!/bin/bash #!/bin/bash
# This script contains the common code for the autocommands.
_check_required_env_vars "BACKUP_FILE" "TEMP_DIR"
MYID=$(id -u) MYID=$(id -u)
MYGRP=$(id -g) MYGRP=$(id -g)
BACKUP_TEMP_PATH="$TEMP_DIR/backup"
_autocommandrun_volume() { _autocommandrun_volume() {
command="$1" local command="$1"
volume_name="$2" local volume_name="$2"
local backup_folder="$3"
case "$command" in case "$command" in
create) create)
@ -17,12 +23,10 @@ _autocommandrun_volume() {
docker volume rm ${volume_name} docker volume rm ${volume_name}
;; ;;
backup) backup)
local backup_folder="$3"
echo "Backing up volume ${volume_name}" 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" 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) restore)
local backup_folder="$3"
echo "Restoring volume ${volume_name}" echo "Restoring volume ${volume_name}"
docker volume rm ${volume_name} docker volume rm ${volume_name}
docker volume create ${volume_name} docker volume create ${volume_name}
@ -32,8 +36,9 @@ _autocommandrun_volume() {
} }
_autocommandrun_path() { _autocommandrun_path() {
command="$1" local command="$1"
path="$2" local path="$2"
local backup_folder="$3"
case "$command" in case "$command" in
create) create)
@ -51,7 +56,6 @@ _autocommandrun_path() {
fi fi
;; ;;
backup) backup)
local backup_folder="$3"
echo "Backing up path ${path}" echo "Backing up path ${path}"
if [ -d "${path}" ]; then 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" 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 fi
;; ;;
restore) restore)
local backup_folder="$3"
echo "Restoring path ${path}" echo "Restoring path ${path}"
tar -xzvf ${backup_folder}/backup.tgz -C ${path} --strip-components=1 tar -xzvf ${backup_folder}/backup.tgz -C ${path} --strip-components=1
;; ;;
@ -68,32 +71,30 @@ _autocommandrun_path() {
} }
_autocommandrun_file() { _autocommandrun_file() {
command="$1" local command="$1"
value="$2" local filepath="$2"
local backup_folder="$3"
case "$command" in case "$command" in
create) create)
;; ;;
nuke) nuke)
rm -f ${value} rm -f ${filepath}
;; ;;
backup) backup)
local backup_folder="$3" echo "Backing up file ${filepath}"
echo "Backing up file ${value}" FILEPARENT=$(dirname ${filepath})
FILENAME=$(basename ${filepath})
FILEPARENT=$(dirname ${value})
FILENAME=$(basename ${value})
if [ -f "${FILEPARENT}/${FILENAME}" ]; then 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" docker run --rm-v ${FILEPARENT}:/volume -v ${backup_folder}:/backup debian bash -c "cp /volume/${FILENAME} /backup/${FILENAME} && chown -R $MYID:$MYGRP /backup"
else else
echo "File ${value} does not exist - nothing to backup" echo "File ${filepath} does not exist - nothing to backup"
fi fi
;; ;;
restore) restore)
local backup_folder="$3" echo "Restoring file ${filepath}"
echo "Restoring file ${value}" local FILENAME=$(basename ${filepath})
local filename=$(basename ${value}) cp ${backup_folder}/${FILENAME} ${filepath}
cp ${backup_folder}/${filename} ${value}
;; ;;
esac esac
} }
@ -111,11 +112,7 @@ _autocommandparse() {
local command="$1" local command="$1"
shift shift
echo "autocommandparse: command=$command"
local temp_path="$1"
shift
echo "autocommandparse: command=$command temp_path=$temp_path"
# Extract the backup file and temp path (last two arguments) # Extract the backup file and temp path (last two arguments)
local args=("$@") local args=("$@")
@ -134,15 +131,9 @@ _autocommandparse() {
local value="${pair#*=}" local value="${pair#*=}"
# create backup folder unique to key/value. # create backup folder unique to key/value.
local bfolder="${key}_${value}" local bfolder=$(echo "${key}_${value}" | tr -cd '[:alnum:]_-')
local targetpath="${BACKUP_TEMP_PATH}/${bfolder}"
# remove any non-alphanumeric characters, that aren't dash or underscore from the bfile mkdir -p ${targetpath}
targetpath=""
if [ ! "$temp_path" == "-" ]; then
bfolder=$(echo "$bfolder" | tr -cd '[:alnum:]_-')
mkdir -p ${temp_path}/${bfolder}
targetpath="${temp_path}/${bfolder}"
fi
# Key must be one of volume, path or file # Key must be one of volume, path or file
case "$key" in case "$key" in
@ -164,49 +155,31 @@ _autocommandparse() {
autocreate() { autocreate() {
_autocommandparse create "-" "$@" _autocommandparse create "$@"
} }
autonuke() { autonuke() {
_autocommandparse nuke "-" "$@" _autocommandparse nuke "$@"
} }
autobackup() { autobackup() {
local backup_file="$1" mkdir -p "$BACKUP_TEMP_PATH"
shift echo "_autocommandparse [backup] [$@]"
local temp_path="$1" _autocommandparse backup "$@"
shift
[ -f "$backup_file" ] && _die "Backup file $backup_file already exists" tar zcvf "$BACKUP_FILE" -C "$BACKUP_TEMP_PATH" .
[ -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" .
} }
autorestore() { autorestore() {
local backup_file="$1" echo "_autocommandparse [restore] [$@]"
shift
local temp_path="$1"
shift
[ -f "$backup_file" ] || _die "Backup file $backup_file does not exist" mkdir -p "$BACKUP_TEMP_PATH"
[ -d "$temp_path" ] || _die "Temp path $temp_path does not exist" tar zxvf "$BACKUP_FILE" -C "$BACKUP_TEMP_PATH" --strip-components=1
local restore_temp_path="$temp_path/restore" _autocommandparse restore "$@"
mkdir -p "$restore_temp_path"
tar zxvf "$backup_file" -C "$restore_temp_path" --strip-components=1
_autocommandparse restore "$restore_temp_path" "$@"
} }

View File

@ -1,10 +1,10 @@
#!/bin/bash #!/bin/bash
source "${AGENT_PATH}/_common.sh" 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 # Nginx Example Backup Script
# hot backup is fine for nginx website content. # 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}"

View File

@ -1,15 +1,13 @@
#!/bin/bash #!/bin/bash
source "${AGENT_PATH}/_common.sh" 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 # Nginx Example Restore Script
BACKUP_FILE="$1"
echo "Uninstalling service before restore..." echo "Uninstalling service before restore..."
bash ./uninstall.sh || _die "Failed to uninstall 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..." echo "Restore complete. Reinstalling service..."
bash ./install.sh || _die "Failed to reinstall service after restore" bash ./install.sh || _die "Failed to reinstall service after restore"

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
source "${AGENT_PATH}/_common.sh" 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 # Simple Object Storage Backup Script
# Creates a backup tarball of the volume contents. # 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 # 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}" echo "Backup complete: ${BACKUP_FILE}"

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
source "${AGENT_PATH}/_common.sh" || _die "Failed to source _common.sh" 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 # Simple Object Storage Restore Script
# Restores data from a backup file. # 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}..." 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..." echo "Restore complete. Reinstalling service..."

View File

@ -1,11 +1,11 @@
#!/bin/bash #!/bin/bash
source "${AGENT_PATH}/_common.sh" 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 before backup
_stop_container "$CONTAINER_NAME" _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 after backup
_start_container "$CONTAINER_NAME" _start_container "$CONTAINER_NAME"

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
source "${AGENT_PATH}/_common.sh" 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 # RESTORE SCRIPT
# The restore script is OPTIONAL. # The restore script is OPTIONAL.
@ -10,7 +10,7 @@ _check_required_env_vars "CONTAINER_NAME" "LOCAL_DATA_FOLDER"
# # Stop container before backup # # Stop container before backup
bash ./uninstall.sh || _die "Failed to uninstall 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"
# reinstall service # reinstall service
bash ./install.sh || _die "Failed to reinstall service after restore" bash ./install.sh || _die "Failed to reinstall service after restore"