diff --git a/docker/dropshell_alpine_builder/Dockerfile b/docker/dropshell_alpine/Dockerfile.build similarity index 53% rename from docker/dropshell_alpine_builder/Dockerfile rename to docker/dropshell_alpine/Dockerfile.build index 3620a72..aa87d26 100644 --- a/docker/dropshell_alpine_builder/Dockerfile +++ b/docker/dropshell_alpine/Dockerfile.build @@ -14,9 +14,8 @@ WORKDIR /app COPY . . -COPY --chmod=755 docker/dropshell_alpine_builder/_create_dropshell.sh /scripts/ +COPY --chmod=755 docker/dropshell_alpine/_create_dropshell.sh /scripts/ RUN rm -rf build -# dropshell makesafecmd "cmake .. -DCMAKE_BUILD_TYPE=Release && make -j4 && cp /app/build/dropshell /output/ && chmod a+rwx /output/dropshell" CMD ["/bin/bash","/scripts/_create_dropshell.sh"] diff --git a/docker/dropshell_alpine/Dockerfile.run b/docker/dropshell_alpine/Dockerfile.run new file mode 100644 index 0000000..20cf002 --- /dev/null +++ b/docker/dropshell_alpine/Dockerfile.run @@ -0,0 +1,19 @@ +FROM alpine:latest + +RUN apk add --no-cache \ + libtbb \ + xxhash-dev \ + bash \ + nano + +WORKDIR /app + +COPY docker/dropshell_alpine/output/dropshell /app/dropshell +RUN /bin/bash -c "mkdir -p /opt/dropshell/templates && mkdir -p /config" +COPY templates /opt/dropshell/templates +COPY src/dropshell-completion.bash /etc/bash_completion.d/ + +RUN /app/dropshell init /config +RUN /app/dropshell version + +ENTRYPOINT ["/app/dropshell"] diff --git a/docker/dropshell_alpine_builder/_create_dropshell.sh b/docker/dropshell_alpine/_create_dropshell.sh similarity index 100% rename from docker/dropshell_alpine_builder/_create_dropshell.sh rename to docker/dropshell_alpine/_create_dropshell.sh diff --git a/docker/dropshell_alpine_builder/build.sh b/docker/dropshell_alpine/build.sh similarity index 74% rename from docker/dropshell_alpine_builder/build.sh rename to docker/dropshell_alpine/build.sh index 43d3a65..8800ba4 100755 --- a/docker/dropshell_alpine_builder/build.sh +++ b/docker/dropshell_alpine/build.sh @@ -6,7 +6,7 @@ ROOT_DIR=$(dirname $(dirname $SCRIPT_DIR)) echo "Building dropshell from $ROOT_DIR" -docker build -t dropshell_alpine_builder $ROOT_DIR -f $SCRIPT_DIR/Dockerfile +docker build -t dropshell_alpine_builder $ROOT_DIR -f $SCRIPT_DIR/Dockerfile.build rm -rf $SCRIPT_DIR/output mkdir -p $SCRIPT_DIR/output @@ -17,3 +17,7 @@ MYGID=$(id -g) docker run -it --env CHOWN_USER=$MYUID --env CHOWN_GROUP=$MYGID -v $SCRIPT_DIR/output:/output dropshell_alpine_builder echo "dropshell built in $SCRIPT_DIR/output/dropshell" + +docker build -t gitea.jde.nz/j/dropshell_alpine:latest -t dropshell_alpine $ROOT_DIR -f $SCRIPT_DIR/Dockerfile.run + +docker run -it dropshell_alpine version diff --git a/docker/dropshell_alpine/example.sh b/docker/dropshell_alpine/example.sh new file mode 100755 index 0000000..c99549e --- /dev/null +++ b/docker/dropshell_alpine/example.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if [ $# -lt 1 ]; then + echo " Use: example " + exit 0 +fi + + +( +cd "$1" +echo ZG9ja2VyIHJ1biAtdHQgLXYuOi94IGdpdGVhLmpkZS5uei9qL2Ryb3BzaGVsbF9hbHBpbmUgaGFzaCAveA== | base64 -d | bash +) + diff --git a/docker/dropshell_alpine/publish.sh b/docker/dropshell_alpine/publish.sh new file mode 100755 index 0000000..3745cc2 --- /dev/null +++ b/docker/dropshell_alpine/publish.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker push gitea.jde.nz/j/dropshell_alpine:latest diff --git a/src/main.cpp b/src/main.cpp index 6dd061a..6f00a21 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,8 +18,14 @@ #include #include + namespace dropshell { +extern const std::string VERSION; +extern const std::string RELEASE_DATE; +extern const std::string AUTHOR; +extern const std::string LICENSE; + void print_help() { std::cout << std::endl; maketitle("DropShell version " + VERSION); @@ -57,22 +63,21 @@ void print_help() { } } -} // namespace dropshell int die(const std::string & msg) { std::cerr << msg << std::endl; return 1; } -bool parseargs(std::string arg2, std::string arg3, std::string & server_name, std::vector& servicelist) +bool parseargs(std::string arg2, std::string arg3, std::string & server_name, std::vector& servicelist) { if (arg2.empty()) return false; server_name = arg2; if (arg3.empty()) { - servicelist = dropshell::get_server_services_info(server_name); + servicelist = get_server_services_info(server_name); } else { - servicelist.push_back(dropshell::get_service_info(server_name, arg3)); + servicelist.push_back(get_service_info(server_name, arg3)); } return true; @@ -84,17 +89,27 @@ std::string safearg(int argc, char *argv[], int index) return argv[index]; } -int main(int argc, char* argv[]) { +void printversion() { + maketitle("DropShell version " + VERSION); + std::cout << "Release date: " << RELEASE_DATE << std::endl; + std::cout << "Author: " << AUTHOR << std::endl; + std::cout << "License: " << LICENSE << std::endl; +} - if (safearg(argc,argv,1) == "hash") return dropshell::hash_demo_raw(safearg(argc,argv,2)); +#define HAPPYEXIT(CMD, RUNCMD) {if (safearg(argc,argv,1) == CMD) {RUNCMD; return 0;}} + +int main(int argc, char* argv[]) { + HAPPYEXIT("hash", hash_demo_raw(safearg(argc,argv,2))) + HAPPYEXIT("makesafecmd", std::cout<' to initialise the user directory and create a configuration file."); - const std::vector & local_config_directories = dropshell::gConfig().get_local_config_directories(); + const std::vector & local_config_directories = gConfig().get_local_config_directories(); std::cout << "Config directories: "; for (auto & dir : local_config_directories) std::cout << "["<< dir << "] "; @@ -139,10 +154,10 @@ int main(int argc, char* argv[]) { switch (argc) { case 2: - dropshell::list_servers(); + list_servers(); return 0; case 3: - dropshell::show_server_details(argv[2]); + show_server_details(argv[2]); return 0; case 4: cmd="logs"; @@ -152,65 +167,65 @@ int main(int argc, char* argv[]) { } if (cmd == "templates") { - dropshell::list_templates(); + list_templates(); return 0; } if (cmd == "create-template") { if (argc < 3) return die("Error: create-template requires a template name"); - dropshell::create_template(argv[2]); + create_template(argv[2]); return 0; } if (cmd == "create-server") { if (argc < 3) return die("Error: create-server requires a server name"); - dropshell::create_server(argv[2]); + create_server(argv[2]); return 0; } if (cmd == "create-service") { if (argc < 5) return die("Error: not enough arguments.\ndropshell create-service server template service"); - dropshell::create_service(argv[2], argv[3], argv[4]); + create_service(argv[2], argv[3], argv[4]); return 0; } if (cmd == "ssh" && argc < 4) { if (argc < 3) return die("Error: ssh requires a server name and optionally service name"); - dropshell::interactive_ssh(argv[2], "bash"); + interactive_ssh(argv[2], "bash"); return 0; } if (cmd == "edit" && argc < 4) { ASSERT_MSG(argc>=3, "Error: logic error!"); - dropshell::edit_server(safearg(argc,argv,2)); + edit_server(safearg(argc,argv,2)); return 0; } if (cmd == "backup" || cmd=="backups") { if (argc < 4) return die("Error: backup requires a target server and target service to back up"); - return dropshell::main_commands::backup(argvec); + return main_commands::backup(argvec); } if (cmd == "restore") { if (argc < 4) return die("Error: restore requires a target server, target service the backup file to restore"); - return dropshell::main_commands::restore(argvec); + return main_commands::restore(argvec); } // handle running a command. std::set commands; - dropshell::get_all_used_commands(commands); + get_all_used_commands(commands); commands.merge(std::set{"ssh","edit","_allservicesstatus"}); // handled by service_runner, but not in template_shell_commands. for (const auto& command : commands) { if (cmd == command) { std::string server_name; - std::vector servicelist; + std::vector servicelist; if (!parseargs(safearg(argc, argv, 2), safearg(argc, argv, 3), server_name, servicelist)) { std::cerr << "Error: " << command << " command requires server name and optionally service name" << std::endl; return 1; } for (const auto& service_info : servicelist) { - dropshell::service_runner runner(server_name, service_info.service_name); + service_runner runner(server_name, service_info.service_name); if (!runner.isValid()) { std::cerr << "Error: Failed to initialize service" << std::endl; return 1; @@ -238,4 +253,10 @@ int main(int argc, char* argv[]) { std::cerr << "Error: " << e.what() << std::endl; return 1; } -} \ No newline at end of file +} + +} // namespace dropshell + +int main(int argc, char* argv[]) { + return dropshell::main(argc, argv); +} \ No newline at end of file diff --git a/src/server_env_manager.cpp b/src/server_env_manager.cpp index 88183df..7ddffab 100644 --- a/src/server_env_manager.cpp +++ b/src/server_env_manager.cpp @@ -215,5 +215,11 @@ std::string sCommand::construct_safecmd() const // base64 <<< "FOO=BAR WHEE=YAY bash ./test.sh" // echo YmFzaCAtYyAnRk9PPUJBUiBXSEVFPVlBWSBiYXNoIC4vdGVzdC5zaCcK | base64 -d | bash +std::string makesafecmd(const std::string &command) +{ + std::string encoded = base64_encode(dequote(trim(command))); + std::string commandstr = "echo " + encoded + " | base64 -d | bash"; + return commandstr; +} -} // namespace dropshell \ No newline at end of file +} // namespace dropshell \ No newline at end of file diff --git a/src/server_env_manager.hpp b/src/server_env_manager.hpp index a0a3a97..0639e4e 100644 --- a/src/server_env_manager.hpp +++ b/src/server_env_manager.hpp @@ -34,6 +34,7 @@ class sCommand { std::map mVars; }; +std::string makesafecmd(const std::string& command); // reads path / server.env and provides a class to access the variables. // each env file is required to have the following variables: