Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b439959413 | |||
|
|
d0fbd30f31 | ||
|
|
004addd2b4 | ||
|
|
79bc82e365 | ||
|
|
c129f72b91 |
@@ -1,5 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/bash
|
||||||
echo "This is an independent test. It does not depend on other tests."
|
#
|
||||||
echo "Environment file check: TEST_VAR from environment file is set to: $TEST_VAR"
|
echo test from script
|
||||||
|
/usr/bin/dialog --title "This should be one argument" --inputbox "Enter your name:" 0 0
|
||||||
|
|
||||||
exit $?
|
|
||||||
|
|
||||||
|
env
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ set -a
|
|||||||
|
|
||||||
echo "variables file says hello and set a variable named TEST_VAR"
|
echo "variables file says hello and set a variable named TEST_VAR"
|
||||||
TEST_VAR="999"
|
TEST_VAR="999"
|
||||||
|
TERM=xterm
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
lcpex: setgid failed: Operation not permitted
|
|
||||||
lcpex: Aborting: Setting GID failed: bagira/bagira
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/usr/bin/bash: line 1: /home/phanes/development/internal/rex-rewrite/sample/environments/rex.variables: Permission denied
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/usr/bin/bash: line 1: /home/phanes/development/internal/rex-rewrite/sample/environments/rex.variables: Permission denied
|
|
||||||
0
sample/plans/atomic.plan
Normal file → Executable file
0
sample/plans/atomic.plan
Normal file → Executable file
0
sample/plans/test.plan
Normal file → Executable file
0
sample/plans/test.plan
Normal file → Executable file
2
sample/rex.config
Normal file → Executable file
2
sample/rex.config
Normal file → Executable file
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"project_root": "/home/phanes/development/internal/rex-rewrite/sample",
|
"project_root": "/tmp/sample",
|
||||||
"units_path": "units/",
|
"units_path": "units/",
|
||||||
"logs_path": "logs/",
|
"logs_path": "logs/",
|
||||||
"shells_path": "shells/shells.definitions",
|
"shells_path": "shells/shells.definitions",
|
||||||
|
|||||||
0
sample/shells/shells.definitions
Normal file → Executable file
0
sample/shells/shells.definitions
Normal file → Executable file
Binary file not shown.
0
sample/units/new.units
Normal file → Executable file
0
sample/units/new.units
Normal file → Executable file
@@ -134,6 +134,12 @@ void Conf::set_object_b(std::string keyname, bool & object_member, std::string f
|
|||||||
this->slog.log_task( E_DEBUG, "SET_PROPERTY", "'" + keyname + "' " + std::to_string(object_member));
|
this->slog.log_task( E_DEBUG, "SET_PROPERTY", "'" + keyname + "' " + std::to_string(object_member));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeTrailingSlash(std::string &str) {
|
||||||
|
if (!str.empty() && str.back() == '/') {
|
||||||
|
str.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prepend the project root to a relative path
|
* @brief Prepend the project root to a relative path
|
||||||
*
|
*
|
||||||
@@ -147,6 +153,7 @@ void Conf::set_object_b(std::string keyname, bool & object_member, std::string f
|
|||||||
*/
|
*/
|
||||||
std::string Conf::prepend_project_root( std::string relative_path)
|
std::string Conf::prepend_project_root( std::string relative_path)
|
||||||
{
|
{
|
||||||
|
removeTrailingSlash(relative_path);
|
||||||
return this->project_root + "/" + relative_path;
|
return this->project_root + "/" + relative_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +238,7 @@ void Conf::load_shells() {
|
|||||||
{
|
{
|
||||||
tmp_S.load_root( jbuff[index] );
|
tmp_S.load_root( jbuff[index] );
|
||||||
this->shells.push_back( tmp_S );
|
this->shells.push_back( tmp_S );
|
||||||
this->slog.log_task( E_DEBUG, "SHELLS", "Loaded shell: '" + tmp_S.name + "'" );
|
this->slog.log_task( E_DEBUG, "SHELLS", "Loaded shell: '" + tmp_S.name + "' (" + tmp_S.path + ")" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,6 +266,7 @@ Shell Conf::get_shell_by_name( std::string name ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Conf
|
* @class Conf
|
||||||
* @brief Loads the configuration for the application
|
* @brief Loads the configuration for the application
|
||||||
@@ -300,10 +308,12 @@ Conf::Conf(std::string filename, int LOG_LEVEL ): JSON_Loader(LOG_LEVEL ), slog(
|
|||||||
set_object_s( "project_root", this->project_root, filename );
|
set_object_s( "project_root", this->project_root, filename );
|
||||||
// convert to an absolute path after all the interpolation is done.
|
// convert to an absolute path after all the interpolation is done.
|
||||||
this->project_root = get_absolute_path( this->project_root );
|
this->project_root = get_absolute_path( this->project_root );
|
||||||
|
set_object_s( "logs_path", this->logs_path, filename );
|
||||||
|
this->logs_path = get_absolute_path( this->logs_path );
|
||||||
|
|
||||||
|
|
||||||
// all other paths are relative to project_root
|
// all other paths are relative to project_root
|
||||||
set_object_s_derivedpath( "units_path", this->units_path, filename );
|
set_object_s_derivedpath( "units_path", this->units_path, filename );
|
||||||
set_object_s_derivedpath( "logs_path", this->logs_path, filename );
|
|
||||||
set_object_s_derivedpath( "shells_path", this->shell_definitions_path, filename );
|
set_object_s_derivedpath( "shells_path", this->shell_definitions_path, filename );
|
||||||
|
|
||||||
// ensure these paths exists, with exception to the logs_path, which will be created at runtime
|
// ensure these paths exists, with exception to the logs_path, which will be created at runtime
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ std::string prefix_generator(
|
|||||||
prefix = shell_path;
|
prefix = shell_path;
|
||||||
|
|
||||||
// if the shell takes an argument to execute a command, add it enclosed in quotes
|
// if the shell takes an argument to execute a command, add it enclosed in quotes
|
||||||
if (shell_execution_arg != "") {
|
if ( shell_execution_arg != "" )
|
||||||
|
{
|
||||||
// add the execution arg
|
// add the execution arg
|
||||||
prefix += " " + shell_execution_arg + " ";
|
prefix += " " + shell_execution_arg + " ";
|
||||||
} else {
|
} else {
|
||||||
@@ -35,15 +36,15 @@ std::string prefix_generator(
|
|||||||
// it's not a shell command, so we can just execute it directly
|
// it's not a shell command, so we can just execute it directly
|
||||||
prefix = command;
|
prefix = command;
|
||||||
}
|
}
|
||||||
std::cout << "prefix: " << prefix << std::endl;
|
std::cout << "LAUNCHER: " << prefix << std::endl;
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int lcpex(
|
int lcpex(
|
||||||
std::string command,
|
std::string command,
|
||||||
std::string stdout_log_file,
|
FILE * stdout_log_fh,
|
||||||
std::string stderr_log_file,
|
FILE * stderr_log_fh,
|
||||||
bool context_override,
|
bool context_override,
|
||||||
std::string context_user,
|
std::string context_user,
|
||||||
std::string context_group,
|
std::string context_group,
|
||||||
@@ -71,11 +72,11 @@ int lcpex(
|
|||||||
// if we are forcing a pty, then we will use the vpty library
|
// if we are forcing a pty, then we will use the vpty library
|
||||||
if( force_pty )
|
if( force_pty )
|
||||||
{
|
{
|
||||||
return exec_pty( command, stdout_log_file, stderr_log_file, context_override, context_user, context_group, supply_environment );
|
return exec_pty( command, stdout_log_fh, stderr_log_fh, context_override, context_user, context_group, supply_environment );
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, we will use the execute function
|
// otherwise, we will use the execute function
|
||||||
return execute( command, stdout_log_file, stderr_log_file, context_override, context_user, context_group, supply_environment );
|
return execute( command, stdout_log_fh, stderr_log_fh, context_override, context_user, context_group, supply_environment );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,23 +131,23 @@ void run_child_process(bool context_override, const char* context_user, const ch
|
|||||||
case IDENTITY_CONTEXT_ERRORS::ERROR_NONE:
|
case IDENTITY_CONTEXT_ERRORS::ERROR_NONE:
|
||||||
break;
|
break;
|
||||||
case IDENTITY_CONTEXT_ERRORS::ERROR_NO_SUCH_USER:
|
case IDENTITY_CONTEXT_ERRORS::ERROR_NO_SUCH_USER:
|
||||||
std::cerr << "lcpex: Aborting: context user not found: " << context_user << std::endl;
|
std::cerr << "REX: Aborting: context user not found: " << context_user << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case IDENTITY_CONTEXT_ERRORS::ERROR_NO_SUCH_GROUP:
|
case IDENTITY_CONTEXT_ERRORS::ERROR_NO_SUCH_GROUP:
|
||||||
std::cerr << "lcpex: Aborting: context group not found: " << context_group << std::endl;
|
std::cerr << "REX: Aborting: context group not found: " << context_group << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case IDENTITY_CONTEXT_ERRORS::ERROR_SETGID_FAILED:
|
case IDENTITY_CONTEXT_ERRORS::ERROR_SETGID_FAILED:
|
||||||
std::cerr << "lcpex: Aborting: Setting GID failed: " << context_user << "/" << context_group << std::endl;
|
std::cerr << "REX: Aborting: Setting GID failed: " << context_user << "/" << context_group << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case IDENTITY_CONTEXT_ERRORS::ERROR_SETUID_FAILED:
|
case IDENTITY_CONTEXT_ERRORS::ERROR_SETUID_FAILED:
|
||||||
std::cerr << "lcpex: Aborting: Setting UID failed: " << context_user << "/" << context_group << std::endl;
|
std::cerr << "REX: Aborting: Setting UID failed: " << context_user << "/" << context_group << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "lcpex: Aborting: Unknown error while setting identity context." << std::endl;
|
std::cerr << "REX: Aborting: Unknown error while setting identity context." << std::endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -160,8 +161,8 @@ void run_child_process(bool context_override, const char* context_user, const ch
|
|||||||
|
|
||||||
int execute(
|
int execute(
|
||||||
std::string command,
|
std::string command,
|
||||||
std::string stdout_log_file,
|
FILE * stdout_log_fh,
|
||||||
std::string stderr_log_file,
|
FILE * stderr_log_fh,
|
||||||
bool context_override,
|
bool context_override,
|
||||||
std::string context_user,
|
std::string context_user,
|
||||||
std::string context_group,
|
std::string context_group,
|
||||||
@@ -182,10 +183,6 @@ int execute(
|
|||||||
clearenv();
|
clearenv();
|
||||||
}
|
}
|
||||||
|
|
||||||
// open file handles to the two log files we need to create for each execution
|
|
||||||
FILE * stdout_log_fh = fopen( stdout_log_file.c_str(), "a+" );
|
|
||||||
FILE * stderr_log_fh = fopen( stderr_log_file.c_str(), "a+" );
|
|
||||||
|
|
||||||
// create the pipes for the child process to write and read from using its stdin/stdout/stderr
|
// create the pipes for the child process to write and read from using its stdin/stdout/stderr
|
||||||
int fd_child_stdout_pipe[2];
|
int fd_child_stdout_pipe[2];
|
||||||
int fd_child_stderr_pipe[2];
|
int fd_child_stderr_pipe[2];
|
||||||
@@ -324,9 +321,7 @@ int execute(
|
|||||||
// wait for child to exit, capture status
|
// wait for child to exit, capture status
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
|
|
||||||
// close the log file handles
|
|
||||||
fclose(stdout_log_fh);
|
|
||||||
fclose(stderr_log_fh);
|
|
||||||
if WIFEXITED(status) {
|
if WIFEXITED(status) {
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -39,8 +39,8 @@
|
|||||||
*/
|
*/
|
||||||
int execute(
|
int execute(
|
||||||
std::string command,
|
std::string command,
|
||||||
std::string stdout_log_file,
|
FILE * stdout_log_fh,
|
||||||
std::string stderr_log_file,
|
FILE * stderr_log_fh,
|
||||||
bool context_override,
|
bool context_override,
|
||||||
std::string context_user,
|
std::string context_user,
|
||||||
std::string context_group,
|
std::string context_group,
|
||||||
@@ -76,8 +76,8 @@ int execute(
|
|||||||
*/
|
*/
|
||||||
int lcpex(
|
int lcpex(
|
||||||
std::string command,
|
std::string command,
|
||||||
std::string stdout_log_file,
|
FILE * stdout_log_fh,
|
||||||
std::string stderr_log_file,
|
FILE * stderr_log_fh,
|
||||||
bool context_override,
|
bool context_override,
|
||||||
std::string context_user,
|
std::string context_user,
|
||||||
std::string context_group,
|
std::string context_group,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "string_expansion.h"
|
#include "string_expansion.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// convert a string to a char** representing our artificial argv to be consumed by execvp
|
// convert a string to a char** representing our artificial argv to be consumed by execvp
|
||||||
char ** expand_env(const std::string& var, int flags )
|
char ** expand_env(const std::string& var, int flags )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ void run_child_process( int fd_child_stderr_pipe[2], char * processed_command[],
|
|||||||
// - TEE child stdout/stderr to parent stdout/stderr
|
// - TEE child stdout/stderr to parent stdout/stderr
|
||||||
int exec_pty(
|
int exec_pty(
|
||||||
std::string command,
|
std::string command,
|
||||||
std::string stdout_log_file,
|
FILE * stdout_log_fh,
|
||||||
std::string stderr_log_file,
|
FILE * stderr_log_fh,
|
||||||
bool context_override,
|
bool context_override,
|
||||||
std::string context_user,
|
std::string context_user,
|
||||||
std::string context_group,
|
std::string context_group,
|
||||||
@@ -114,9 +114,16 @@ int exec_pty(
|
|||||||
// turn our command string into something execvp can consume
|
// turn our command string into something execvp can consume
|
||||||
char ** processed_command = expand_env( command );
|
char ** processed_command = expand_env( command );
|
||||||
|
|
||||||
// open file handles to the two log files we need to create for each execution
|
if ( stdout_log_fh == NULL ) {
|
||||||
FILE * stdout_log_fh = fopen( stdout_log_file.c_str(), "a+" );
|
safe_perror( "Error opening STDOUT log file. Aborting.", &ttyOrig );
|
||||||
FILE * stderr_log_fh = fopen( stderr_log_file.c_str(), "a+" );
|
exit( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( stderr_log_fh == NULL ) {
|
||||||
|
safe_perror( "Error opening STDERR log file. Aborting.", &ttyOrig );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// create the pipes for the child process to write and read from using its stderr
|
// create the pipes for the child process to write and read from using its stderr
|
||||||
int fd_child_stderr_pipe[2];
|
int fd_child_stderr_pipe[2];
|
||||||
@@ -267,9 +274,6 @@ int exec_pty(
|
|||||||
// wait for child to exit, capture status
|
// wait for child to exit, capture status
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
|
|
||||||
// close the log file handles
|
|
||||||
fclose(stdout_log_fh);
|
|
||||||
fclose(stderr_log_fh);
|
|
||||||
ttyResetExit( &ttyOrig);
|
ttyResetExit( &ttyOrig);
|
||||||
if WIFEXITED(status) {
|
if WIFEXITED(status) {
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
|
|||||||
@@ -38,8 +38,8 @@
|
|||||||
*/
|
*/
|
||||||
int exec_pty(
|
int exec_pty(
|
||||||
std::string command,
|
std::string command,
|
||||||
std::string stdout_log_file,
|
FILE * stdout_log_fh,
|
||||||
std::string stderr_log_file,
|
FILE * stderr_log_fh,
|
||||||
bool context_override,
|
bool context_override,
|
||||||
std::string context_user,
|
std::string context_user,
|
||||||
std::string context_group,
|
std::string context_group,
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ bool createDirectory(const std::string& path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Task::prepare_logs( std::string task_name, std::string logs_root, std::string timestamp )
|
bool Task::prepare_logs( std::string task_name, std::string logs_root )
|
||||||
{
|
{
|
||||||
std::string full_path = logs_root + "/" + task_name;
|
std::string full_path = logs_root + "/" + task_name;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@@ -407,19 +407,24 @@ void Task::execute( Conf * configuration )
|
|||||||
logs_root = configuration->get_project_root() + "/" + logs_root;
|
logs_root = configuration->get_project_root() + "/" + logs_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string timestamp = get_8601();
|
|
||||||
// set these first so the pre-execution logs get there.
|
// set these first so the pre-execution logs get there.
|
||||||
/*
|
/*
|
||||||
* create the logs dir here
|
* create the logs dir here
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (! this->prepare_logs( task_name, logs_root, timestamp ) )
|
if (! this->prepare_logs( task_name, logs_root ) )
|
||||||
{
|
{
|
||||||
throw TaskException("Could not prepare logs for task execution at '" + logs_root + "'.");
|
throw TaskException("Could not prepare logs for task execution at '" + logs_root + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string stdout_log_file = logs_root + "/" + timestamp + ".stdout.log";
|
std::string timestamp = get_8601();
|
||||||
std::string stderr_log_file = logs_root + "/" + timestamp + ".stderr.log";
|
std::string stdout_log_file = logs_root + "/" + task_name + "/" + timestamp + ".stdout.log";
|
||||||
|
std::string stderr_log_file = logs_root + "/" + task_name + "/" + timestamp + ".stderr.log";
|
||||||
|
|
||||||
|
// open file handles to the two log files we need to create for each execution
|
||||||
|
FILE * stdout_log_fh = fopen( stdout_log_file.c_str(), "a+" );
|
||||||
|
FILE * stderr_log_fh = fopen( stderr_log_file.c_str(), "a+" );
|
||||||
|
|
||||||
// check if working directory is to be set
|
// check if working directory is to be set
|
||||||
if ( override_working_dir )
|
if ( override_working_dir )
|
||||||
@@ -443,8 +448,8 @@ void Task::execute( Conf * configuration )
|
|||||||
|
|
||||||
int return_code = lcpex(
|
int return_code = lcpex(
|
||||||
command,
|
command,
|
||||||
stdout_log_file,
|
stdout_log_fh,
|
||||||
stderr_log_file,
|
stderr_log_fh,
|
||||||
set_user_context,
|
set_user_context,
|
||||||
user,
|
user,
|
||||||
group,
|
group,
|
||||||
@@ -457,7 +462,6 @@ void Task::execute( Conf * configuration )
|
|||||||
environment_file
|
environment_file
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// **********************************************
|
// **********************************************
|
||||||
// d[0] Error Code Check
|
// d[0] Error Code Check
|
||||||
// **********************************************
|
// **********************************************
|
||||||
@@ -513,8 +517,8 @@ void Task::execute( Conf * configuration )
|
|||||||
this->slog.log_task( E_INFO, task_name, "Executing rectification: " + rectifier + "." );
|
this->slog.log_task( E_INFO, task_name, "Executing rectification: " + rectifier + "." );
|
||||||
int rectifier_error = lcpex(
|
int rectifier_error = lcpex(
|
||||||
rectifier,
|
rectifier,
|
||||||
stdout_log_file,
|
stdout_log_fh,
|
||||||
stderr_log_file,
|
stderr_log_fh,
|
||||||
set_user_context,
|
set_user_context,
|
||||||
user,
|
user,
|
||||||
group,
|
group,
|
||||||
@@ -565,8 +569,8 @@ void Task::execute( Conf * configuration )
|
|||||||
|
|
||||||
int retry_code = lcpex(
|
int retry_code = lcpex(
|
||||||
command,
|
command,
|
||||||
stdout_log_file,
|
stdout_log_fh,
|
||||||
stderr_log_file,
|
stderr_log_fh,
|
||||||
set_user_context,
|
set_user_context,
|
||||||
user,
|
user,
|
||||||
group,
|
group,
|
||||||
@@ -618,4 +622,7 @@ void Task::execute( Conf * configuration )
|
|||||||
// end d[1] Rectify Check
|
// end d[1] Rectify Check
|
||||||
// **********************************************
|
// **********************************************
|
||||||
}
|
}
|
||||||
|
// close the log file handles
|
||||||
|
fclose(stdout_log_fh);
|
||||||
|
fclose(stderr_log_fh);
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,7 @@ class Task
|
|||||||
// the readiness of this task to execute
|
// the readiness of this task to execute
|
||||||
bool defined;
|
bool defined;
|
||||||
|
|
||||||
bool prepare_logs( std::string task_name, std::string logs_root, std::string timestamp );
|
bool prepare_logs( std::string task_name, std::string logs_root );
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ int Shell::load_root( Json::Value loader_root )
|
|||||||
throw ShellException("No execution_arg attribute specified when loading a shell definition.");
|
throw ShellException("No execution_arg attribute specified when loading a shell definition.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( loader_root.isMember("execution_arg") )
|
if ( loader_root.isMember("source_cmd") )
|
||||||
{
|
{
|
||||||
this->execution_arg = loader_root.get( "execution_arg", errmsg ).asString();
|
this->source_cmd = loader_root.get( "source_cmd", errmsg ).asString();
|
||||||
} else {
|
} else {
|
||||||
throw ShellException("No execution_arg attribute specified when loading a shell definition.");
|
throw ShellException("No source_cmd attribute specified when loading a shell definition.");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ void Suite::get_units_from_dir( std::vector<std::string> * files, std::string pa
|
|||||||
// you want here. Something like:
|
// you want here. Something like:
|
||||||
if ( strstr( hFile->d_name, ".units" ))
|
if ( strstr( hFile->d_name, ".units" ))
|
||||||
{
|
{
|
||||||
std::string full_path = path + hFile->d_name;
|
std::string full_path = path + "/" + hFile->d_name;
|
||||||
files->push_back( full_path );
|
files->push_back( full_path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user