Add install option
This commit is contained in:
parent
32413f17bd
commit
0a2036cbd7
14
src/autocomplete.hpp
Normal file
14
src/autocomplete.hpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __AUTOCOMPLETE_H
|
||||||
|
#define __AUTOCOMPLETE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace dropshell {
|
||||||
|
|
||||||
|
std::vector<std::string> autocomplete_list_servers();
|
||||||
|
std::vector<std::string> autocomplete_list_services(const std::string& server_name);
|
||||||
|
|
||||||
|
} // namespace dropshell
|
||||||
|
|
||||||
|
#endif // __AUTOCOMPLETE_H
|
@ -7,7 +7,7 @@ _dropshell_completions() {
|
|||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
|
||||||
# List of main commands
|
# List of main commands
|
||||||
opts="help version status servers templates autocomplete_list_servers autocomplete_list_services run"
|
opts="help version status servers templates autocomplete_list_servers autocomplete_list_services run install"
|
||||||
|
|
||||||
# If we're completing the first argument, show all commands
|
# If we're completing the first argument, show all commands
|
||||||
if [[ ${COMP_CWORD} -eq 1 ]] ; then
|
if [[ ${COMP_CWORD} -eq 1 ]] ; then
|
||||||
@ -37,23 +37,23 @@ _dropshell_completions() {
|
|||||||
COMPREPLY=( $(compgen -W "${servers[*]}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${servers[*]}" -- ${cur}) )
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
run)
|
run|install)
|
||||||
# First argument after run is server name
|
# First argument after run/install is server name
|
||||||
local servers=($(dropshell autocomplete_list_servers))
|
local servers=($(dropshell autocomplete_list_servers))
|
||||||
COMPREPLY=( $(compgen -W "${servers[*]}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${servers[*]}" -- ${cur}) )
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Handle completion for service names and commands after run
|
# Handle completion for service names and commands after run/install
|
||||||
if [[ ${COMP_CWORD} -ge 2 ]] && [[ "${COMP_WORDS[1]}" == "run" ]]; then
|
if [[ ${COMP_CWORD} -ge 2 ]] && [[ "${COMP_WORDS[1]}" == "run" || "${COMP_WORDS[1]}" == "install" ]]; then
|
||||||
if [[ ${COMP_CWORD} -eq 3 ]]; then
|
if [[ ${COMP_CWORD} -eq 3 ]]; then
|
||||||
# Second argument is service name
|
# Second argument is service name
|
||||||
local server_name="${COMP_WORDS[2]}"
|
local server_name="${COMP_WORDS[2]}"
|
||||||
local services=($(dropshell autocomplete_list_services "$server_name"))
|
local services=($(dropshell autocomplete_list_services "$server_name"))
|
||||||
COMPREPLY=( $(compgen -W "${services[*]}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${services[*]}" -- ${cur}) )
|
||||||
return 0
|
return 0
|
||||||
elif [[ ${COMP_CWORD} -eq 4 ]]; then
|
elif [[ ${COMP_CWORD} -eq 4 && "${COMP_WORDS[1]}" == "run" ]]; then
|
||||||
# Third argument is command name
|
# Third argument is command name (only for run command)
|
||||||
# For now, we'll just complete with common commands
|
# For now, we'll just complete with common commands
|
||||||
local common_commands="status start stop update backup"
|
local common_commands="status start stop update backup"
|
||||||
COMPREPLY=( $(compgen -W "${common_commands}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "${common_commands}" -- ${cur}) )
|
||||||
|
@ -31,7 +31,5 @@ void show_server_details(const std::string& server_name);
|
|||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
std::vector<ServerInfo> get_configured_servers();
|
std::vector<ServerInfo> get_configured_servers();
|
||||||
std::vector<std::string> autocomplete_list_servers();
|
|
||||||
std::vector<std::string> autocomplete_list_services(const std::string& server_name);
|
|
||||||
|
|
||||||
} // namespace dropshell
|
} // namespace dropshell
|
237
src/main.cpp
237
src/main.cpp
@ -1,128 +1,171 @@
|
|||||||
#include "dropshell.hpp"
|
#include "dropshell.hpp"
|
||||||
|
#include "server_service.hpp"
|
||||||
|
#include "autocomplete.hpp"
|
||||||
#include "init_user_directory.hpp"
|
#include "init_user_directory.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/program_options.hpp>
|
#include <string>
|
||||||
#include <boost/filesystem.hpp>
|
#include <vector>
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace dropshell {
|
||||||
namespace fs = boost::filesystem;
|
|
||||||
|
void print_help() {
|
||||||
|
std::cout << "Usage: dropshell [OPTIONS] COMMAND [ARGS]" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "A tool for managing server configurations" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "Commands:" << std::endl;
|
||||||
|
std::cout << " help Show this help message" << std::endl;
|
||||||
|
std::cout << " version Show version information" << std::endl;
|
||||||
|
std::cout << " init DIR Initialize the user directory for server configurations" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << " status Check system status" << std::endl;
|
||||||
|
std::cout << " servers List configured servers" << std::endl;
|
||||||
|
std::cout << " servers NAME Show details for specific server" << std::endl;
|
||||||
|
std::cout << " templates List available templates" << std::endl;
|
||||||
|
std::cout << " install SERVER SERVICE Install a service on a server" << std::endl;
|
||||||
|
std::cout << " run SERVER SERVICE COMMAND Run a command on a specific service" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "Examples:" << std::endl;
|
||||||
|
std::cout << " dropshell servers" << std::endl;
|
||||||
|
std::cout << " dropshell servers myserver" << std::endl;
|
||||||
|
std::cout << " dropshell init /path/to/directory" << std::endl;
|
||||||
|
std::cout << " dropshell templates" << std::endl;
|
||||||
|
std::cout << " dropshell install myserver myservice" << std::endl;
|
||||||
|
std::cout << " dropshell run myserver myservice status" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dropshell
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
try {
|
try {
|
||||||
// Define command line options
|
|
||||||
po::options_description desc("Usage: dropshell <command> [options]");
|
|
||||||
desc.add_options()
|
|
||||||
("help,h", "Show help message")
|
|
||||||
("version,V", "Show version information")
|
|
||||||
("command", po::value<std::string>(), "Command to execute")
|
|
||||||
("directory", po::value<std::string>(), "Directory path for init command")
|
|
||||||
("verbose,v", "Enable verbose output");
|
|
||||||
|
|
||||||
po::positional_options_description p;
|
|
||||||
p.add("command", 1);
|
|
||||||
p.add("directory", 1); // Add directory as a positional argument
|
|
||||||
|
|
||||||
po::variables_map vm;
|
|
||||||
po::store(po::command_line_parser(argc, argv)
|
|
||||||
.options(desc)
|
|
||||||
.positional(p)
|
|
||||||
.run(), vm);
|
|
||||||
po::notify(vm);
|
|
||||||
|
|
||||||
// Load configuration
|
// Load configuration
|
||||||
if (!dropshell::load_config()) {
|
if (!dropshell::load_config()) {
|
||||||
std::cerr << "Error: Failed to load configuration" << std::endl;
|
std::cerr << "Error: Failed to load configuration" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No arguments provided
|
||||||
|
if (argc < 2) {
|
||||||
|
dropshell::print_help();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle commands
|
// Handle commands
|
||||||
if (vm.count("help") || (vm.count("command") && vm["command"].as<std::string>() == "help")) {
|
std::string cmd = argv[1];
|
||||||
dropshell::print_help(desc);
|
|
||||||
|
if (cmd == "help" || cmd == "-h" || cmd == "--help") {
|
||||||
|
dropshell::print_help();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("version") || (vm.count("command") && vm["command"].as<std::string>() == "version")) {
|
if (cmd == "version" || cmd == "-V" || cmd == "--version") {
|
||||||
dropshell::print_version();
|
dropshell::print_version();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("command")) {
|
if (cmd == "status") {
|
||||||
std::string cmd = vm["command"].as<std::string>();
|
dropshell::check_status();
|
||||||
if (cmd == "status") {
|
return 0;
|
||||||
dropshell::check_status();
|
}
|
||||||
return 0;
|
|
||||||
} else if (cmd == "servers") {
|
if (cmd == "servers") {
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
// Show details for specific server
|
// Show details for specific server
|
||||||
dropshell::show_server_details(argv[2]);
|
dropshell::show_server_details(argv[2]);
|
||||||
} else {
|
|
||||||
// List all servers
|
|
||||||
dropshell::list_servers();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else if (cmd == "templates") {
|
|
||||||
dropshell::list_templates();
|
|
||||||
return 0;
|
|
||||||
} else if (cmd == "init") {
|
|
||||||
if (!vm.count("directory")) {
|
|
||||||
std::cerr << "Error: init command requires a directory argument" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
dropshell::init_user_directory(vm["directory"].as<std::string>());
|
|
||||||
return 0;
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
std::cerr << "Error: " << e.what() << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else if (cmd == "autocomplete_list_servers") {
|
|
||||||
auto servers = dropshell::autocomplete_list_servers();
|
|
||||||
for (const auto& server : servers) {
|
|
||||||
std::cout << server << std::endl;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else if (cmd == "autocomplete_list_services") {
|
|
||||||
if (argc < 3) {
|
|
||||||
std::cerr << "Error: autocomplete_list_services requires a server name" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
auto services = dropshell::autocomplete_list_services(argv[2]);
|
|
||||||
for (const auto& service : services) {
|
|
||||||
std::cout << service << std::endl;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else if (cmd == "run") {
|
|
||||||
if (argc < 5) {
|
|
||||||
std::cerr << "Error: run command requires server name, service name, and command" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
std::string server_name = argv[2];
|
|
||||||
std::string service_name = argv[3];
|
|
||||||
std::string command = argv[4];
|
|
||||||
|
|
||||||
dropshell::server_service service;
|
|
||||||
if (!service.init(server_name, service_name)) {
|
|
||||||
std::cerr << "Error: Failed to initialize service" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!service.run_command(command)) {
|
|
||||||
std::cerr << "Error: Failed to run command" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Error: Unknown command '" << cmd << "'" << std::endl;
|
// List all servers
|
||||||
dropshell::print_help(desc);
|
dropshell::list_servers();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == "templates") {
|
||||||
|
dropshell::list_templates();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == "init") {
|
||||||
|
if (argc < 3) {
|
||||||
|
std::cerr << "Error: init command requires a directory argument" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
dropshell::init_user_directory(argv[2]);
|
||||||
|
return 0;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "Error: " << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No command provided
|
if (cmd == "autocomplete_list_servers") {
|
||||||
std::cerr << "Error: No command provided" << std::endl;
|
auto servers = dropshell::autocomplete_list_servers();
|
||||||
dropshell::print_help(desc);
|
for (const auto& server : servers) {
|
||||||
|
std::cout << server << std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == "autocomplete_list_services") {
|
||||||
|
if (argc < 3) {
|
||||||
|
std::cerr << "Error: autocomplete_list_services requires a server name" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
auto services = dropshell::autocomplete_list_services(argv[2]);
|
||||||
|
for (const auto& service : services) {
|
||||||
|
std::cout << service << std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == "install") {
|
||||||
|
if (argc < 4) {
|
||||||
|
std::cerr << "Error: install command requires server name and service name" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string server_name = argv[2];
|
||||||
|
std::string service_name = argv[3];
|
||||||
|
|
||||||
|
dropshell::server_service service;
|
||||||
|
if (!service.init(server_name, service_name)) {
|
||||||
|
std::cerr << "Error: Failed to initialize service" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!service.install()) {
|
||||||
|
std::cerr << "Error: Failed to install service" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd == "run") {
|
||||||
|
if (argc < 5) {
|
||||||
|
std::cerr << "Error: run command requires server name, service name, and command" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string server_name = argv[2];
|
||||||
|
std::string service_name = argv[3];
|
||||||
|
std::string command = argv[4];
|
||||||
|
|
||||||
|
dropshell::server_service service;
|
||||||
|
if (!service.init(server_name, service_name)) {
|
||||||
|
std::cerr << "Error: Failed to initialize service" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!service.run_command(command)) {
|
||||||
|
std::cerr << "Error: Failed to run command" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown command
|
||||||
|
std::cerr << "Error: Unknown command '" << cmd << "'" << std::endl;
|
||||||
|
dropshell::print_help();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
|
@ -158,7 +158,7 @@ bool server_service::run_command(const std::string& command) {
|
|||||||
// Check if service directory exists
|
// Check if service directory exists
|
||||||
std::string check_dir_cmd = ssh_cmd.str() + "'test -d " + service_dir + "'";
|
std::string check_dir_cmd = ssh_cmd.str() + "'test -d " + service_dir + "'";
|
||||||
if (system(check_dir_cmd.c_str()) != 0) {
|
if (system(check_dir_cmd.c_str()) != 0) {
|
||||||
std::cerr << "Error: Service directory not found on server" << std::endl;
|
std::cerr << "Error: Service directory not found on server - has it been installed?" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user