Added a run_at, run_every and run_on_start, making the app a daemon like entity.

This commit is contained in:
unrealdragon 2026-10-21 21:38:49 +05:30
commit 41c405a0c5

143
main.cpp
View file

@ -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> &copy_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> &copy_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>();