Compare commits

..

8 Commits

Author SHA1 Message Date
47dcfca5f2 dropshell release 2025.0514.2222
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
2025-05-14 22:22:15 +12:00
283b88effc Working on install.
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
2025-05-13 22:26:24 +12:00
97776b4642 dropshell release 2025.0513.2220
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
2025-05-13 22:20:16 +12:00
89095cdc50 dropshell release 2025.0513.2200
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
2025-05-13 22:02:02 +12:00
8d5296d9ea Merge branch 'main' of https://gitea.jde.nz/public/dropshell
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
2025-05-13 21:56:47 +12:00
524d3df1b2 dropshell release 2025.0513.2156 2025-05-13 21:56:24 +12:00
54dce4862f Update README.md
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
2025-05-13 21:54:18 +12:00
1dd4a7958d dropshell release 2025.0513.2151
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
2025-05-13 21:51:53 +12:00
13 changed files with 189 additions and 69 deletions

View File

@ -1,3 +1,9 @@
# Dropshell # Dropshell
A system management tool for server operations, written in C++. A system management tool for server operations, written in C++.
## Installation
```
curl -fsSL https://gitea.jde.nz/public/dropshell/releases/download/latest/install.sh | bash
```

View File

@ -9,15 +9,11 @@ GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Parse command line arguments JOBS=4
AUTO_INSTALL=false # Determine number of CPU cores for parallel build
for arg in "$@"; do if command -v nproc >/dev/null 2>&1; then
case $arg in JOBS=$(nproc)
--auto-install) fi
AUTO_INSTALL=true
;;
esac
done
# Function to print status messages # Function to print status messages
@ -79,7 +75,7 @@ cmake .. -DCMAKE_BUILD_TYPE=Debug
# Build the project # Build the project
print_status "Building project..." print_status "Building project..."
make -j$(nproc) make -j"$JOBS"
# Check if build was successful # Check if build was successful
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
@ -90,27 +86,16 @@ else
exit 1 exit 1
fi fi
# Check if user wants to install print_status "Auto-installing dropshell..."
if [ $AUTO_INSTALL = true ]; then sudo make install
print_status "Auto-installing dropshell..." if [ $? -eq 0 ]; then
sudo make install print_status "Installation successful!"
if [ $? -eq 0 ]; then
print_status "Installation successful!"
else
print_error "Installation failed!"
exit 1
fi
else else
print_status "Installing dropshell..." print_error "Installation failed!"
sudo make install exit 1
if [ $? -eq 0 ]; then
print_status "Installation successful!"
else
print_error "Installation failed!"
exit 1
fi
fi fi
# Return to original directory # Return to original directory
cd .. cd ..

47
install.sh Executable file
View File

@ -0,0 +1,47 @@
#!/bin/bash
set -e
# download and install dropshell
# Check if running as root
if [ "$EUID" -ne 0 ]; then
print_error "Please run this script as root (use sudo)"
exit 1
fi
# 1. Determine architecture
# -----------------------------------------------------------------------------
ARCH=$(uname -m)
if [[ "$ARCH" == "x86_64" ]]; then
BIN=dropshell.amd64
elif [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
BIN=dropshell.arm64
else
echo "Unsupported architecture: $ARCH" >&2
exit 1
fi
# 2. Download the appropriate binary to a temp directory
# -----------------------------------------------------------------------------
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
URL="https://gitea.jde.nz/public/dropshell/releases/download/latest/$BIN"
echo "Downloading $BIN from $URL..."
curl -fsSL -o "$TMPDIR/dropshell" "$URL"
if [ ! -f "$TMPDIR/dropshell" ]; then
echo "Failed to download dropshell" >&2
exit 1
fi
chmod +x "$TMPDIR/dropshell"
cp "$TMPDIR/dropshell" /usr/local/bin/dropshell
ln -s /usr/local/bin/dropshell /usr/local/bin/ds
rm -rf "$TMPDIR"
echo "dropshell installed successfully to /usr/local/bin/dropshell"

View File

@ -6,20 +6,47 @@
set -e set -e
# Build for amd64 rm -f build_amd64/dropshell build_arm64/dropshell build/dropshell.amd64 build/dropshell.arm64
echo "Building for amd64..."
cmake -B build_amd64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-march=x86-64" . # Determine number of CPU cores for parallel build
cmake --build build_amd64 --target dropshell --config Release if command -v nproc >/dev/null 2>&1; then
JOBS=$(nproc)
else
JOBS=4 # fallback default
fi
# Build for amd64 (musl)
echo "Building for amd64 (musl)..."
cmake -B build_amd64 -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=x86_64-linux-musl-gcc \
-DCMAKE_CXX_COMPILER=x86_64-linux-musl-g++ \
-DCMAKE_EXE_LINKER_FLAGS="-static" \
-DCMAKE_CXX_FLAGS="-march=x86-64" .
cmake --build build_amd64 --target dropshell --config Release -j"$JOBS"
mkdir -p build mkdir -p build
cp build_amd64/dropshell build/dropshell.amd64 cp build_amd64/dropshell build/dropshell.amd64
# Build for arm64 # Build for arm64 (musl)
echo "Building for arm64..." echo "Building for arm64 (musl)..."
cmake -B build_arm64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-march=armv8-a" -DCMAKE_SYSTEM_PROCESSOR=aarch64 -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ . cmake -B build_arm64 -DCMAKE_BUILD_TYPE=Release \
cmake --build build_arm64 --target dropshell --config Release -DCMAKE_C_COMPILER=aarch64-linux-musl-gcc \
-DCMAKE_CXX_COMPILER=aarch64-linux-musl-g++ \
-DCMAKE_EXE_LINKER_FLAGS="-static" \
-DCMAKE_CXX_FLAGS="-march=armv8-a" \
-DCMAKE_SYSTEM_PROCESSOR=aarch64 .
cmake --build build_arm64 --target dropshell --config Release -j"$JOBS"
mkdir -p build mkdir -p build
cp build_arm64/dropshell build/dropshell.arm64 cp build_arm64/dropshell build/dropshell.arm64
if [ ! -f build/dropshell.amd64 ]; then
echo "build/dropshell.amd64 not found!" >&2
exit 1
fi
if [ ! -f build/dropshell.arm64 ]; then
echo "build/dropshell.arm64 not found!" >&2
exit 1
fi
echo "Builds complete:" echo "Builds complete:"
ls -lh build/dropshell.* ls -lh build/dropshell.*

View File

@ -72,7 +72,7 @@ if [ -z "$RELEASE_ID" ]; then
fi fi
# Upload binaries and install.sh # Upload binaries and install.sh
for FILE in dropshell.amd64 dropshell.arm64 install.sh; do for FILE in dropshell.amd64 dropshell.arm64 install.sh server_autosetup.sh; do
if [ -f "build/$FILE" ]; then if [ -f "build/$FILE" ]; then
filetoupload="build/$FILE" filetoupload="build/$FILE"
elif [ -f "$FILE" ]; then elif [ -f "$FILE" ]; then

View File

@ -55,6 +55,13 @@ if ! command -v docker &> /dev/null; then
rm get-docker.sh rm get-docker.sh
fi fi
# check bb64 installation
if ! command -v bb64 &> /dev/null; then
echo "bb64 is not installed."
echo "Installing bb64..."
curl -fsSL https://gitea.jde.nz/public/bb64/releases/download/latest/install.sh | bash
fi
# check dropshell user exists # check dropshell user exists
if ! id "dropshell" &> /dev/null; then if ! id "dropshell" &> /dev/null; then
echo "Dropshell user does not exist." echo "Dropshell user does not exist."

View File

@ -102,8 +102,6 @@ int edit_config()
gConfig().save_config(true); gConfig().save_config(true);
// make sure we have executables.
std::cout << "Successfully edited config file at " << config_file << std::endl; std::cout << "Successfully edited config file at " << config_file << std::endl;
return 0; return 0;
} }

View File

@ -170,7 +170,7 @@ namespace dropshell
result += buffer; result += buffer;
} }
pclose(pipe); pclose(pipe);
return result; return trim(result);
} }
int update_dropshell() int update_dropshell()
@ -243,20 +243,90 @@ namespace dropshell
return -1; return -1;
} }
int install_local_agent()
{
std::vector<std::filesystem::path> paths = {
gConfig().get_local_template_cache_path(),
gConfig().get_local_backup_path(),
gConfig().get_local_tempfiles_path(),
localpath::agent()
};
for (auto &p : gConfig().get_local_server_definition_paths())
paths.push_back(p);
for (auto &p : paths)
if (!std::filesystem::exists(p))
{
std::cout << "Creating directory: " << p << std::endl;
std::filesystem::create_directories(p);
}
// download bb64.
if (!std::filesystem::exists(localpath::agent()+"bb64"))
{
std::string cmd = "cd " + localpath::agent() + " && 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 " << localpath::agent() << std::endl;
else
std::cerr << "Failed to download bb64 to " << localpath::agent() << std::endl;
} else {
std::cout << "Updating bb64..." << std::endl;
system((localpath::agent()+"bb64 -u").c_str()); // update.
}
return 0;
}
int install_host() int install_host()
{ {
// update dropshell. // update dropshell.
// install the local dropshell agent. // install the local dropshell agent.
return update_dropshell(); int rval = update_dropshell();
if (rval != 0)
return rval;
rval = install_local_agent();
if (rval != 0)
return rval;
std::cout << "Installation complete." << std::endl;
return 0;
} }
int install_server(const std::string &server) int install_server(const std::string &server)
{ {
// install the dropshell agent on the given server. // install the dropshell agent on the given server.
std::cout << "Installing dropshell agent on " << server << std::endl;
std::string agent_path = remotepath::agent(server);
if (agent_path.empty())
{
std::cerr << "Failed to get agent path for " << server << std::endl;
return 1;
}
// first install bb64.
std::string remote_cmd =
"curl -fsSL https://gitea.jde.nz/public/bb64/releases/download/latest/install.sh | bash -s -- " + agent_path;
server_env_manager server_env(server);
if (!server_env.is_valid()) {
std::cerr << "Invalid server environment for " << server << std::endl;
return 1;
}
std::string fullcmd = "ssh -p " + server_env.get_SSH_INFO().port + " " + server_env.get_SSH_INFO().user + "@" + server_env.get_SSH_INFO().host;
fullcmd += " bash -c '" + remote_cmd + "'";
std::cout << "Executing: " << fullcmd << std::endl;
if (!execute_local_command(fullcmd, nullptr, cMode::Silent)) {
std::cerr << "Failed to download bb64 to " << agent_path << " on remote server." << std::endl;
} else {
std::cout << "Downloaded bb64 to " << agent_path << " on remote server." << std::endl;
}
return 0; // NOTIMPL
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -9,7 +9,7 @@
#include "utils/assert.hpp" #include "utils/assert.hpp"
#pragma TODO("Fix issues with Nuke below.") #pragma message ("TODO: Fix issues with Nuke below.")
/* /*

View File

@ -61,7 +61,6 @@ bool config::save_config(bool create_aux_directories)
std::string dropshell_base = homedir + "/.dropshell"; std::string dropshell_base = homedir + "/.dropshell";
mConfig["tempfiles"] = dropshell_base + "/tmp"; mConfig["tempfiles"] = dropshell_base + "/tmp";
mConfig["backups"] = dropshell_base + "/backups"; mConfig["backups"] = dropshell_base + "/backups";
mConfig["executables"] = dropshell_base + "/executables";
mConfig["template_cache"] = dropshell_base + "/template_cache"; mConfig["template_cache"] = dropshell_base + "/template_cache";
mConfig["template_registry_URLs"] = { mConfig["template_registry_URLs"] = {
@ -85,8 +84,7 @@ bool config::save_config(bool create_aux_directories)
std::vector<std::filesystem::path> paths = { std::vector<std::filesystem::path> paths = {
get_local_template_cache_path(), get_local_template_cache_path(),
get_local_backup_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()) for (auto & p : get_local_server_definition_paths())
paths.push_back(p); paths.push_back(p);
@ -98,18 +96,7 @@ bool config::save_config(bool create_aux_directories)
std::filesystem::create_directories(p); std::filesystem::create_directories(p);
} }
} }
// 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; return true;
} }
@ -135,11 +122,6 @@ std::string config::get_local_template_cache_path() {
return mConfig["template_cache"]; return mConfig["template_cache"];
} }
std::string config::get_local_executables_path()
{
return mConfig["executables"];
}
std::vector<std::string> config::get_template_registry_urls() { std::vector<std::string> config::get_template_registry_urls() {
nlohmann::json template_registry_urls = mConfig["template_registry_URLs"]; nlohmann::json template_registry_urls = mConfig["template_registry_URLs"];
std::vector<std::string> urls; std::vector<std::string> urls;

View File

@ -20,7 +20,6 @@ class config {
std::string get_local_tempfiles_path(); std::string get_local_tempfiles_path();
std::string get_local_backup_path(); std::string get_local_backup_path();
std::string get_local_template_cache_path(); std::string get_local_template_cache_path();
std::string get_local_executables_path();
std::vector<std::string> get_template_registry_urls(); std::vector<std::string> get_template_registry_urls();
std::vector<std::string> get_template_local_paths(); std::vector<std::string> get_template_local_paths();
std::vector<std::string> get_local_server_definition_paths(); std::vector<std::string> get_local_server_definition_paths();

View File

@ -12,6 +12,7 @@ namespace dropshell {
// local user config directories // local user config directories
// ~/.config/dropshell/dropshell.json // ~/.config/dropshell/dropshell.json
// ~/.local/dropshell_agent/bb64
// server_definition_path // server_definition_path
// |-- <server_name> // |-- <server_name>
@ -27,8 +28,6 @@ namespace dropshell {
// temp files path // temp files path
// executables path
// template cache path // template cache path
// |-- templates // |-- templates
// | |-- <template_name>.json // | |-- <template_name>.json

View File

@ -25,7 +25,7 @@ namespace dropshell
{ {
if (command.get_command_to_run().empty()) if (command.get_command_to_run().empty())
return false; return false;
std::string full_command = command.construct_cmd(gConfig().get_local_executables_path()); // Get the command string std::string full_command = command.construct_cmd(localpath::agent()); // Get the command string
pid_t pid = fork(); pid_t pid = fork();
@ -56,7 +56,7 @@ namespace dropshell
ASSERT(output != nullptr, "Output string must be provided"); ASSERT(output != nullptr, "Output string must be provided");
if (command.get_command_to_run().empty()) if (command.get_command_to_run().empty())
return false; return false;
std::string full_cmd = command.construct_cmd(gConfig().get_local_executables_path()) + " 2>&1"; std::string full_cmd = command.construct_cmd(localpath::agent()) + " 2>&1";
FILE *pipe = popen(full_cmd.c_str(), "r"); FILE *pipe = popen(full_cmd.c_str(), "r");
if (!pipe) if (!pipe)
{ {
@ -99,7 +99,7 @@ namespace dropshell
if (command.get_command_to_run().empty()) if (command.get_command_to_run().empty())
return false; return false;
bool silent = hasFlag(mode, cMode::Silent); bool silent = hasFlag(mode, cMode::Silent);
std::string full_cmd = command.construct_cmd(gConfig().get_local_executables_path()) + " 2>&1" + (silent ? " > /dev/null" : ""); std::string full_cmd = command.construct_cmd(localpath::agent()) + " 2>&1" + (silent ? " > /dev/null" : "");
int ret = system(full_cmd.c_str()); int ret = system(full_cmd.c_str());
bool ok = EXITSTATUSCHECK(ret); bool ok = EXITSTATUSCHECK(ret);