.
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled

This commit is contained in:
Your Name 2025-05-12 23:53:52 +12:00
parent d946c18d7c
commit 5201e92cb3
9 changed files with 73 additions and 48 deletions

View File

@ -50,7 +50,7 @@ struct EditCommandRegister {
// ------------------------------------------------------------------------------------------------
// utility function to edit a file
// ------------------------------------------------------------------------------------------------
bool edit_file(const std::string &file_path)
bool edit_file(const std::string &file_path, bool has_bb64)
{
// make sure parent directory exists.
std::string parent_dir = get_parent(file_path);
@ -72,7 +72,15 @@ bool edit_file(const std::string &file_path)
}
std::cout << "Editing file: " << file_path << std::endl;
return execute_local_command(editor_cmd, nullptr, cMode::Interactive);
if (has_bb64) {
return execute_local_command(editor_cmd, nullptr, cMode::Interactive);
}
else {
// might not have bb64 at this early stage. Direct edit.
int ret = system(editor_cmd.c_str());
return EXITSTATUSCHECK(ret);
}
}
// ------------------------------------------------------------------------------------------------
@ -84,7 +92,7 @@ int edit_config()
gConfig().save_config(false); // save defaults.
std::string config_file = localfile::dropshell_json();
if (!edit_file(config_file) || !std::filesystem::exists(config_file))
if (!edit_file(config_file, false) || !std::filesystem::exists(config_file))
return die("Error: Failed to edit config file.");
gConfig().load_config();
@ -92,6 +100,9 @@ int edit_config()
return die("Error: Failed to load and parse edited config file!");
gConfig().save_config(true);
// make sure we have executables.
std::cout << "Successfully edited config file at " << config_file << std::endl;
return 0;
}
@ -113,7 +124,7 @@ int edit_server(const std::string &server_name)
<< "Once moved, reinstall all services with: dropshell install " << server_name;
std::string config_file = serverpath + "/server.env";
if (!edit_file(config_file)) {
if (!edit_file(config_file, true)) {
std::cerr << "Error: Failed to edit server.env" << std::endl;
std::cerr << "You can manually edit this file at: " << config_file << std::endl;
std::cerr << "After editing, " << aftertext.str() << std::endl;
@ -135,7 +146,7 @@ int edit_service_config(const std::string &server, const std::string &service)
return 1;
}
if (edit_file(config_file) && std::filesystem::exists(config_file))
if (edit_file(config_file, true) && std::filesystem::exists(config_file))
std::cout << "To apply your changes, run:\n dropshell install " + server + " " + service << std::endl;
return 0;
}

View File

@ -88,7 +88,7 @@ bool install_service(const std::string& server, const std::string& service, bool
// Create service directory
std::string remote_service_path = remotepath::service(server, service);
std::string mkdir_cmd = "mkdir -p " + quote(remote_service_path);
if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand("",remotepath::executables(server), mkdir_cmd, {}), cMode::Silent))
if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand("", mkdir_cmd, {}), cMode::Silent))
{
std::cerr << "Failed to create service directory " << remote_service_path << std::endl;
return false;
@ -96,7 +96,7 @@ bool install_service(const std::string& server, const std::string& service, bool
// Check if rsync is installed on remote host
std::string check_rsync_cmd = "which rsync";
if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand("",remotepath::executables(server), check_rsync_cmd, {}), cMode::Silent))
if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand("", check_rsync_cmd, {}), cMode::Silent))
{
std::cerr << "rsync is not installed on the remote host" << std::endl;
return false;

View File

@ -5,7 +5,7 @@
#include "utils/utils.hpp"
#include "utils/json.hpp"
#include <filesystem>
#include "utils/execute.hpp"
namespace dropshell {
@ -85,7 +85,8 @@ bool config::save_config(bool create_aux_directories)
std::vector<std::filesystem::path> paths = {
get_local_template_cache_path(),
get_local_backup_path(),
get_local_tempfiles_path()
get_local_tempfiles_path(),
get_local_executables_path()
};
for (auto & p : get_local_server_definition_paths())
paths.push_back(p);
@ -98,6 +99,17 @@ bool config::save_config(bool create_aux_directories)
}
}
// also make sure the executables are in the path.
std::string executables_path = get_local_executables_path();
// download bb64.
std::string cmd = "cd " + executables_path + " && curl -fsSL -o bb64 https://gitea.jde.nz/public/bb64/releases/download/latest/bb64.amd64 && chmod a+x bb64";
int ret = system(cmd.c_str());
if (EXITSTATUSCHECK(ret))
std::cout << "Downloaded bb64 to " << executables_path << std::endl;
else
std::cerr << "Failed to download bb64 to " << executables_path << std::endl;
return true;
}

View File

@ -141,8 +141,6 @@ auto command_match = [](const std::string& cmd_list, int argc, char* argv[]) ->
}
int old_main(int argc, char* argv[]) {
HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2)))
HAPPYEXIT("version", printversion())

View File

@ -122,7 +122,6 @@ std::optional<sCommand> server_env_manager::construct_standard_template_run_cmd(
sCommand sc(
remote_service_template_path,
remotepath::executables(mServerName),
quote(script_path) + argstr + (silent ? " > /dev/null 2>&1" : ""),
env_vars
);
@ -137,12 +136,12 @@ std::optional<sCommand> server_env_manager::construct_standard_template_run_cmd(
bool server_env_manager::check_remote_dir_exists(const std::string &dir_path) const
{
sCommand scommand("",remotepath::executables(mServerName),"test -d " + quote(dir_path),{});
sCommand scommand("", "test -d " + quote(dir_path),{});
return execute_ssh_command(get_SSH_INFO(), scommand, cMode::Silent);
}
bool server_env_manager::check_remote_file_exists(const std::string& file_path) const {
sCommand scommand("",remotepath::executables(mServerName),"test -f " + quote(file_path),{});
sCommand scommand("", "test -f " + quote(file_path),{});
return execute_ssh_command(get_SSH_INFO(), scommand, cMode::Silent);
}
@ -156,7 +155,7 @@ bool server_env_manager::check_remote_items_exist(const std::vector<std::string>
file_names_str += std::filesystem::path(file_path).filename().string() + " ";
}
// check if all items in the vector exist on the remote server, in a single command.
sCommand scommand("",remotepath::executables(mServerName),"for item in " + file_paths_str + "; do test -f $item; done",{});
sCommand scommand("", "for item in " + file_paths_str + "; do test -f $item; done",{});
bool okay = execute_ssh_command(get_SSH_INFO(), scommand, cMode::Silent);
if (!okay) {
@ -187,7 +186,7 @@ bool server_env_manager::remove_remote_dir(const std::string &dir_path, bool sil
if (!silent)
std::cout << "Running command: " << remote_cmd << std::endl;
sCommand scommand("",remotepath::executables(mServerName),remote_cmd,{});
sCommand scommand("", remote_cmd,{});
cMode mode = (silent ? cMode::Silent : cMode::None);
return execute_ssh_command(get_SSH_INFO(), scommand, mode);

View File

@ -43,7 +43,7 @@ class server_env_manager {
std::string get_SSH_USER() const { return get_variable("SSH_USER"); }
std::string get_SSH_PORT() const { return get_variable("SSH_PORT"); }
std::string get_DROPSHELL_DIR() const { return get_variable("DROPSHELL_DIR"); }
sSSHInfo get_SSH_INFO() const { return sSSHInfo{get_SSH_HOST(), get_SSH_USER(), get_SSH_PORT()}; }
sSSHInfo get_SSH_INFO() const { return sSSHInfo{get_SSH_HOST(), get_SSH_USER(), get_SSH_PORT(), get_server_name()}; }
bool is_valid() const { return mValid; }
std::string get_server_name() const { return mServerName; }

View File

@ -241,7 +241,7 @@ bool service_runner::interactive_ssh(const std::string & server_name, const std:
std::cerr << "Error: Invalid server environment file: " << server_name << std::endl;
return false;
}
sCommand scommand("",remotepath::executables(server_name), "bash",{});
sCommand scommand("", "bash",{});
return execute_ssh_command(env.get_SSH_INFO(), scommand, cMode::Interactive);
}
@ -426,7 +426,7 @@ bool service_runner::backup(bool silent) {
std::string remote_backups_dir = remotepath::backups(mServer);
if (!silent) std::cout << "Remote backups directory on "<< mServer <<": " << remote_backups_dir << std::endl;
std::string mkdir_cmd = "mkdir -p " + quote(remote_backups_dir);
if (!execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand("",remotepath::executables(mServer), mkdir_cmd, {}), cMode::Silent)) {
if (!execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand("",mkdir_cmd, {}), cMode::Silent)) {
std::cerr << "Failed to create backups directory on server" << std::endl;
return false;
}
@ -484,7 +484,7 @@ cRemoteTempFolder::cRemoteTempFolder(const server_env_manager &server_env) : mSe
{
std::string p = remotepath::temp_files(server_env.get_server_name()) + "/" + random_alphanumeric_string(10);
std::string mkdir_cmd = "mkdir -p " + quote(p);
if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand("",remotepath::executables(server_env.get_server_name()), mkdir_cmd, {}), cMode::Silent))
if (!execute_ssh_command(server_env.get_SSH_INFO(), sCommand("", mkdir_cmd, {}), cMode::Silent))
std::cerr << "Failed to create temp directory on server" << std::endl;
else
mPath = p;
@ -493,7 +493,7 @@ cRemoteTempFolder::cRemoteTempFolder(const server_env_manager &server_env) : mSe
cRemoteTempFolder::~cRemoteTempFolder()
{
std::string rm_cmd = "rm -rf " + quote(mPath);
execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand("",remotepath::executables(mServerEnv.get_server_name()), rm_cmd, {}), cMode::Silent);
execute_ssh_command(mServerEnv.get_SSH_INFO(), sCommand("", rm_cmd, {}), cMode::Silent);
}
std::string cRemoteTempFolder::path() const

View File

@ -12,19 +12,20 @@
#include "utils/utils.hpp"
#include "utils/b64ed.hpp"
#include "config.hpp"
bool EXITSTATUSCHECK(int ret)
{
return (ret != -1 && WIFEXITED(ret) && (WEXITSTATUS(ret) == 0)); // ret is -1 if the command failed to execute.
}
#include "utils/directories.hpp"
namespace dropshell
{
bool EXITSTATUSCHECK(int ret)
{
return (ret != -1 && WIFEXITED(ret) && (WEXITSTATUS(ret) == 0)); // ret is -1 if the command failed to execute.
}
bool execute_local_command_interactive(const sCommand &command)
{
if (command.get_command_to_run().empty())
return false;
std::string full_command = command.construct_cmd(); // Get the command string
std::string full_command = command.construct_cmd(gConfig().get_local_executables_path()); // Get the command string
pid_t pid = fork();
@ -55,7 +56,7 @@ namespace dropshell
ASSERT(output != nullptr, "Output string must be provided");
if (command.get_command_to_run().empty())
return false;
std::string full_cmd = command.construct_cmd() + " 2>&1";
std::string full_cmd = command.construct_cmd(gConfig().get_local_executables_path()) + " 2>&1";
FILE *pipe = popen(full_cmd.c_str(), "r");
if (!pipe)
{
@ -72,12 +73,12 @@ namespace dropshell
bool execute_local_command(std::string command, std::string *output, cMode mode)
{
return execute_local_command("",command,{}, output, mode);
return execute_local_command("", command, {}, output, mode);
}
bool execute_local_command(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> &env_vars, std::string *output, cMode mode)
{
sCommand command(directory_to_run_in, gConfig().get_local_executables_path(), command_to_run, env_vars);
sCommand command(directory_to_run_in, command_to_run, env_vars);
if (hasFlag(mode, cMode::Interactive))
{
@ -98,7 +99,7 @@ namespace dropshell
if (command.get_command_to_run().empty())
return false;
bool silent = hasFlag(mode, cMode::Silent);
std::string full_cmd = command.construct_cmd() + " 2>&1" + (silent ? " > /dev/null" : "");
std::string full_cmd = command.construct_cmd(gConfig().get_local_executables_path()) + " 2>&1" + (silent ? " > /dev/null" : "");
int ret = system(full_cmd.c_str());
bool ok = EXITSTATUSCHECK(ret);
@ -121,36 +122,38 @@ namespace dropshell
ssh_cmd << "ssh -p " << ssh_info.port << " " << (hasFlag(mode, cMode::Interactive) ? "-tt " : "")
<< ssh_info.user << "@" << ssh_info.host;
std::string remote_executables_path = remotepath::executables(ssh_info.server_ID);
bool rval = execute_local_command(
"", // directory to run in
ssh_cmd.str() + " " + remote_command.construct_cmd(), // local command to run
{}, // environment variables
output, // output string
mode // mode
);
"", // directory to run in
ssh_cmd.str() + " " + remote_command.construct_cmd(remote_executables_path), // local command to run
{}, // environment variables
output, // output string
mode // mode
);
if (!rval && !hasFlag(mode, cMode::Silent))
{
std::cerr << std::endl
<< std::endl;
std::cerr << "Error: Failed to execute ssh command:" << std::endl;
std::cerr << "\033[90m" << ssh_cmd.str() + " " + remote_command.construct_cmd() << "\033[0m" << std::endl;
std::cerr << "\033[90m" << ssh_cmd.str() + " " + remote_command.construct_cmd(remote_executables_path) << "\033[0m" << std::endl;
std::cerr << std::endl
<< std::endl;
}
return rval;
}
std::string sCommand::makesafecmd(const std::string &command) const
std::string sCommand::makesafecmd(std::string executables_path, const std::string &command) const
{
if (command.empty())
return "";
std::string encoded = base64_encode(dequote(trim(command)));
std::string commandstr = mExecutablesPath + "/bb64 " + encoded;
std::string commandstr = executables_path + "/bb64 " + encoded;
return commandstr;
}
std::string sCommand::construct_cmd() const
std::string sCommand::construct_cmd(std::string executables_path) const
{
if (mCmd.empty())
return "";
@ -167,7 +170,7 @@ namespace dropshell
cmdstr += mCmd;
cmdstr = makesafecmd(cmdstr);
cmdstr = makesafecmd(executables_path, cmdstr);
return cmdstr;
}

View File

@ -28,6 +28,7 @@ typedef struct sSSHInfo {
std::string host;
std::string user;
std::string port;
std::string server_ID; // dropshell name for server.
} sSSHInfo;
bool execute_local_command(std::string command, std::string * output = nullptr, cMode mode = cMode::None);
@ -41,11 +42,10 @@ bool execute_ssh_command(const sSSHInfo & ssh_info, const sCommand & remote_comm
// class to hold a command to run on the remote server.
class sCommand {
public:
sCommand(std::string directory_to_run_in, std::string executables_path, std::string command_to_run, const std::map<std::string, std::string> & env_vars) :
mDir(directory_to_run_in), mExecutablesPath(executables_path), mCmd(command_to_run), mVars(env_vars) {}
sCommand(std::string directory_to_run_in, std::string command_to_run, const std::map<std::string, std::string> & env_vars) :
mDir(directory_to_run_in), mCmd(command_to_run), mVars(env_vars) {}
std::string get_directory_to_run_in() const { return mDir; }
std::string get_executables_path() const { return mExecutablesPath; }
std::string get_command_to_run() const { return mCmd; }
const std::map<std::string, std::string>& get_env_vars() const { return mVars; }
@ -53,18 +53,20 @@ class sCommand {
bool empty() const { return mCmd.empty(); }
std::string construct_cmd() const;
std::string construct_cmd(std::string executables_path) const;
private:
std::string makesafecmd(const std::string& command) const;
std::string makesafecmd(std::string executables_path, const std::string& command) const;
private:
std::string mDir;
std::string mExecutablesPath;
std::string mCmd;
std::map<std::string, std::string> mVars;
};
bool EXITSTATUSCHECK(int ret);
} // namespace dropshell