Compare commits

...

7 Commits

Author SHA1 Message Date
c836b26657 dropshell release 2025.0527.2201
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m44s
2025-05-27 22:01:51 +12:00
7bf624589f tidying
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m46s
2025-05-26 23:39:40 +12:00
a5e339a358 tidying
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m37s
2025-05-26 23:26:37 +12:00
029823a6b4 tidying
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m52s
2025-05-26 23:22:38 +12:00
f79abd346e Tidying
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 3m2s
2025-05-26 23:19:10 +12:00
940c2a12a1 dropshell release 2025.0526.2310
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m58s
2025-05-26 23:12:28 +12:00
6ac651d4f0 Tidying
Some checks failed
Dropshell Test / Build_and_Test (push) Failing after 2m40s
2025-05-26 22:49:37 +12:00
11 changed files with 167 additions and 179 deletions

View File

@ -1,4 +1,6 @@
# can you make this script run in bash, but fall back to sh if bash is not installed? #!/bin/bash
# set up a remote server for use with dropshell.
# check if we are running as root # check if we are running as root
if [ "$(id -u)" -ne 0 ]; then if [ "$(id -u)" -ne 0 ]; then

View File

@ -46,17 +46,16 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
file(GLOB_RECURSE SOURCES "src/*.cpp") file(GLOB_RECURSE SOURCES "src/*.cpp")
file(GLOB_RECURSE HEADERS "src/*.hpp") file(GLOB_RECURSE HEADERS "src/*.hpp")
# Add custom target to run make_createagent.sh at the start of the build process # Add custom target to run cmake_prebuild.sh at the start of the build process
add_custom_target(run_createagent ALL add_custom_target(run_prebuild_script ALL
COMMAND ${CMAKE_COMMAND} -E echo "Running make_createagent.sh..." COMMAND ${CMAKE_COMMAND} -E echo "Running cmake_prebuild.sh..."
COMMAND ${CMAKE_COMMAND} -E env bash ${CMAKE_CURRENT_SOURCE_DIR}/make_createagent.sh COMMAND ${CMAKE_COMMAND} -E env bash ${CMAKE_CURRENT_SOURCE_DIR}/cmake_prebuild.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Running make_createagent.sh before build"
) )
# Add executable # Add executable
add_executable(dropshell ${SOURCES}) add_executable(dropshell ${SOURCES})
add_dependencies(dropshell run_createagent) add_dependencies(dropshell run_prebuild_script)
# Mark the generated files as GENERATED so CMake knows they'll be created during build # Mark the generated files as GENERATED so CMake knows they'll be created during build
set_source_files_properties( set_source_files_properties(

View File

@ -1,5 +1,8 @@
#!/bin/bash #!/bin/bash
# install the dropshell host agent on this computer.
# (not for remote servers)
SCRIPT_DIR=$(dirname "$0") SCRIPT_DIR=$(dirname "$0")
echo "Installing dropshell host agent on this computer..." echo "Installing dropshell host agent on this computer..."
@ -22,27 +25,6 @@ _check_required_env_vars() {
done done
} }
# Checks if Docker is installed, running, and user has permission. Returns 1 on failure.
_check_docker_installed() {
if ! command -v docker &> /dev/null; then
echo "Docker is not installed"
return 1
fi
# check if docker daemon is running
if ! docker info &> /dev/null; then
echo "Docker daemon is not running"
return 1
fi
# check if user has permission to run docker
if ! docker run --rm hello-world &> /dev/null; then
echo "User does not have permission to run docker"
return 1
fi
return 0
}
function install_bb64() { function install_bb64() {
# check curl installed # check curl installed
@ -77,7 +59,5 @@ set +a
_check_required_env_vars "AGENT_LOCAL_PATH" _check_required_env_vars "AGENT_LOCAL_PATH"
echo "Installing host agent into $AGENT_LOCAL_PATH" echo "Installing host agent into $AGENT_LOCAL_PATH"
_check_docker_installed || _die "Docker is required."
install_bb64 install_bb64

View File

@ -53,6 +53,12 @@ if ! command -v docker &> /dev/null; then
exit 1 exit 1
fi fi
# check rsync installation
if ! command -v rsync &> /dev/null; then
echo "Rsync is not installed. Rsync is required for agent installation."
exit 1
fi
#------------------------------------------------------------------------- #-------------------------------------------------------------------------

View File

@ -1,86 +1,45 @@
#!/bin/bash #!/bin/bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
OUTPUT_DIR=${SCRIPT_DIR}/output
INSTALL_DIR=${HOME}/.local/bin
mkdir -p ${OUTPUT_DIR}
# Exit on error # Exit on error
set -e set -e
# Colors for output function build_native() {
RED='\033[0;31m' local BUILDDIR=${SCRIPT_DIR}/build/native
GREEN='\033[0;32m' local PREVDIR=$PWD
YELLOW='\033[1;33m' local JOBS=$(nproc) # Set JOBS to the number of available CPU cores
NC='\033[0m' # No Color mkdir -p ${BUILDDIR}
cd ${SCRIPT_DIR}
JOBS=4 CC="${HOME}/.musl-cross/x86_64-linux-musl-native/bin/x86_64-linux-musl-gcc"
# Determine number of CPU cores for parallel build CXX="${HOME}/.musl-cross/x86_64-linux-musl-native/bin/x86_64-linux-musl-g++"
if command -v nproc >/dev/null 2>&1; then
JOBS=$(nproc)
fi
# Function to print status messages
print_status() {
echo -e "${GREEN}[*] $1${NC}"
}
print_error() { cmake -B ${BUILDDIR} -G Ninja \
echo -e "${RED}[!] $1${NC}" -DCMAKE_BUILD_TYPE=Debug \
} -DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_LINKER=mold \
-DCMAKE_C_COMPILER=${CC} \
-DCMAKE_CXX_COMPILER=${CXX}
print_warning() { cd ${BUILDDIR}
echo -e "${YELLOW}[!] $1${NC}"
}
# ensure we have latest dehydrate.
dehydrate -u
# Check if build directory exists, if not create it
if [ ! -d "build" ]; then
print_status "Creating build directory..."
mkdir build
fi
# Enter build directory
cd build
# Check if CMake is installed
if ! command -v cmake &> /dev/null; then
print_error "CMake is not installed. Please install CMake first."
exit 1
fi
# Check if Ninja is installed
if ! command -v ninja &> /dev/null; then
print_error "Ninja is not installed. Please install Ninja first."
exit 1
fi
# Check if ccache is installed
if ! command -v ccache &> /dev/null; then
print_warning "ccache is not installed. Builds will be slower without it."
print_warning "Consider installing ccache for faster builds."
fi
# Configure with CMake
print_status "Configuring with CMake..."
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
# Build the project
print_status "Building project..."
ninja -j"$JOBS" ninja -j"$JOBS"
# Check if build was successful #upx ${BUILDDIR}/dropshell
if [ $? -eq 0 ]; then cp ${BUILDDIR}/dropshell ${OUTPUT_DIR}/dropshell.native
print_status "Build successful!"
else
print_error "Build failed!"
exit 1
fi
print_status "Auto-installing dropshell locally..." cd ${PREVDIR}
mkdir -p "${HOME}/.local/bin" }
cp "$SCRIPT_DIR/build/dropshell" "${HOME}/.local/bin/dropshell"
# Return to original directory build_native
cd ..
print_status "Build process completed!" echo "Auto-installing dropshell locally..."
mkdir -p "${INSTALL_DIR}"
cp "${OUTPUT_DIR}/dropshell.native" "${INSTALL_DIR}/dropshell"
ds version
echo "Build process completed!"

View File

@ -1,6 +1,9 @@
#!/bin/bash #!/bin/bash
set -e set -e
# CMake pre-build script.
# Runs before the build process.
# This script creates two files: # This script creates two files:
# src/utils/createagent.hpp # src/utils/createagent.hpp
# src/utils/createagent.cpp # src/utils/createagent.cpp
@ -11,9 +14,11 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if ! command -v dehydrate &> /dev/null; then if ! command -v dehydrate &> /dev/null; then
echo "dehydrate could not be found - installing" echo "dehydrate could not be found - installing"
curl -fsSL https://gitea.jde.nz/public/dehydrate/releases/download/latest/install.sh | bash curl -fsSL https://gitea.jde.nz/public/dehydrate/releases/download/latest/install.sh | bash
else
# ensure we have latest dehydrate.
dehydrate -u
fi fi
mkdir -p "${SCRIPT_DIR}/src/autogen" mkdir -p "${SCRIPT_DIR}/src/autogen"
dehydrate "${SCRIPT_DIR}/agent-remote" "${SCRIPT_DIR}/src/autogen" dehydrate "${SCRIPT_DIR}/agent-remote" "${SCRIPT_DIR}/src/autogen"
dehydrate "${SCRIPT_DIR}/agent-local" "${SCRIPT_DIR}/src/autogen" dehydrate "${SCRIPT_DIR}/agent-local" "${SCRIPT_DIR}/src/autogen"

View File

@ -37,11 +37,16 @@ fi
print_status "Detected OS: $OS $VER" print_status "Detected OS: $OS $VER"
#----------------------------------------------------------------------------------------------------------
# INSTALL PREREQUISITE PACKAGES
#----------------------------------------------------------------------------------------------------------
# Define packages based on distribution # Define packages based on distribution
case $OS in case $OS in
"Ubuntu"|"Debian GNU/Linux") "Ubuntu"|"Debian GNU/Linux")
# Common packages for both Ubuntu and Debian # Common packages for both Ubuntu and Debian
PACKAGES="cmake make g++ devscripts debhelper build-essential upx" PACKAGES="cmake make g++ devscripts debhelper build-essential upx musl-tools wget tar ccache ninja-build"
;; ;;
*) *)
print_error "Unsupported distribution: $OS" print_error "Unsupported distribution: $OS"
@ -73,19 +78,9 @@ for pkg in $PACKAGES; do
fi fi
done done
# Verify all required tools are installed # ----------------------------------------------------------------------------------------------------------
print_status "Verifying installation..." # MUSL CROSS COMPILERS
for tool in cmake make g++; do # ----------------------------------------------------------------------------------------------------------
if ! command -v "$tool" &> /dev/null; then
print_error "$tool is not installed properly"
exit 1
fi
done
# Install other required packages
apt install -y musl-tools wget tar ccache ninja-build
# Set install directory # Set install directory
if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then
@ -96,59 +91,58 @@ fi
INSTALL_DIR="$USER_HOME/.musl-cross" INSTALL_DIR="$USER_HOME/.musl-cross"
mkdir -p "$INSTALL_DIR" mkdir -p "$INSTALL_DIR"
MUSL_CC_URL="https://musl.cc"
TMPDIR=$(mktemp -d) TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT trap 'rm -rf "$TMPDIR"' EXIT
# x86_64 function install_musl_cross() {
if [ ! -d "$INSTALL_DIR/x86_64-linux-musl-cross" ]; then local TOOLCHAIN="$1"
echo "Downloading x86_64 musl cross toolchain..." local MUSL_CC_URL="https://musl.cc"
wget -nc -O "$TMPDIR/x86_64-linux-musl-cross.tgz" $MUSL_CC_URL/x86_64-linux-musl-cross.tgz if [ ! -d "$INSTALL_DIR/$TOOLCHAIN" ]; then
tar -C "$INSTALL_DIR" -xvf "$TMPDIR/x86_64-linux-musl-cross.tgz" echo "Downloading $TOOLCHAIN musl cross toolchain..."
wget -nc -O "$TMPDIR/$TOOLCHAIN.tgz" $MUSL_CC_URL/$TOOLCHAIN.tgz
tar -C "$INSTALL_DIR" -xvf "$TMPDIR/$TOOLCHAIN.tgz"
fi fi
}
# aarch64 function check_path() {
if [ ! -d "$INSTALL_DIR/aarch64-linux-musl-cross" ]; then if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then
echo "Downloading aarch64 musl cross toolchain..." local BASHRC="$USER_HOME/.bashrc"
wget -nc -O "$TMPDIR/aarch64-linux-musl-cross.tgz" $MUSL_CC_URL/aarch64-linux-musl-cross.tgz local TOOLCHAIN="$1"
tar -C "$INSTALL_DIR" -xvf "$TMPDIR/aarch64-linux-musl-cross.tgz" local MUSL_PATH="$INSTALL_DIR/$TOOLCHAIN/bin"
if ! echo "$PATH" | grep -q "$MUSL_PATH"; then
echo "Adding $MUSL_PATH to PATH in $BASHRC"
PATH_LINE="export PATH=\"$MUSL_PATH:\$PATH\""
if ! grep -Fxq "$PATH_LINE" "$BASHRC"; then
echo "" >> "$BASHRC"
echo "# Add musl cross compilers to PATH for dropshell" >> "$BASHRC"
echo "$PATH_LINE" >> "$BASHRC"
echo "Added musl cross compilers to $BASHRC"
echo "You should run 'source ~/.bashrc' to update your PATH"
else
echo "You should run 'source ~/.bashrc' to update your PATH"
fi fi
fi
fi
}
# Print instructions for adding to PATH
# cat <<EOF
# To use the musl cross compilers, add the following to your shell: TOOLCHAIN_LIST=(
# export PATH="$INSTALL_DIR/x86_64-linux-musl-cross/bin:$INSTALL_DIR/aarch64-linux-musl-cross/bin:$PATH" "aarch64-linux-musl-cross"
"x86_64-linux-musl-cross"
"x86_64-linux-musl-native"
)
# Or run: for TOOLCHAIN in "${TOOLCHAIN_LIST[@]}"; do
# export PATH="$INSTALL_DIR/x86_64-linux-musl-cross/bin:$INSTALL_DIR/aarch64-linux-musl-cross/bin:\$PATH" install_musl_cross "$TOOLCHAIN"
check_path "$TOOLCHAIN"
# EOF done
# Clean up # Clean up
rm -rf "$TMPDIR" rm -rf "$TMPDIR"
# If run with sudo, add to invoking user's ~/.bashrc # ----------------------------------------------------------------------------------------------------------
if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then # COMPLETE
BASHRC="$USER_HOME/.bashrc" # ----------------------------------------------------------------------------------------------------------
EXPORT_LINE="export PATH=\"$INSTALL_DIR/x86_64-linux-musl-cross/bin:$INSTALL_DIR/aarch64-linux-musl-cross/bin:\$PATH\""
if ! grep -Fxq "$EXPORT_LINE" "$BASHRC"; then
echo "" >> "$BASHRC"
echo "# Add musl cross compilers to PATH for bb64" >> "$BASHRC"
echo "$EXPORT_LINE" >> "$BASHRC"
echo "Added musl cross compilers to $BASHRC"
else
echo "musl cross compiler PATH already present in $BASHRC"
fi
fi
# check if dehydrate command is installed
if ! command -v dehydrate &> /dev/null; then
curl -fsSL https://gitea.jde.nz/public/dehydrate/releases/download/latest/install.sh | bash
fi
dehydrate -u
print_status "All dependencies installed successfully!" print_status "All dependencies installed successfully!"
print_status "You can now run ./build.sh to build the project" print_status "You can now run ./build.sh to build the project"

View File

@ -1,11 +1,15 @@
#!/bin/bash #!/bin/bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# Create output directory # Create output directory
mkdir -p output mkdir -p ${SCRIPT_DIR}/output
function build_arch() { function build_arch() {
local arch=$1 local arch=$1
local PREVDIR=$PWD
cd ${SCRIPT_DIR}
if [ ! -f "${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-c++" ]; then if [ ! -f "${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-c++" ]; then
echo "Musl cross compiler for ${arch} not found. Please run install_build_prerequisites.sh first." echo "Musl cross compiler for ${arch} not found. Please run install_build_prerequisites.sh first."
@ -16,14 +20,16 @@ function build_arch() {
CC="${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-gcc" CC="${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-gcc"
CXX="${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-g++" CXX="${HOME}/.musl-cross/${arch}-linux-musl-cross/bin/${arch}-linux-musl-g++"
BUILDDIR=build/${arch} BUILDDIR=${SCRIPT_DIR}/build/${arch}
mkdir -p ${BUILDDIR} mkdir -p ${BUILDDIR}
cmake -B ${BUILDDIR} -G Ninja -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} cmake -B ${BUILDDIR} -G Ninja -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX}
cmake --build ${BUILDDIR} cmake --build ${BUILDDIR}
upx ${BUILDDIR}/dropshell upx ${BUILDDIR}/dropshell
cp ${BUILDDIR}/dropshell output/dropshell.${arch} cp ${BUILDDIR}/dropshell ${SCRIPT_DIR}/output/dropshell.${arch}
cd ${PREVDIR}
} }
build_arch x86_64 build_arch x86_64

View File

@ -130,6 +130,28 @@ int edit_server(const std::string &server_name)
return 0; return 0;
} }
void list_directory(std::string dir, std::string msg)
{
bool first=true;
std::vector<std::string> directories;
for (const auto &file : std::filesystem::directory_iterator(dir))
{
if (first)
{
if (!msg.empty())
info << msg << std::endl;
first=false;
}
if (std::filesystem::is_directory(file.path()))
directories.push_back(file.path());
else
info << " " << file.path() << std::endl;
}
for (const auto &dir : directories)
list_directory(dir, "");
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// edit service config // edit service config
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -143,7 +165,14 @@ int edit_service_config(const std::string &server, const std::string &service)
} }
if (edit_file(config_file, true) && std::filesystem::exists(config_file)) if (edit_file(config_file, true) && std::filesystem::exists(config_file))
info << "To apply your changes, run:\n dropshell install " + server + " " + service << std::endl; info << "Successfully edited service config file at " << config_file << std::endl;
std::string service_dir = localpath::service(server, service);
list_directory(service_dir, "You may wish to edit the other files in " + service_dir);
info << "Then to apply your changes, run:" << std::endl;
info << " dropshell uninstall " + server + " " + service << std::endl;
info << " dropshell install " + server + " " + service << std::endl;
return 0; return 0;
} }

View File

@ -69,7 +69,26 @@ namespace dropshell
std::string server = server_env.get_server_name(); std::string server = server_env.get_server_name();
LocalServiceInfo service_info = get_service_info(server_env.get_server_name(), service); LocalServiceInfo service_info = get_service_info(server_env.get_server_name(), service);
if (!SIvalid(service_info) || !service_info.service_template_hash_match) if (!SIvalid(service_info))
{
error << "Failed to install - service information not valid." << std::endl;
return false;
}
if (!server_env.is_valid())
return false; // should never hit this.
std::string user = server_env.get_user_for_service(service);
std::string remote_service_path = remotepath(server,user).service(service);
if (server_env.check_remote_dir_exists(remote_service_path, user))
{ // uninstall the old service before we update the config or template!
info << "Service " << service << " is already installed on " << server << std::endl;
shared_commands::uninstall_service(server_env, service);
}
if (!service_info.service_template_hash_match)
{ {
warning << "Service " << service << " is using an old template. Updating. " << std::endl; warning << "Service " << service << " is using an old template. Updating. " << std::endl;
if (!merge_updated_service_template(server_env.get_server_name(), service)) if (!merge_updated_service_template(server_env.get_server_name(), service))
@ -88,9 +107,6 @@ namespace dropshell
maketitle("Installing " + service + " (" + service_info.template_name + ") on " + server); maketitle("Installing " + service + " (" + service_info.template_name + ") on " + server);
if (!server_env.is_valid())
return false; // should never hit this.
// Check if template exists // Check if template exists
template_info tinfo = gTemplateManager().get_template_info(service_info.template_name); template_info tinfo = gTemplateManager().get_template_info(service_info.template_name);
if (!tinfo.is_set()) if (!tinfo.is_set())
@ -103,8 +119,6 @@ namespace dropshell
} }
// Create service directory // Create service directory
std::string user = server_env.get_user_for_service(service);
std::string remote_service_path = remotepath(server,user).service(service);
std::string mkdir_cmd = "mkdir -p " + quote(remote_service_path); std::string mkdir_cmd = "mkdir -p " + quote(remote_service_path);
if (!execute_ssh_command(server_env.get_SSH_INFO(user), sCommand("", mkdir_cmd, {}), cMode::Silent)) if (!execute_ssh_command(server_env.get_SSH_INFO(user), sCommand("", mkdir_cmd, {}), cMode::Silent))
{ {
@ -112,14 +126,6 @@ namespace dropshell
return false; return false;
} }
// Check if rsync is installed on remote host
std::string check_rsync_cmd = "which rsync";
if (!execute_ssh_command(server_env.get_SSH_INFO(user), sCommand("", check_rsync_cmd, {}), cMode::Silent))
{
std::cerr << "rsync is not installed on the remote host" << std::endl;
return false;
}
// Copy template files // Copy template files
debug << "Copying: [LOCAL] " << tinfo.local_template_path() << std::endl debug << "Copying: [LOCAL] " << tinfo.local_template_path() << std::endl
<< std::string(8, ' ') << "[REMOTE] " << remotepath(server,user).service_template(service) << "/" << std::endl; << std::string(8, ' ') << "[REMOTE] " << remotepath(server,user).service_template(service) << "/" << std::endl;

View File

@ -345,6 +345,8 @@ namespace dropshell
return std::nullopt; return std::nullopt;
} }
env_vars["HOST_NAME"] = get_SSH_HOST();
std::string argstr = ""; std::string argstr = "";
for (const auto &arg : args) for (const auto &arg : args)
{ {