From 4bcbf120883ae793a5af28c8c67a591dbf2f37a2 Mon Sep 17 00:00:00 2001 From: j Date: Tue, 30 Dec 2025 09:31:21 +1300 Subject: [PATCH] Tidying --- source/agent-remote/agent-install.sh | 1 + source/agent-remote/ds_run.sh | 42 +++++++++------- source/src/commands/install.cpp | 12 ++++- source/src/utils/directories.cpp | 5 ++ source/src/utils/directories.hpp | 3 ++ source/src/utils/execute.cpp | 75 +++++++++++++--------------- 6 files changed, 79 insertions(+), 59 deletions(-) diff --git a/source/agent-remote/agent-install.sh b/source/agent-remote/agent-install.sh index 6782e6b..a5d5676 100755 --- a/source/agent-remote/agent-install.sh +++ b/source/agent-remote/agent-install.sh @@ -75,6 +75,7 @@ required_files=( "$AGENT_PATH/bb64" "$AGENT_PATH/common.sh" "$AGENT_PATH/datacommands.sh" + "$AGENT_PATH/ds_run.sh" ) # check if all files exist diff --git a/source/agent-remote/ds_run.sh b/source/agent-remote/ds_run.sh index a653e40..e4ac575 100644 --- a/source/agent-remote/ds_run.sh +++ b/source/agent-remote/ds_run.sh @@ -3,21 +3,28 @@ set -euo pipefail # Dropshell Run - Execute a service command on the remote server # -# Usage: ds_run.sh SERVER SERVICE COMMAND [args...] +# Usage: ds_run.sh SERVICE COMMAND [args...] # # Remote directory structure: -# DROPSHELL_DIR/ -# ├── agent/ -# │ ├── ds_run.sh (this script) -# │ └── common.sh -# └── services// -# ├── config/ -# │ └── service.env -# └── template/ -# ├── template_info.env -# ├── install.sh, uninstall.sh, etc. -# └── config/ -# └── service.env (template defaults) + # // |-- server_info.env + # // |-- server.json + # // |-- backups + # // |-- temp_files + # // |-- agent + # // | |-- bb64 + # // | |-- ds_run.sh (this script) + # // | |-- common.sh + # // | |-- (other agent files) + # // |-- services + # // |-- service name + # // |-- config + # // |-- service.env (actual service config) + # // |-- template + # // |-- (script files) + # // |-- template_info.env + # // |-- config + # // |-- service.env (default service config) + # // |-- (other template/example config files) # -- Determine paths -- SCRIPT_PATH="$(readlink -f "${BASH_SOURCE[0]}")" @@ -37,10 +44,9 @@ if [[ $# -lt 3 ]]; then exit 1 fi -export SERVER="$1" -export SERVICE="$2" -export DSCOMMAND="$3" -shift 3 +export SERVICE="$1" +export DSCOMMAND="$2" +shift 2 # Suppress Docker CLI hints export DOCKER_CLI_HINTS=false @@ -50,6 +56,7 @@ export CONFIG_PATH="${DROPSHELL_DIR}/services/${SERVICE}/config" export TEMPLATE_PATH="${DROPSHELL_DIR}/services/${SERVICE}/template" # -- Validate service exists -- +[[ -f "${DROPSHELL_DIR}/server_info.env" ]] || _die "Missing ${DROPSHELL_DIR}/server_info.env" [[ -d "${CONFIG_PATH}" ]] || _die "Service '${SERVICE}' does not exist on server (missing ${CONFIG_PATH})" # -- Load template info (template defaults, loaded first) -- @@ -65,6 +72,7 @@ export SERVICE_ENV="${CONFIG_PATH}/service.env" # -- Source env files with auto-export (set -a exports all assigned variables) -- set -a +source "${DROPSHELL_DIR}/server_info.env" source "${TEMPLATE_INFO_ENV}" source "${SERVICE_ENV}" set +a diff --git a/source/src/commands/install.cpp b/source/src/commands/install.cpp index a1dc8e2..a5a26e5 100644 --- a/source/src/commands/install.cpp +++ b/source/src/commands/install.cpp @@ -529,6 +529,17 @@ complete -F _dropshell_completions ds server, false, user.user); info << "done." << std::endl; + // create server_info.env + info << "Creating server_info.env on remote server... " < "+rsiep,{}); + if (! execute_ssh_command(server.get_SSH_INFO(user.user),cmd,cMode::Defaults | cMode::NoBB64, nullptr)) + { + error << std::endl << "Failed to create " << rsiep << " on " << server.get_server_name() << std::endl; + return 1; + } + info << "done." << std::endl; + // run the agent installer. Can't use BB64 yet, as we're installing it on the remote server. bool okay = execute_ssh_command(server.get_SSH_INFO(user.user), sCommand(agent_path, "agent-install.sh",{}), cMode::Defaults | cMode::NoBB64, nullptr); if (!okay) @@ -537,7 +548,6 @@ complete -F _dropshell_completions ds return 1; } - info << "Installation on " << server.get_server_name() << " complete." << std::endl; } return 0; diff --git a/source/src/utils/directories.cpp b/source/src/utils/directories.cpp index d82e3be..c162048 100644 --- a/source/src/utils/directories.cpp +++ b/source/src/utils/directories.cpp @@ -170,6 +170,11 @@ namespace dropshell return remotepath(mServer_name, mUser).DROPSHELL_DIR() + "/" + filenames::server_json; } + std::string remotefile::server_info_env() + { + return remotepath(mServer_name, mUser).DROPSHELL_DIR() + "/" + filenames::server_info_env; + } + remotepath::remotepath(const std::string &server_name, const std::string &user) : mServer_name(server_name), mUser(user) {} std::string remotepath::DROPSHELL_DIR() const diff --git a/source/src/utils/directories.hpp b/source/src/utils/directories.hpp index 7ef52fd..e42fc73 100644 --- a/source/src/utils/directories.hpp +++ b/source/src/utils/directories.hpp @@ -42,6 +42,7 @@ namespace dropshell { // |-- (...other config files for specific server&service...) namespace filenames { + static const std::string server_info_env = "server_info.env"; static const std::string template_info_env = "template_info.env"; static const std::string service_env = "service.env"; static const std::string readme = "README.txt"; @@ -80,6 +81,7 @@ namespace dropshell { //------------------------------------------------------------------------------------------------ // remote paths // DROPSHELL_DIR + // |-- server_info.env // |-- server.json // |-- backups // |-- temp_files @@ -102,6 +104,7 @@ namespace dropshell { remotefile(const std::string &server_name, const std::string &user); std::string service_env(const std::string &service_name) const; std::string server_json(); + std::string server_info_env(); private: std::string mServer_name; std::string mUser; diff --git a/source/src/utils/execute.cpp b/source/src/utils/execute.cpp index 893d333..49a55a4 100644 --- a/source/src/utils/execute.cpp +++ b/source/src/utils/execute.cpp @@ -235,52 +235,45 @@ namespace dropshell return ""; // need to construct to change directory and set environment variables - std::string cmdstr; - if (!bb64path.empty()) - { - if (!mDir.empty()) - cmdstr += "cd " + quote(mDir) + " && "; - - if (!mVars.empty()) - { - // Export variables so they're available for expansion in the command - for (const auto &env_var : mVars) - { - // Basic sanity check - skip invalid variable names - if (!is_valid_env_var_name(env_var.first)) - { - error << "Skipping invalid environment variable name: " << env_var.first << std::endl; - continue; - } - - // Very basic check for completely broken values that could break the command - // We still use quote() for proper escaping, but warn about suspicious values - const std::string &value = env_var.second; - if (value.find('\0') != std::string::npos) - { - error << "Skipping environment variable with null byte: " << env_var.first << std::endl; - continue; - } - - cmdstr += "export " + env_var.first + "=" + quote(dequote(trim(value))) + " && "; - } - } - - cmdstr += mCmd; - - cmdstr = makesafecmd(bb64path, cmdstr); - } - else + if (bb64path.empty()) { // raw! bootstrapping only. ASSERT(mVars.empty(), "Bootstrapping command must not have environment variables"); - if (!mDir.empty()) - cmdstr += mDir + "/" + mCmd; - else - cmdstr += mCmd; + return (mDir.empty() ? mCmd : mDir + "/" + mCmd); } - return cmdstr; + std::string cmdstr; + if (!mDir.empty()) + cmdstr += "cd " + quote(mDir) + " && "; + + if (!mVars.empty()) + { + // Export variables so they're available for expansion in the command + for (const auto &env_var : mVars) + { + // Basic sanity check - skip invalid variable names + if (!is_valid_env_var_name(env_var.first)) + { + error << "Skipping invalid environment variable name: " << env_var.first << std::endl; + continue; + } + + // Very basic check for completely broken values that could break the command + // We still use quote() for proper escaping, but warn about suspicious values + const std::string &value = env_var.second; + if (value.find('\0') != std::string::npos) + { + error << "Skipping environment variable with null byte: " << env_var.first << std::endl; + continue; + } + + cmdstr += "export " + env_var.first + "=" + quote(dequote(trim(value))) + " && "; + } + } + + cmdstr += mCmd; + + return makesafecmd(bb64path, cmdstr); } bool sSSHInfo::valid() const