implement basic command line parsing
This commit is contained in:
parent
1f4c020df9
commit
b73f25e835
4 changed files with 335 additions and 1 deletions
68
include/cli_util.hpp
Normal file
68
include/cli_util.hpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (c) 2023 Fabian Posch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CLI_UTIL_H__
|
||||
#define __CLI_UTIL_H__
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include "db_client.hpp"
|
||||
|
||||
#define POSTGRES_DEFAULT_PORT 5432
|
||||
|
||||
// environment variables used by the database module of the argument parser
|
||||
#define SERVER_ADDR_ENV "ACT_DEPLOY_SERVER_ADDR"
|
||||
#define SERVER_PORT_ENV "ACT_DEPLOY_SERVER_PORT"
|
||||
#define SERVER_USER_ENV "ACT_DEPLOY_SERVER_USER"
|
||||
#define SERVER_PWD_ENV "ACT_DEPLOY_SERVER_PWD"
|
||||
#define SERVER_DBASE_ENV "ACT_DEPLOY_SERVER_DBASE"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Parse database credentials from arguments or environment
|
||||
*
|
||||
* Parses the database options common between the different commands. No command line overrides were given,
|
||||
* the data is loaded from environment variables given externally through macros. These macros are:
|
||||
*
|
||||
* - SERVER_ADDR_ENV: Environment variable containing the address of the Postgresql database server
|
||||
* - SERVER_PORT_ENV: Variable containing the port of the Postgresql database server
|
||||
* - SERVER_USER_ENV: Variable containing the database user
|
||||
* - SERVER_PWD_ENV: Variable containing the database password
|
||||
* - SERVER_DBASE_ENV: Variable containing the database name
|
||||
*
|
||||
* @param arguments Argument list given to the program
|
||||
* @return db_credentials_t Structure containing the database credentials
|
||||
*
|
||||
* @throw std::invalid_argument Thrown if the server name was set by neither the environment nor an override argument
|
||||
* @throw std::invalid_argument Thrown if the server port was set by neither the environment nor an override argument
|
||||
* @throw std::invalid_argument Thrown if the given port is invalid
|
||||
* @throw std::invalid_argument Thrown if the database user was set by neither the environment nor an override argument
|
||||
* @throw std::invalid_argument Thrown if the database password was set by neither the environment nor an override argument
|
||||
* @throw std::invalid_argument Thrown if the database name was set by neither the environment nor an override argument
|
||||
*/
|
||||
//db::db_credentials_t get_db_cred (arg_list& arguments);
|
||||
|
||||
void get_db_cred_env (db::db_credentials_t& db_cred);
|
||||
|
||||
#endif
|
||||
37
include/main.hpp
Normal file
37
include/main.hpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (c) 2023 Fabian Posch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __ACTSIM_CLUSTER_AGENT__
|
||||
#define __ACTSIM_CLUSTER_AGENT__
|
||||
|
||||
// program version is defined by external variable
|
||||
#ifndef PROG_VERSION
|
||||
#define PROG_VERSION "unknown"
|
||||
#endif
|
||||
#define VERSION PROG_VERSION
|
||||
|
||||
void print_usage();
|
||||
int main(int argc, char** argv);
|
||||
|
||||
#endif
|
||||
99
src/cli_util.cpp
Normal file
99
src/cli_util.cpp
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
|
||||
/*************************************************************************
|
||||
*
|
||||
* Copyright (c) 2023 Fabian Posch
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include "db_client.hpp"
|
||||
#include "util.h"
|
||||
#include "cli_util.hpp"
|
||||
|
||||
|
||||
void get_db_cred_env (db::db_credentials_t& db_cred) {
|
||||
|
||||
// check if a server was given
|
||||
if (!db_cred.server_override) {
|
||||
if (std::getenv(SERVER_ADDR_ENV) == nullptr) {
|
||||
throw new std::invalid_argument("No database server set in environment variable " SERVER_ADDR_ENV);
|
||||
}
|
||||
|
||||
db_cred.server = std::getenv(SERVER_ADDR_ENV);
|
||||
db_cred.server_override = false;
|
||||
}
|
||||
|
||||
// check if a port was given
|
||||
if (!db_cred.port_override) {
|
||||
// if no env variable is set, we use postgresql's default port
|
||||
if (std::getenv(SERVER_PORT_ENV) == nullptr) {
|
||||
std::cerr << "Warning: No port given in environment variable " SERVER_PORT_ENV ". Using default Postgresql port." << std::endl;
|
||||
db_cred.port = POSTGRES_DEFAULT_PORT;
|
||||
db_cred.port_override = false;
|
||||
|
||||
// otherwise we try to parse it from the environment variable
|
||||
} else {
|
||||
|
||||
std::string port_st = std::getenv(SERVER_PORT_ENV);
|
||||
|
||||
DEBUG_PRINT("Parsing port " + port_st);
|
||||
|
||||
try {
|
||||
db_cred.port = std::atoi(port_st.c_str());
|
||||
} catch (std::invalid_argument& e) {
|
||||
throw new std::invalid_argument("Could not parse port from environment variable " SERVER_PORT_ENV);
|
||||
}
|
||||
|
||||
// make sure the port is valid
|
||||
if (db_cred.port <= 0) {
|
||||
throw new std::invalid_argument("Port " SERVER_PORT_ENV " given in environment variable is not a valid port.");
|
||||
}
|
||||
|
||||
db_cred.port_override = false;
|
||||
}
|
||||
}
|
||||
|
||||
// check if a user was given
|
||||
if (!db_cred.uname_override) {
|
||||
if (std::getenv(SERVER_USER_ENV) == nullptr) {
|
||||
throw new std::invalid_argument("No database user set in environment variable " SERVER_USER_ENV);
|
||||
}
|
||||
db_cred.uname = std::getenv(SERVER_USER_ENV);
|
||||
db_cred.uname_override = false;
|
||||
}
|
||||
|
||||
// check if a password was given
|
||||
if (!db_cred.pwd_override) {
|
||||
if (std::getenv(SERVER_PWD_ENV) == nullptr) {
|
||||
throw new std::invalid_argument("No database password set in environment variable " SERVER_PWD_ENV);
|
||||
}
|
||||
db_cred.pwd = std::getenv(SERVER_PWD_ENV);
|
||||
db_cred.pwd_override = false;
|
||||
}
|
||||
|
||||
// check if a database was given
|
||||
if (!db_cred.dbase_override) {
|
||||
if (std::getenv(SERVER_DBASE_ENV) == nullptr) {
|
||||
throw new std::invalid_argument("No database set in environment variable " SERVER_DBASE_ENV);
|
||||
}
|
||||
db_cred.dbase = std::getenv(SERVER_DBASE_ENV);
|
||||
db_cred.dbase_override = false;
|
||||
}
|
||||
}
|
||||
132
src/main.cpp
132
src/main.cpp
|
|
@ -23,9 +23,139 @@
|
|||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <getopt.h>
|
||||
#include <thread>
|
||||
#include "cli_util.hpp"
|
||||
#include "db_types.hpp"
|
||||
#include "util.h"
|
||||
#include "main.hpp"
|
||||
|
||||
void print_usage() {
|
||||
std::cout << "acstim-cluster-agent v" << VERSION << std::endl;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"dbase-server", required_argument, 0, 0},
|
||||
{"dbase-port", required_argument, 0, 0},
|
||||
{"dbase-user", required_argument, 0, 0},
|
||||
{"dbase-pwd", required_argument, 0, 0},
|
||||
{"dbase-dbase", required_argument, 0, 0},
|
||||
{"jobs", optional_argument, 0, 'j'},
|
||||
{0, 0, 0, 0} // null termination
|
||||
};
|
||||
|
||||
int c;
|
||||
int option_index = 0;
|
||||
|
||||
// options to be set
|
||||
int jobs = 1;
|
||||
db::db_credentials_t db_cred;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "j::", long_options, &option_index)) != -1) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
|
||||
DEBUG_PRINT("Long argument found.");
|
||||
|
||||
// switch through the options struct index
|
||||
switch (option_index) {
|
||||
case 0:
|
||||
DEBUG_PRINT("Database server customized.");
|
||||
db_cred.server = optarg;
|
||||
db_cred.server_override = true;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DEBUG_PRINT("Database port customized.");
|
||||
try {
|
||||
db_cred.port = std::atoi(optarg);
|
||||
} catch (std::invalid_argument& e) {
|
||||
std::cerr << "Error: Database port parameter must be a number!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (db_cred.port < 1) {
|
||||
std::cerr << "Error: Database port given is invalid. Aborting." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
db_cred.port_override = true;
|
||||
|
||||
case 2:
|
||||
DEBUG_PRINT("Database user customized.");
|
||||
db_cred.uname = optarg;
|
||||
db_cred.uname_override = true;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
DEBUG_PRINT("Database password customized.");
|
||||
db_cred.pwd = optarg;
|
||||
db_cred.pwd_override = true;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
DEBUG_PRINT("Database name customized.");
|
||||
db_cred.dbase = optarg;
|
||||
db_cred.dbase_override = true;
|
||||
|
||||
default:
|
||||
DEBUG_PRINT("Unexpected option index!");
|
||||
}
|
||||
|
||||
std::cout << "Option " << long_options[option_index].name;
|
||||
if (optarg) {
|
||||
std::cout << " with arg " << optarg;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
|
||||
DEBUG_PRINT("Number of worker threads customized.");
|
||||
|
||||
if (optarg) {
|
||||
|
||||
try {
|
||||
jobs = std::atoi(optarg);
|
||||
} catch (std::invalid_argument& e) {
|
||||
std::cerr << "Error: Worker threads parameter must be a number!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (jobs < 1) {
|
||||
std::cerr << "Error: Number of worker threads smaller than 1. Aborting." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
const auto proc_count = std::thread::hardware_concurrency();
|
||||
if (proc_count == 0) {
|
||||
std::cerr << "Error: Could not detect number of hardware threads. Defaulting to 1." << std::endl;
|
||||
} else {
|
||||
jobs = proc_count;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Agent set to using " << jobs << " worker threads." << std::endl;
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
get_db_cred_env(db_cred);
|
||||
} catch (std::invalid_argument& e) {
|
||||
std::cerr << "Error: Could not load database configuration from environment. " << e.what() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::cout << "Hello world!" << std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue