pre-release

This commit is contained in:
Chris Punches
2021-04-04 21:21:05 -04:00
parent 4b3a9170bf
commit 89f734de84
34 changed files with 553 additions and 348 deletions

View File

@@ -10,7 +10,7 @@ Logger::Logger( int LOG_LEVEL, std::string mask )
this->mask = mask;
setlogmask( LOG_UPTO( this->LOG_LEVEL ) );
openlog( this->mask.c_str(), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_PERROR | LOG_LOCAL1 );
openlog( "rex", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_PERROR | LOG_LOCAL1 );
}
@@ -33,19 +33,10 @@ void Logger::log( int LOG_LEVEL, std::string msg )
if ( LOG_LEVEL == E_FATAL | LOG_LEVEL == E_WARN )
{
std::cerr << "[" << this->get_8601() << "] [" << ERR << "] " << "[" << this->mask << "] " << msg.c_str() << std::endl;
std::cerr << "[" << get_8601() << "] [" << ERR << "] " << "[" << this->mask << "] " << msg.c_str() << std::endl;
} else {
std::cout << "[" << this->get_8601() << "] [" << ERR << "] " << "[" << this->mask << "] " << msg.c_str() << std::endl;
std::cout << "[" << get_8601() << "] [" << ERR << "] " << "[" << this->mask << "] " << msg.c_str() << std::endl;
}
}
}
std::string Logger::get_8601()
{
auto now = std::chrono::system_clock::now();
auto itt = std::chrono::system_clock::to_time_t(now);
std::ostringstream ss;
// ss << std::put_time(gmtime(&itt), "%FT%TZ");
ss << std::put_time(localtime(&itt), "%Y-%m-%d_%H:%M:%S");
return ss.str();
}

View File

@@ -2,15 +2,15 @@
// Created by bagira on 6/13/20.
//
#ifndef EXAMPLAR_LOGGER_H
#define EXAMPLAR_LOGGER_H
#ifndef REX_LOGGER_H
#define REX_LOGGER_H
#include <syslog.h>
#include <string>
#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>
#include "../loaders/misc/helpers.h"
enum L_LVL {
E_FATAL,
@@ -27,9 +27,8 @@ public:
private:
int LOG_LEVEL;
std::string mask;
std::string get_8601();
};
#endif //EXAMPLAR_LOGGER_H
#endif //REX_LOGGER_H

View File

@@ -1,4 +1,6 @@
#include "Sproc.h"
#include "../loaders/misc/helpers.h"
#include "sys/stat.h"
#define PARENT default
@@ -141,7 +143,7 @@ int set_identity_context( std::string task_name, std::string user_name, std::str
///
/// \param input - The commandline input to execute.
/// \return - The return code of the execution of input in the calling shell.
int Sproc::execute(std::string shell, std::string environment_file, std::string user_name, std::string group_name, std::string command, int LOG_LEVEL, std::string task_name )
int Sproc::execute(std::string shell, std::string environment_file, std::string user_name, std::string group_name, std::string command, int LOG_LEVEL, std::string task_name, bool log_to_file, std::string logs_dir )
{
// the logger
Logger slog = Logger( LOG_LEVEL, "_sproc" );
@@ -164,10 +166,25 @@ int Sproc::execute(std::string shell, std::string environment_file, std::string
// potentially corrupting user interaction with TUIs in the processes. This should give us our log and our output
// in as hands off a way as possible with as few assumptions as possible, while still doing this in a somewhat C++-y
// way.
if (! is_dir( logs_dir ) ) {
int check = mkdir( logs_dir.c_str(), 0777 );
if (! check ) {
slog.log( E_FATAL, "Sprocket couldn't create the logs parent directory." );
}
}
std::string timestamp = get_8601();
std::string contained_dir = logs_dir + "/" + task_name;
if (! is_dir( contained_dir ) ) {
int check = mkdir( contained_dir.c_str(), 0777 );
if (! check ) {
slog.log( E_FATAL, "Sprocket couldn't create the instance log directory.");
}
}
// set up the "Tee" with the parent
std::string child_stdout_log_path = "./stdout.log";
std::string child_stderr_log_path = "./stderr.log";
std::string child_stdout_log_path = contained_dir + "/" + timestamp + ".stdout.log";
std::string child_stderr_log_path = contained_dir + "/" + timestamp + ".stderr.log";
std::ofstream stdout_log;
std::ofstream stderr_log;
@@ -316,9 +333,13 @@ int Sproc::execute(std::string shell, std::string environment_file, std::string
set_stdout_break = true;
break;
default:
tee_out.write( stdout_buf, stdout_count );
tee_out.flush();
if ( log_to_file ) {
tee_out.write( stdout_buf, stdout_count );
tee_out.flush();
} else {
std::cout.write( stdout_buf, stdout_count );
std::cout.flush();
}
// clear the buffer to prevent artifacts from previous loop
memset( &stdout_buf[0], 0, sizeof( stdout_buf ) -1 );
}

View File

@@ -17,8 +17,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FTESTS_SPROC_H
#define FTESTS_SPROC_H
#ifndef REX_SPROCKET_H
#define REX_SPROCKET_H
#include "../Logger/Logger.h"
#include <iostream>
@@ -61,7 +61,9 @@ class Sproc {
std::string group_name,
std::string command,
int LOG_LEVEL,
std::string task_name
std::string task_name,
bool log_to_file,
std::string logs_dir
);
};
@@ -88,4 +90,4 @@ class teestream : public std::ostream
teebuf tbuf;
};
#endif //FTESTS_SPROC_H
#endif //REX_SPROCKET_H

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -66,7 +66,7 @@ protected:
/// TODO Expand to detect when a directory path is supplied for units_path or plan_path and import all Tasks and Units.
///
/// \param filename - The filename to load the configuration from.
Conf::Conf( std::string filename, int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slog( LOG_LEVEL, "e_conf" )
Conf::Conf(std::string filename, int LOG_LEVEL ): JSON_Loader(LOG_LEVEL ), slog(LOG_LEVEL, "_conf_" )
{
this->LOG_LEVEL = LOG_LEVEL;
@@ -91,18 +91,18 @@ Conf::Conf( std::string filename, int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slo
throw ConfigLoadException("config_version string expected was " + std::string(VERSION_STRING) + " in: " + filename);
}
// find the path to the plan file
if ( this->get_serialized(this->plan_path, "plan_path" ) != 0 )
{
throw ConfigLoadException("plan_path string is not set in the config file supplied:" + filename);
}
// find the path to the unit definitions file
if (this->get_serialized(this->units_path, "units_path" ) != 0 )
{
throw ConfigLoadException("units_path string is not set in the config file supplied: " + filename);
}
// find the path to logs directory
if (this->get_serialized(this->logs_path, "logs_path" ) != 0 )
{
throw ConfigLoadException("logs_path string is not set in the config file supplied: " + filename);
}
if ( this->get_serialized(this->override_execution_context, "execution_context_override" ) != 0 )
{
throw ConfigLoadException("execution_context_override boolean is not set in the config file supplied: " + filename);
@@ -114,11 +114,15 @@ Conf::Conf( std::string filename, int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slo
{
throw ConfigLoadException("execution_context string is not set in the config file supplied: " + filename);
} else {
this->execution_context_literal = this->execution_context.asString();
if ( is_dir( this->execution_context.asString() ) ) {
this->execution_context_literal = this->execution_context.asString();
} else {
throw ConfigLoadException( "The execution context supplied is an invalid directory.");
}
}
};
/// Conf::has_context_override - Specifies whether or not the override context function is enabled in the conf file.
/// Conf::has_context_override - Specifies whether or not the override context function is enabled in the Conf file.
bool Conf::has_context_override() {
return this->override_execution_context.asBool();
}
@@ -128,14 +132,14 @@ std::string Conf::get_execution_context() {
return this->execution_context_literal;
}
/// Conf::get_plan_path - Retrieves the path to the Plan definition file from the application configuration file.
std::string Conf::get_plan_path() { return this->plan_path.asString(); }
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
std::string Conf::get_units_path() { return this->units_path.asString(); }
/// Conf::get_units_path - Retrieves the path to the Unit definition file from the application configuration file.
std::string Conf::get_logs_path() { return this->logs_path.asString(); }
/// Conf::set_execution_context- Sets the execution context.
void Conf::set_execution_context( std::string execution_context )
void Conf::set_execution_context(std::string execution_context )
{
this->execution_context_literal = execution_context;
}

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -18,8 +18,8 @@
*/
#ifndef FTESTS_CONF_H
#define FTESTS_CONF_H
#ifndef REX_CONF_H
#define REX_CONF_H
#include "../low_level/JSON_Loader.h"
#include <exception>
#include "../../Logger/Logger.h"
@@ -27,7 +27,7 @@
#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)
# define IMPL_CONFIG_VERSION 3
# define IMPL_CONFIG_VERSION 4
# define VERSION_STRING STRINGIZE(IMPL_CONFIG_VERSION)
class Conf: public JSON_Loader
@@ -37,23 +37,24 @@ private:
Json::Value units_path;
Json::Value execution_context;
Json::Value config_version;
Json::Value logs_path;
// flag to indicate if execution context should be overriden in config file
// if set to true Examplar should use whats in the config file for current working directory
// if set to false, Examplar should use the current working directory at time of execution
// if set to true rex should use whats in the config file for current working directory
// if set to false, rex should use the current working directory at time of execution
Json::Value override_execution_context;
bool override_context;
std::string execution_context_literal;
public:
Conf( std::string filename, int LOG_LEVEL );
Conf(std::string filename, int LOG_LEVEL );
bool has_context_override();
std::string get_plan_path();
std::string get_units_path();
std::string get_execution_context();
std::string get_logs_path();
void set_execution_context( std::string );
@@ -63,4 +64,4 @@ private:
};
#endif //FTESTS_CONF_H
#endif //REX_CONF_H

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -120,7 +120,7 @@ protected:
/// Plan::Plan() - Constructor for Plan class. A Plan is a managed container for a Task vector. These tasks reference
/// Units that are defined in the Units files (Suite). If Units are definitions, Tasks are selections of those
/// definitions to execute, and if Units together form a Suite, Tasks together form a Plan.
Plan::Plan( Conf * configuration, int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slog( LOG_LEVEL, "e_plan" )
Plan::Plan(Conf * configuration, int LOG_LEVEL ): JSON_Loader(LOG_LEVEL ), slog(LOG_LEVEL, "_plan_" )
{
this->configuration = configuration;
this->LOG_LEVEL = LOG_LEVEL;

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -18,8 +18,8 @@
*/
#ifndef FTESTS_PLAN_H
#define FTESTS_PLAN_H
#ifndef REX_PLAN_H
#define REX_PLAN_H
#include <string>
#include "../../json/json.h"
@@ -36,7 +36,7 @@ class Plan: public JSON_Loader
Conf * configuration;
public:
Plan( Conf * configuration, int LOG_LEVEL );
Plan(Conf * configuration, int LOG_LEVEL );
// append this->tasks from JSON file
void load_plan_file( std::string filename );
@@ -63,4 +63,4 @@ private:
Logger slog;
};
#endif //FTESTS_PLAN_H
#endif //REX_PLAN_H

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -18,8 +18,8 @@
*/
#ifndef FTESTS_UNITS_H
#define FTESTS_UNITS_H
#ifndef REX_UNITS_H
#define REX_UNITS_H
#include <vector>
#include "../../json/json.h"
@@ -54,4 +54,4 @@ private:
Logger slog;
};
#endif //FTESTS_UNITS_H
#endif //REX_UNITS_H

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -80,7 +80,7 @@ protected:
/// Task::Task() - Constructor for the Task class. The Task is the building block of a Plan indicating of which Unit to
/// execute, and its dependencies on other units to have already been completed successfully.
Task::Task( int LOG_LEVEL ):
slog( LOG_LEVEL, "e_task" ),
slog( LOG_LEVEL, "_task_" ),
definition( LOG_LEVEL )
{
// it hasn't executed yet.
@@ -165,9 +165,9 @@ bool Task::has_definition()
/// Task::execute - execute a task's unit definition.
/// See the design document for what flow control needs to look like here.
/// \param verbose - Verbosity level - not implemented yet.
void Task::execute( Conf * configuration )
void Task::execute(Conf * configuration )
{
// DUFFING - If Examplar is broken it's probably going to be in this block.
// DUFFING - If rex is broken it's probably going to be in this block.
// Somebody come clean this up, eh?
// PREWORK
@@ -219,7 +219,9 @@ void Task::execute( Conf * configuration )
this->definition.get_group(),
target_command,
this->LOG_LEVEL,
task_name
task_name,
this->definition.get_stdout_log_flag(),
configuration->get_logs_path()
);
// **********************************************
@@ -286,7 +288,9 @@ void Task::execute( Conf * configuration )
this->definition.get_group(),
rectifier_command,
this->LOG_LEVEL,
task_name
task_name,
this->definition.get_stdout_log_flag(),
configuration->get_logs_path()
);
// **********************************************
@@ -335,7 +339,9 @@ void Task::execute( Conf * configuration )
this->definition.get_group(),
target_command,
this->LOG_LEVEL,
task_name
task_name,
this->definition.get_stdout_log_flag(),
configuration->get_logs_path()
);
// **********************************************

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -18,8 +18,8 @@
*/
#ifndef FTESTS_TASK_H
#define FTESTS_TASK_H
#ifndef REX_TASK_H
#define REX_TASK_H
#include <string>
#include <unistd.h>
#include "../../json/json.h"
@@ -67,7 +67,7 @@ class Task
std::string get_name();
// execute this task's definition
void execute( Conf * configuration );
void execute(Conf * configuration );
void mark_complete();
@@ -79,4 +79,4 @@ private:
int LOG_LEVEL;
};
#endif //FTESTS_TASK_H
#endif //REX_TASK_H

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -80,7 +80,7 @@ public:
/// required, which is used as a flag to halt or continue if rectifier does not heal the system in such a way that
/// target can run successfully.
/// rectify, which is used as a flag to determine in the rectifier runs.
Unit::Unit( int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slog( LOG_LEVEL, "e_unit" )
Unit::Unit( int LOG_LEVEL ): JSON_Loader( LOG_LEVEL ), slog( LOG_LEVEL, "_unit_" )
{
this->LOG_LEVEL;
}
@@ -117,6 +117,10 @@ int Unit::load_root(Json::Value loader_root)
{ this->required = loader_root.get("required", errmsg).asBool(); } else
throw UnitException("No required attribute specified when loading a unit.");
if ( loader_root.isMember("log") )
{ this->stdout_log_flag = loader_root.get("log", errmsg).asBool(); } else
throw UnitException("No log attribute specified when loading a unit.");
if ( loader_root.isMember("rectify") )
{ this->rectify = loader_root.get("rectify", errmsg).asBool(); } else
throw UnitException("No rectify boolean attribute specified when loading a unit.");
@@ -286,3 +290,12 @@ std::string Unit::get_env_vars_file()
return this->env_vars_file;
}
/// Unit::get_stdout_log_flag() - retrieves the file path to use for the unit environment file. This is a file that is
/// sourced by the chosen shell to populate any environment variables.
/// \return the string value of the shell path.
bool Unit::get_stdout_log_flag()
{
if ( ! this->populated ) { throw UnitException("Attempted to access an unpopulated unit."); }
return this->stdout_log_flag;
}

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -19,12 +19,12 @@
*/
/* Unit.h
* Unit is a type that represents a safely deserialized JSON object which defines what actions are taken as Examplar
* Unit is a type that represents a safely deserialized JSON object which defines what actions are taken as rex
* iterates through it's Tasks in it's given Plan. They only define the behaviour on execution, while the tasks define
* which Units are executed and in what order (and which Units a given Task depends on.
*/
#ifndef FTESTS_UNIT_H
#define FTESTS_UNIT_H
#ifndef FTEST_UNIT_H
#define FTEST_UNIT_H
#include <string>
#include "../../json/json.h"
#include "../low_level/JSON_Loader.h"
@@ -59,6 +59,9 @@ private:
// if rectifier exits on non-zero return code, it should be trigger the behaviour indicated by required
bool rectify;
//indicator of whether stdout should log to file. used mainly to handle glitchy TUI systems when logs are being tailed.
bool stdout_log_flag;
// user to run process as.
// not intended for protected accounts, handle your own security
std::string user;
@@ -91,6 +94,7 @@ public:
bool get_active();
bool get_required();
bool get_rectify();
bool get_stdout_log_flag();
std::string get_user();
std::string get_group();
std::string get_shell();
@@ -100,4 +104,4 @@ private:
Logger slog;
};
#endif //FTESTS_UNIT_H
#endif //FTEST_UNIT_H

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -17,12 +17,12 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FTESTS_LOADERS_H
#define FTESTS_LOADERS_H
#ifndef REX_LOADERS_H
#define REX_LOADERS_H
#include "../low_level/JSON_Loader.h"
#include "Suite.h"
#include "Plan.h"
#include "Conf.h"
#endif //FTESTS_LOADERS_H
#endif //REX_LOADERS_H

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -38,7 +38,7 @@ class JSON_Loader_InvalidJSON: public std::runtime_error { public:
/// JSON_Loader::JSON_Loader - Constructor for JSON_Loader base class. Simply inits to an unpopulated state.
///
/// The JSON_Loader type is a base type. It is meant to provide the functionalities shared between Suite and Plan.
JSON_Loader::JSON_Loader( int LOG_LEVEL ): slog( LOG_LEVEL, "e_json" )
JSON_Loader::JSON_Loader( int LOG_LEVEL ): slog( LOG_LEVEL, "_json_" )
{
this->populated = false;
this->LOG_LEVEL = LOG_LEVEL;
@@ -91,7 +91,7 @@ void JSON_Loader::load_json_file( std::string filename )
// first, check if the file exists
if (! exists( filename ) )
{
this->slog.log( E_FATAL, "File '" + filename + "' does not exist." );
this->slog.log( E_DEBUG, "File '" + filename + "' does not exist." );
throw JSON_Loader_FileNotFound();
}

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -17,8 +17,8 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FTESTS_JLOADER_H
#define FTESTS_JLOADER_H
#ifndef REX_JLOADER_H
#define REX_JLOADER_H
#include "../../json/json.h"
#include <iostream>
#include <fstream>
@@ -55,4 +55,4 @@ private:
Logger slog;
int LOG_LEVEL;
};
#endif //FTESTS_JLOADER_H
#endif //REX_JLOADER_H

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -44,4 +44,14 @@ bool is_dir( std::string path )
struct stat buf;
stat( path.c_str(), &buf );
return S_ISDIR(buf.st_mode);
}
std::string get_8601()
{
auto now = std::chrono::system_clock::now();
auto itt = std::chrono::system_clock::to_time_t(now);
std::ostringstream ss;
// ss << std::put_time(gmtime(&itt), "%FT%TZ");
ss << std::put_time(localtime(&itt), "%Y-%m-%d_%H:%M:%S");
return ss.str();
}

View File

@@ -1,5 +1,5 @@
/*
Examplar - An automation and testing framework.
rex - An automation and testing framework.
© SURRO INDUSTRIES and Chris Punches, 2017.
@@ -18,13 +18,18 @@
*/
#ifndef FTESTS_HELPERS_H
#define FTESTS_HELPERS_H
#ifndef REX_HELPERS_H
#define REX_HELPERS_H
#include <string>
#include <sys/stat.h>
#include <sys/param.h>
#include <unistd.h>
#include <chrono>
#include <sstream>
#include <syslog.h>
#include <iostream>
#include <iomanip>
#include <sstream>
bool exists (const std::string& name);
@@ -32,4 +37,7 @@ std::string get_working_path();
bool is_file( std::string );
bool is_dir( std::string );
#endif //FTESTS_HELPERS_H
std::string get_8601();
#endif //REX_HELPERS_JH