Added a run_at, run_every and run_on_start, making the app a daemon like entity.
This commit is contained in:
parent
111c2487d8
commit
41c405a0c5
1 changed files with 694 additions and 46 deletions
143
main.cpp
143
main.cpp
|
|
@ -89,20 +89,20 @@ std::string strip(std::string& t) {
|
|||
}
|
||||
|
||||
void printHelp() {
|
||||
std::cout << "Usage: StartUpRunner [OPTIONS]" << std::endl;
|
||||
std::cout << "OPTIONS:" << std::endl;
|
||||
std::cout << "\t--help|-h : Prints this screen." << std::endl;
|
||||
std::cout << "\t--version|-v : Prints version info." << std::endl;
|
||||
std::cout << "\t--threads|-t [T] : Sets number of threads to [T]." << std::endl;
|
||||
std::cout << "\t--log_dir|-ld [Dir] : Sets log directory to [Dir]." << std::endl;
|
||||
std::cout << "\t--defaults|-d : Prints the default values used if no arguments are provided." << std::endl;
|
||||
std::cout << "\t--json|-j [FileName]: Set Json Startup List to FileName." << std::endl;
|
||||
std::cout << "\t--test|-T [FileName]: Check the json file for errors." << std::endl;
|
||||
std::cout << "For a detailed info about the json startup file use --help json." << std::endl;
|
||||
std::cout << R"(Usage: StartUpRunner [OPTIONS]
|
||||
OPTIONS:
|
||||
--help|-h : Prints this screen.
|
||||
--version|-v : Prints version info.
|
||||
--threads|-t [T] : Sets number of threads to [T].
|
||||
--log_dir|-ld [Dir] : Sets log directory to [Dir].
|
||||
--defaults|-d : Prints the default values used if no arguments are provided.
|
||||
--json|-j [FileName]: Set Json Startup List to FileName.
|
||||
--test|-T [FileName]: Check the json file for errors.
|
||||
For a detailed info about the json startup file use --help json.)" << std::endl;
|
||||
}
|
||||
|
||||
void printVersion() {
|
||||
std::cout << "StartUpRunner: Version-0.0.2 Pre-Alpha Pre-BigBang Era Edition." << std::endl;
|
||||
std::cout << "StartUpRunner: Version-0.0.3 Pre-Alpha Pre-BigBang Era Edition." << std::endl;
|
||||
}
|
||||
|
||||
void printDefaults() {
|
||||
|
|
@ -114,30 +114,56 @@ void printDefaults() {
|
|||
}
|
||||
|
||||
void printJsonHelp() {
|
||||
std::cout << "Json StartUp List file format: " << std::endl;
|
||||
std::cout << "Top level is an Array of Apps." << std::endl;
|
||||
std::cout << "Each App Entry contains: " << std::endl;
|
||||
std::cout << "\t[REQUIRED] name[string] : Name of the module." << std::endl;
|
||||
std::cout << "\t[REQUIRED] app_name[string] : Path to the program with its name." << std::endl;
|
||||
std::cout << "\t[OPTIONAL] app_args[list[string]] : List of arguments to the program." << std::endl;
|
||||
std::cout << "\t[REQUIRED] run_mode[string] : Mode can be daemon or script." << std::endl;
|
||||
std::cout << "\t\tMode daemon : The app forks the program and exits without waiting." << std::endl;
|
||||
std::cout << "\t\tMode script : The app forks the program and waits for it to finish execution." << std::endl;
|
||||
std::cout << "\t\t If no run_mode is given it is presumed to be script." << std::endl;
|
||||
std::cout << "\t[OPTIONAL] after[{name,state}] : List containing names and state of modules." << std::endl;
|
||||
std::cout << "\t\tname[string] : Name of the other module." << std::endl;
|
||||
std::cout << "\t\tstate[string]: State of the other module." << std::endl;
|
||||
std::cout << "\t\t\tState exited : Specified module must have finished execution." << std::endl;
|
||||
std::cout << "\t\t\tState running : Specified module must be running." << std::endl;
|
||||
std::cout << "\t\tThis module will be launched after the module found\n\t\t"
|
||||
"in this list using name is at the state specified as state." << std::endl;
|
||||
std::cout << "\t[OPTIONAL] env{} : Additional enviroment variables." << std::endl;
|
||||
std::cout << "\t\tEvery key in this object will be used as environment name,\n\t\tand every corresponding value as its value." << std::endl;
|
||||
std::cout << "\t[OPTIONAL] working_dir[string] : Working directory of the program." << std::endl;
|
||||
std::cout << "\t[OPTIONAL] create_log[boolean] : Create a log file at logs path." << std::endl;
|
||||
std::cout << "\t[OPTIONAL] run_as[string] : Run as a particular user." << std::endl;
|
||||
std::cout << std::endl << "Example startup_apps.json: ";
|
||||
std::cout << R"(
|
||||
std::cout << R"(Json StartUp List file format:
|
||||
Top level is an Array of Apps.
|
||||
Each App Entry contains:
|
||||
[REQUIRED] name[string] : Name of the module.
|
||||
[REQUIRED] app_name[string] : Path to the program with its name.
|
||||
[REQUIRED] run_mode[string] : Mode can be daemon or script.
|
||||
[OPTIONAL] app_args[list[string]] : List of arguments to the program.
|
||||
Mode daemon : The app forks the program and exits without waiting.
|
||||
Mode script : The app forks the program and waits for it to finish execution.
|
||||
If no run_mode is given it is presumed to be script.
|
||||
[OPTIONAL] after[{name,state}] : List containing names and state of modules.
|
||||
name[string] : Name of the other module.
|
||||
state[string]: State of the other module.
|
||||
State exited : Specified module must have finished execution.
|
||||
State running : Specified module must be running.
|
||||
This module will be launched after the module foundin this list using name is at the state specified as state.
|
||||
[OPTIONAL] env{key: value} : Additional enviroment variables.
|
||||
Every key in this object will be used as environment name,
|
||||
and every corresponding value as its value.
|
||||
[OPTIONAL] working_dir[string] : Working directory of the program.
|
||||
[OPTIONAL] create_log[boolean] : Create a log file at logs path.
|
||||
[OPTIONAL] run_as[string] : Run as a particular user.
|
||||
[OPTIONAL] run_every[string] : Run task at every specified interval.
|
||||
format should be like:
|
||||
[digits][unit]
|
||||
valid units are:
|
||||
s or S: seconds
|
||||
m: minutes
|
||||
h or H: hours
|
||||
d or D: days
|
||||
w or W: weeks
|
||||
M: months
|
||||
Example: 15s
|
||||
Example: 2h
|
||||
[OPTIONAL] run_at[string] : Run task at every specified time.
|
||||
Format of string should be like:
|
||||
"[time] Daily": for running daily at that time
|
||||
"[day] [time] Weekly": for running every week on those days at that time.
|
||||
"[day_month] [time] Monthly": for running every month on those days at that time.
|
||||
[time] format is 24Hrs with [HH:MM:SS]
|
||||
[day] format is any of [Mon, Tue, Wed, Thu, Fri, Sat, Sun]
|
||||
[day_month] format is 1-31.
|
||||
For Weekly, [day] can be a list of days seperated by commas.
|
||||
For Monthly, [day_month] can be a list of days seperated by commas.
|
||||
For Any, [time] can be a list of timestamps seperated by commas.
|
||||
[time] Daily: for running daily at that time.
|
||||
[day] [time] Weekly: for running every week on those days at that time.
|
||||
[OPTIONAL] run_on_start[boolean] : Run on initial startup as well [Only valid for scheduled tasks].
|
||||
|
||||
Example startup_apps.json:
|
||||
[
|
||||
{
|
||||
"name": "LS 0",
|
||||
|
|
@ -156,10 +182,24 @@ void printJsonHelp() {
|
|||
"after": [{"module": "LS 0", "state": "exited"}],
|
||||
"env": {"PATH": "/home/:/usr/bin/", "NAME": "ONE"},
|
||||
"working_dir": "/home/etc",
|
||||
"run_as": "username"
|
||||
"run_as": "username",
|
||||
"run_every": "10s",
|
||||
"run_on_start": true
|
||||
},
|
||||
{
|
||||
"name": "LS 2",
|
||||
"app_name": "/bin/ls",
|
||||
"app_arpgs": ["-lh"],
|
||||
"run_mode": "script",
|
||||
"create_log": true,
|
||||
"after": [{"module": "LS 0", "state": "exited"}],
|
||||
"working_dir": "/home/etc/Documents",
|
||||
"run_on_start": false,
|
||||
"run_at": "1,15,30 01:30:00 Monthly"
|
||||
}
|
||||
]
|
||||
)" << std::endl;
|
||||
)";
|
||||
|
||||
}
|
||||
|
||||
int contains(std::vector<std::string> &list, std::string l, std::string v) {
|
||||
|
|
@ -424,6 +464,8 @@ std::optional<int> checkAppList(std::deque<AppInfo::AppData> ©_list, std::ve
|
|||
}
|
||||
}
|
||||
for(auto &i: after_list) {
|
||||
bool run_validity = i->checkValidity();
|
||||
i->printInfo(out);
|
||||
for(auto &[j, state]: i->getParents()) {
|
||||
if(state == AppInfo::State::exited && j->getRunMode() == AppInfo::RunMode::daemon) {
|
||||
out << "[WARN]: " << i->getModuleName() <<
|
||||
|
|
@ -431,6 +473,26 @@ std::optional<int> checkAppList(std::deque<AppInfo::AppData> ©_list, std::ve
|
|||
std::endl;
|
||||
}
|
||||
}
|
||||
if(!run_validity) {
|
||||
out << "[ERR]: " << i->getModuleName() <<
|
||||
" incorrect format for scheduled run. Please see help page." << std::endl;
|
||||
} else if((i->getScheduled()) && (!i->getRunOnStart())) {
|
||||
const auto* zone = std::chrono::current_zone();
|
||||
auto local_now = zone->to_local(i->getNextTimeToRun());
|
||||
out << "Module: " << i->getModuleName() <<
|
||||
" is scheduled for execution at: " <<
|
||||
std::format("{:%F %T}", local_now) << std::endl;
|
||||
} else if((i->getScheduled()) && (i->getRunOnStart())) {
|
||||
const auto* zone = std::chrono::current_zone();
|
||||
auto local_now = zone->to_local(i->getNextTimeToRun());
|
||||
out << "Module: " << i->getModuleName() <<
|
||||
" will run on init and is also scheduled for execution at: " <<
|
||||
std::format("{:%F %T}", local_now) << std::endl;
|
||||
}
|
||||
else {
|
||||
out << "Module: " << i->getModuleName() <<
|
||||
" is to be launched on init." << i->getScheduled() << i->getRunOnStart() << run_validity << std::endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -541,6 +603,13 @@ int main(int argc, char *argv[]) {
|
|||
app_info.create_log = object["create_log"].get<bool>();
|
||||
if(object.find("run_as") != object.end())
|
||||
app_info.run_as = object["run_as"].get<std::string>();
|
||||
if(object.find("run_at") != object.end())
|
||||
app_info.run_at = object["run_at"].get<std::string>();
|
||||
if(object.find("run_every") != object.end())
|
||||
app_info.run_every = object["run_every"].get<std::string>();
|
||||
if(object.find("run_on_start") != object.end())
|
||||
app_info.run_on_start = object["run_on_start"].get<bool>();
|
||||
|
||||
app_info.env = env_list;
|
||||
app_info.after = after_list;
|
||||
app_info.module_name = object["name"].get<std::string>();
|
||||
|
|
|
|||
Loading…
Reference in a new issue