]> Kevux Git Server - fll/commitdiff
Progress: controller program, restructure some of f*_execute functionality, and add...
authorKevin Day <thekevinday@gmail.com>
Thu, 31 Dec 2020 22:21:04 +0000 (16:21 -0600)
committerKevin Day <thekevinday@gmail.com>
Thu, 31 Dec 2020 22:21:04 +0000 (16:21 -0600)
For the controller program:
- add "freeze", "thaw", "pause", and "resume".
- improve simulation to actually perform an execute, but with a stub execution (an empty bash script).
- print more information when performing the stubbed simulation.
- simulation should not stop on errors when simulating, there are a number of cases where stopping is still happening.
- add a microsleep during the stubbed execution to better simulate synchronous vs asynchronous behavior.
- The F_schedule is no longer being returned from the child process, do not treat it as a child exit state.
- add more documentation.

14 files changed:
level_0/f_execute/c/execute-common.h
level_1/fl_execute/c/execute-common.h
level_2/fll_execute/c/execute.h
level_3/controller/c/private-common.h
level_3/controller/c/private-controller.c
level_3/controller/c/private-rule.c
level_3/controller/c/private-rule.h
level_3/controller/data/settings/example/rules/command/multiple.rule
level_3/controller/data/settings/example/rules/script/php.rule
level_3/controller/data/settings/example/rules/script/succeed.rule
level_3/controller/documents/actions.txt [new file with mode: 0644]
level_3/controller/documents/rule.txt
level_3/controller/documents/simulate.txt [new file with mode: 0644]
level_3/controller/specifications/rule.txt

index 52dfedbe715a62ec464d85854fcf3ee0482a3f82..71a8d006700d3460b36706c537bdf1f4bf600ef3 100644 (file)
 extern "C" {
 #endif
 
+/**
+ * A structure representing a scheduler and its parameters for execution.
+ *
+ * policy:   the scheduler policy.
+ * priority: the scheduler priority;
+ */
+#ifndef _di_f_execute_scheduler_t_
+  typedef struct {
+    int policy;
+    int priority;
+  } f_execute_scheduler_t;
+
+  #define f_execute_scheduler_t_initialize { 0, 0 }
+
+  #define f_macro_execute_scheduler_t_initialize(policy, priority) { policy, priority }
+
+  #define f_execute_scheduler_t_clear(scheduler) \
+    scheduler.policy = 0; \
+    scheduler.priority = 0;
+#endif // _di_f_execute_scheduler_t_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 7cc9e2c6f400c29faaf3253200a03d8b802c1e68..a3f919f0e25c71f567c145d8e31a90b7543c0c56 100644 (file)
@@ -52,27 +52,6 @@ extern "C" {
 #endif // _di_fl_execute_parameter_t_
 
 /**
- * A structure representing a scheduler and its parameters for execution.
- *
- * policy:   the scheduler policy.
- * priority: the scheduler priority;
- */
-#ifndef _di_fl_execute_scheduler_t_
-  typedef struct {
-    int policy;
-    int priority;
-  } fl_execute_scheduler_t;
-
-  #define fl_execute_scheduler_t_initialize { 0, 0 }
-
-  #define fl_macro_execute_scheduler_t_initialize(policy, priority) { policy, priority }
-
-  #define fl_execute_scheduler_t_clear(scheduler) \
-    scheduler.policy = 0; \
-    scheduler.priority = 0;
-#endif // _di_fl_execute_scheduler_t_
-
-/**
  * A structure for containing identity and access related parameters for the execute functions that call the execv() family of functions.
  *
  * There are likely many more identity and access related things that can be done but this focuses on a small core set of those.
@@ -84,34 +63,34 @@ extern "C" {
  * id_user:       the id of the user to assign the child process to, set to 0 to not use.
  * id_group:      the id of the group to assign the child process to, set to 0 to not use.
  * capability:    all of the capabilities to assign the child process to, set to 0 to not use (f_capability_t is a pointer).
+ * control_group: an array of cgroups (control groups) to assign the child PID to, set to 0 to not use.
  * id_groups:     the ids of each supplemental group to assign the child process to, set to 0 to not use.
  * scheduler:     the scheduler to assign the child process to, set to 0 to not use.
- * control_group: an array of cgroups (control groups) to assign the child PID to, set to 0 to not use.
  */
 #ifndef _di_fl_execute_as_t_
   typedef struct {
     int *nice;
     uid_t *id_user;
     gid_t *id_group;
-    f_capability_t capability;
 
-    f_int32s_t *id_groups;
-    fl_execute_scheduler_t *scheduler;
+    f_capability_t capability;
     f_control_group_t *control_group;
+    f_int32s_t *id_groups;
+    f_execute_scheduler_t *scheduler;
   } fl_execute_as_t;
 
   #define fl_execute_as_t_initialize { 0, 0, 0, 0, 0, 0, 0 }
 
-  #define fl_macro_execute_as_t_initialize(nice, id_user, id_group, capability, id_groups, scheduler, control_group) { nice, id_user, id_group, capability, id_groups, scheduler, control_group }
+  #define fl_macro_execute_as_t_initialize(nice, id_user, id_group, capability, control_group, id_groups, scheduler) { nice, id_user, id_group, capability, control_group, id_groups, scheduler }
 
   #define fl_execute_as_t_clear(as) \
     as.nice = 0; \
     as.id_user = 0; \
     as.id_group = 0; \
     as.capability = 0; \
+    as.control_group = 0; \
     as.id_groups = 0; \
-    as.scheduler = 0; \
-    as.control_group = 0;
+    as.scheduler = 0;
 #endif // _di_fl_execute_as_t_
 
 #ifdef __cplusplus
index 3db3dc5b2e6522ec3f4996060443d799b0229279..fc2a08233be79eef33be9f321f42e91c09e42e61 100644 (file)
@@ -429,7 +429,7 @@ extern "C" {
  *   F_none on success.
  *   F_child on success but this is the child thread.
  *   F_capability (with error bit) on failure to set capabilities in the child (only the child process returns this).
- *   F_control_group (with error bit) on failure to set capabilities in the child (only the parent process returns this).
+ *   F_control_group (with error bit) on failure to set control group in the child (only the parent process returns this).
  *   F_child (with error bit) on any failure without an explicit failure code (like F_group) before calling execute but this is the child thread.
  *   F_failure (with error bit) on execution failure.
  *   F_fork (with error bit) on fork failure.
index 714397ad2d0d01b71e816eba63fe3596b159bfe6..8ded89fd2dee5e80af9d742408550b473e971ddc 100644 (file)
@@ -34,6 +34,7 @@ extern "C" {
   #define controller_string_fail          "fail"
   #define controller_string_failsafe      "failsafe"
   #define controller_string_fifo          "fifo"
+  #define controller_string_freeze        "freeze"
   #define controller_string_group         "group"
   #define controller_string_groups        "groups"
   #define controller_string_how           "how"
@@ -51,6 +52,7 @@ extern "C" {
   #define controller_string_other         "other"
   #define controller_string_parameter     "parameter"
   #define controller_string_path          "path"
+  #define controller_string_pause         "pause"
   #define controller_string_pid           "pid"
   #define controller_string_program       "program"
   #define controller_string_ready         "ready"
@@ -58,6 +60,7 @@ extern "C" {
   #define controller_string_require       "require"
   #define controller_string_required      "required"
   #define controller_string_restart       "restart"
+  #define controller_string_resume        "resume"
   #define controller_string_round_robin   "round_robin"
   #define controller_string_rule          "rule"
   #define controller_string_rules         "rules"
@@ -69,6 +72,7 @@ extern "C" {
   #define controller_string_stop          "stop"
   #define controller_string_succeed       "succeed"
   #define controller_string_synchronous   "synchronous"
+  #define controller_string_thaw          "thaw"
   #define controller_string_timeout       "timeout"
   #define controller_string_type          "type"
   #define controller_string_use           "use"
@@ -99,6 +103,7 @@ extern "C" {
   #define controller_string_fail_length          4
   #define controller_string_failsafe_length      8
   #define controller_string_fifo_length          4
+  #define controller_string_freeze_length        6
   #define controller_string_group_length         5
   #define controller_string_how_length           3
   #define controller_string_idle_length          4
@@ -115,6 +120,7 @@ extern "C" {
   #define controller_string_other_length         5
   #define controller_string_parameter_length     9
   #define controller_string_path_length          4
+  #define controller_string_pause_length         5
   #define controller_string_pid_length           3
   #define controller_string_program_length       7
   #define controller_string_ready_length         5
@@ -122,6 +128,7 @@ extern "C" {
   #define controller_string_require_length       7
   #define controller_string_required_length      8
   #define controller_string_restart_length       7
+  #define controller_string_resume_length        6
   #define controller_string_round_robin_length   11
   #define controller_string_rule_length          4
   #define controller_string_rules_length         5
@@ -133,6 +140,7 @@ extern "C" {
   #define controller_string_stop_length          4
   #define controller_string_succeed_length       7
   #define controller_string_synchronous_length   11
+  #define controller_string_thaw_length          4
   #define controller_string_timeout_length       7
   #define controller_string_type_length          4
   #define controller_string_use_length           3
@@ -157,12 +165,16 @@ extern "C" {
 
   enum {
     controller_rule_action_type_create = 1,
+    controller_rule_action_type_freeze,
     controller_rule_action_type_group,
     controller_rule_action_type_kill,
-    controller_rule_action_type_restart,
+    controller_rule_action_type_pause,
     controller_rule_action_type_reload,
+    controller_rule_action_type_restart,
+    controller_rule_action_type_resume,
     controller_rule_action_type_start,
     controller_rule_action_type_stop,
+    controller_rule_action_type_thaw,
     controller_rule_action_type_use,
     controller_rule_action_type_user,
   };
@@ -287,7 +299,8 @@ extern "C" {
   #define controller_rule_option_asynchronous 0x1
   #define controller_rule_option_require      0x2
   #define controller_rule_option_simulate     0x4
-  #define controller_rule_option_wait         0x8
+  #define controller_rule_option_validate     0x8
+  #define controller_rule_option_wait         0x10
 
   // bitwise codes representing properties on controller_rule_t that have been found in the rule file.
   #define controller_rule_has_control_group 0x1
@@ -327,7 +340,7 @@ extern "C" {
     f_capability_t capability;
     f_control_group_t control_group;
     f_int32s_t groups;
-    fl_execute_scheduler_t scheduler;
+    f_execute_scheduler_t scheduler;
 
     controller_rule_items_t items;
   } controller_rule_t;
@@ -357,7 +370,7 @@ extern "C" {
       f_capability_t_initialize, \
       f_control_group_t_initialize, \
       f_int32s_t_initialize, \
-      fl_execute_scheduler_t_initialize, \
+      f_execute_scheduler_t_initialize, \
       controller_rule_items_initialize, \
     }
 
index 6ba50bec21f2cc2284f37c41affbf03cd94b6706..8111999e253e08128d4b4efc4ca8f43bffda17d6 100644 (file)
@@ -567,6 +567,7 @@ extern "C" {
     controller_entry_actions_t *actions = 0;
 
     const bool simulate = data->parameters[controller_parameter_test].result == f_console_result_found;
+    const bool validate = data->parameters[controller_parameter_validate].result == f_console_result_found;
 
     cache->ats.used = 0;
     cache->line_action = 0;
index 04f6643a66a329d02cc22f0537c8bd56973f932e..2d295acc8383bb9115e26a11ad290d31f56fa982 100644 (file)
@@ -369,23 +369,26 @@ extern "C" {
 
       if (cache.name_action.used) {
         fprintf(output.to.stream, "%s '", item ? "action" : "value");
-        fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_action.string, output.notable.after->string);
-        fprintf(output.to.stream, "%s' on line ", output.context.before->string);
+        fprintf(output.to.stream, "%s%s", output.context.after->string, output.notable.before->string);
+        f_print_dynamic(output.to.stream, cache.name_action);
+        fprintf(output.to.stream, "%s%s' on line ", output.notable.after->string, output.context.before->string);
         fprintf(output.to.stream, "%s%s%llu%s", output.context.after->string, output.notable.before->string, cache.line_action, output.notable.after->string);
         fprintf(output.to.stream, "%s for ", output.context.before->string);
       }
 
       if (cache.name_item.used) {
         fprintf(output.to.stream, "rule %s '", item ? "item" : "setting");
-        fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_item.string, output.notable.after->string);
-        fprintf(output.to.stream, "%s' on line ", output.context.before->string);
+        fprintf(output.to.stream, "%s%s", output.context.after->string, output.notable.before->string);
+        f_print_dynamic(output.to.stream, cache.name_item);
+        fprintf(output.to.stream, "%s%s' on line ", output.notable.after->string, output.context.before->string);
         fprintf(output.to.stream, "%s%s%llu%s", output.context.after->string, output.notable.before->string, cache.line_item, output.notable.after->string);
         fprintf(output.to.stream, "%s for ", output.context.before->string);
       }
 
       if (cache.name_file.used) {
         fprintf(output.to.stream, "file '");
-        fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_file.string, output.notable.after->string);
+        fprintf(output.to.stream, "%s%s", output.context.after->string, output.notable.before->string);
+        f_print_dynamic(output.to.stream, cache.name_file);
         fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol_s[0]);
       }
     }
@@ -442,7 +445,7 @@ extern "C" {
 #endif // _di_controller_rule_error_print_need_want_wish_
 
 #ifndef _di_controller_rule_execute_
-  f_return_status controller_rule_execute(const controller_cache_t cache, const f_array_length_t index, const uint8_t type, controller_data_t *data, controller_setting_t *setting) {
+  f_return_status controller_rule_execute(const controller_cache_t cache, const f_array_length_t index, const uint8_t type, const bool simulate, controller_data_t *data, controller_setting_t *setting) {
     f_status_t status = F_none;
     f_status_t success = F_false;
 
@@ -535,7 +538,7 @@ extern "C" {
             parameter.option |= fl_execute_parameter_option_path;
           }
 
-          status = controller_rule_execute_foreground(item->type, *action, 0, action->parameters, 0, &parameter, &as, data);
+          status = controller_rule_execute_foreground(item->type, *action, simulate, 0, action->parameters, 0, &parameter, &as, data);
 
           if (status == F_child) {
             break;
@@ -543,7 +546,8 @@ extern "C" {
 
           if (F_status_is_error(status)) {
             action->status = F_status_set_error(F_failure);
-            break;
+
+            if (!simulate) break;
           }
 
           success = F_true;
@@ -555,7 +559,7 @@ extern "C" {
             parameter.option |= fl_execute_parameter_option_path;
           }
 
-          status = controller_rule_execute_foreground(item->type, *action, rule->script.used ? rule->script.string : controller_default_program_script, arguments_none, 0, &parameter, &as, data);
+          status = controller_rule_execute_foreground(item->type, *action, simulate, rule->script.used ? rule->script.string : controller_default_program_script, arguments_none, 0, &parameter, &as, data);
 
           if (status == F_child) {
             break;
@@ -563,7 +567,8 @@ extern "C" {
 
           if (F_status_is_error(status)) {
             action->status = F_status_set_error(F_failure);
-            break;
+
+            if (!simulate) break;
           }
 
           success = F_true;
@@ -574,11 +579,12 @@ extern "C" {
             parameter.option |= fl_execute_parameter_option_path;
           }
 
-          status = controller_rule_execute_pid_with(item->type, *action, 0, action->parameters, 0, &parameter, &as, data);
+          status = controller_rule_execute_pid_with(item->type, *action, simulate, 0, action->parameters, 0, &parameter, &as, data);
 
           if (F_status_is_error(status)) {
             action->status = F_status_set_error(F_failure);
-            break;
+
+            if (!simulate) break;
           }
 
           success = F_true;
@@ -604,7 +610,7 @@ extern "C" {
         if (status == F_child || status == F_signal) break;
       } // for
 
-      if (status == F_child || status == F_signal || F_status_is_error(status)) break;
+      if (status == F_child || status == F_signal || F_status_is_error(status) && !simulate) break;
     } // for
 
     fl_string_maps_delete(&environment);
@@ -628,7 +634,9 @@ extern "C" {
 #endif // _di_controller_rule_execute_
 
 #ifndef _di_controller_rule_execute_pid_with_
-  f_return_status controller_rule_execute_pid_with(const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, controller_data_t *data) {
+  f_return_status controller_rule_execute_pid_with(const uint8_t type, const controller_rule_action_t action, const bool simulate, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, controller_data_t *data) {
+
+    f_status_t status = F_none;
     int result = 0;
 
     // @todo check to see if pid file exists.
@@ -637,12 +645,39 @@ extern "C" {
     //       in which case fll_execute_program() is called.
     //       otherwise this needs to call an asynchronous execute process.
     //       until then, this controller_rule_execute_pid_with() function is not correct and only represents a process that forks to the background.
-    f_status_t status = fll_execute_program(program, arguments, parameter, as, &result);
+
+    if (simulate) {
+
+      if (data->error.verbosity != f_console_verbosity_quiet) {
+        fprintf(data->output.stream, "%c", f_string_eol_s[0]);
+        fprintf(data->output.stream, "Simulating execution of '");
+        fprintf(data->output.stream, "%s%s%s", data->context.title.string, program ? program : arguments.used && arguments.array[0].used ? arguments.array[0].string : f_string_empty_s, data->context.reset.string);
+        fprintf(data->output.stream, "' with the arguments: '%s", data->context.title.string);
+
+        for (f_array_length_t i = program ? 0 : 1; i < arguments.used; ++i) {
+          fprintf(data->output.stream, "%s%s", (program && i || !program && i > 1) ? " " : "", arguments.array[i].string);
+        } // for
+
+        fprintf(data->output.stream, "%s'.%c", data->context.reset.string, f_string_eol_s[0]);
+      }
+
+      // sleep for less than a second to better show simulation of synchronous vs asynchronous.
+      usleep(200000);
+
+      const f_string_static_t simulated_program = f_macro_string_static_t_initialize(f_string_empty_s, 0);
+      const f_string_statics_t simulated_arguments = f_string_statics_t_initialize;
+      fl_execute_parameter_t simulated_parameter = fl_macro_execute_parameter_t_initialize(parameter->option, parameter->environment, parameter->signals, &simulated_program);
+
+      status = fll_execute_program(controller_default_program_script, simulated_arguments, &simulated_parameter, as, &result);
+    }
+    else {
+      status = fll_execute_program(program, arguments, parameter, as, &result);
+    }
 
     if (F_status_is_error(status)) {
       status = F_status_set_fine(status);
 
-      if (status == F_child || status == F_capability || status == F_group || status == F_nice || status == F_schedule || status == F_user) {
+      if (status == F_child || status == F_capability || status == F_group || status == F_nice || status == F_user) {
         status = F_child;
       }
       else {
@@ -687,15 +722,43 @@ extern "C" {
 #endif // _di_controller_rule_execute_pid_with_
 
 #ifndef _di_controller_rule_execute_foreground_
-  f_return_status controller_rule_execute_foreground(const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, controller_data_t *data) {
+  f_return_status controller_rule_execute_foreground(const uint8_t type, const controller_rule_action_t action, const bool simulate, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, controller_data_t *data) {
+
+    f_status_t status = F_none;
     int result = 0;
 
-    f_status_t status = fll_execute_program(program, arguments, parameter, as, &result);
+    if (simulate) {
+
+      if (data->error.verbosity != f_console_verbosity_quiet) {
+        fprintf(data->output.stream, "%c", f_string_eol_s[0]);
+        fprintf(data->output.stream, "Simulating execution of '");
+        fprintf(data->output.stream, "%s%s%s", data->context.title.string, program ? program : arguments.used && arguments.array[0].used ? arguments.array[0].string : f_string_empty_s, data->context.reset.string);
+        fprintf(data->output.stream, "' with the arguments: '%s", data->context.title.string);
+
+        for (f_array_length_t i = program ? 0 : 1; i < arguments.used; ++i) {
+          fprintf(data->output.stream, "%s%s", (program && i || !program && i > 1) ? " " : "", arguments.array[i].string);
+        } // for
+
+        fprintf(data->output.stream, "%s'.%c", data->context.reset.string, f_string_eol_s[0]);
+      }
+
+      // sleep for less than a second to better show simulation of synchronous vs asynchronous.
+      usleep(200000);
+
+      const f_string_static_t simulated_program = f_macro_string_static_t_initialize(f_string_empty_s, 0);
+      const f_string_statics_t simulated_arguments = f_string_statics_t_initialize;
+      fl_execute_parameter_t simulated_parameter = fl_macro_execute_parameter_t_initialize(parameter->option, parameter->environment, parameter->signals, &simulated_program);
+
+      status = fll_execute_program(controller_default_program_script, simulated_arguments, &simulated_parameter, as, &result);
+    }
+    else {
+      status = fll_execute_program(program, arguments, parameter, as, &result);
+    }
 
     if (F_status_is_error(status)) {
       status = F_status_set_fine(status);
 
-      if (status == F_child || status == F_capability || status == F_group || status == F_nice || status == F_schedule || status == F_user) {
+      if (status == F_child || status == F_capability || status == F_group || status == F_nice || status == F_user) {
         status = F_child;
       }
       else {
@@ -861,9 +924,15 @@ extern "C" {
       else if (fl_string_dynamic_compare_string(controller_string_kill, cache->name_action, controller_string_kill_length) == F_equal_to) {
         type = controller_rule_action_type_kill;
       }
+      else if (fl_string_dynamic_compare_string(controller_string_pause, cache->name_action, controller_string_pause_length) == F_equal_to) {
+        type = controller_rule_action_type_pause;
+      }
       else if (fl_string_dynamic_compare_string(controller_string_restart, cache->name_action, controller_string_restart_length) == F_equal_to) {
         type = controller_rule_action_type_restart;
       }
+      else if (fl_string_dynamic_compare_string(controller_string_resume, cache->name_action, controller_string_resume_length) == F_equal_to) {
+        type = controller_rule_action_type_resume;
+      }
       else if (fl_string_dynamic_compare_string(controller_string_reload, cache->name_action, controller_string_reload_length) == F_equal_to) {
         type = controller_rule_action_type_reload;
       }
@@ -1057,11 +1126,15 @@ extern "C" {
   f_return_status controller_rule_process(const f_array_length_t index, const uint8_t action, const uint8_t options, controller_data_t *data, controller_setting_t *setting, controller_cache_t *cache) {
 
     switch (action) {
+      case controller_rule_action_type_freeze:
       case controller_rule_action_type_kill:
+      case controller_rule_action_type_pause:
       case controller_rule_action_type_reload:
       case controller_rule_action_type_restart:
+      case controller_rule_action_type_resume:
       case controller_rule_action_type_start:
       case controller_rule_action_type_stop:
+      case controller_rule_action_type_thaw:
         break;
 
       default:
@@ -1243,7 +1316,7 @@ extern "C" {
               memcpy(cache_name_file, cache->name_file.string, cache->name_file.used);
 
               // @todo: this should pass or use the asynchronous state.
-              status = controller_rule_process(at, controller_rule_action_type_start, options, data, setting, cache);
+              status = controller_rule_process(at, action, options, data, setting, cache);
 
               if (status == F_child || status == F_signal) break;
 
@@ -1306,7 +1379,7 @@ extern "C" {
       } // for
     }
 
-    if (!(options & controller_rule_option_simulate) && F_status_is_error_not(status)) {
+    if (!(options & controller_rule_option_validate) && F_status_is_error_not(status)) {
 
       // find at least one of the requested action when the rule is required.
       if (options & controller_rule_option_require) {
@@ -1343,7 +1416,7 @@ extern "C" {
       }
 
       if (F_status_is_error_not(status)) {
-        status = controller_rule_execute(*cache, index, action, data, setting);
+        status = controller_rule_execute(*cache, index, action, options & controller_rule_option_simulate, data, setting);
 
         if (F_status_is_error(status)) {
           controller_rule_error_print(data->error, *cache, F_true);
index b5f14ac37fee2807bb62d789be4a50335fad737d..b795fbf722fb3b8ef17fe6cd2e917c96eb28fbdf 100644 (file)
@@ -214,10 +214,15 @@ extern "C" {
  *
  *   Only subset of the action type codes are supported:
  *   - controller_rule_action_type_kill
+ *   - controller_rule_action_type_pause
  *   - controller_rule_action_type_reload
  *   - controller_rule_action_type_restart
+ *   - controller_rule_action_type_resume
  *   - controller_rule_action_type_start
  *   - controller_rule_action_type_stop
+ * @param simulate
+ *   If TRUE, then run a simulated action (outputing result and executing an empty script).
+ *   If FALSE, perform the real execution.
  * @param data
  *   The program data.
  * @param setting
@@ -233,7 +238,7 @@ extern "C" {
  *   On failure, the individual status for the rule is set to an appropriate error status.
  */
 #ifndef _di_controller_rule_execute_
-  extern f_return_status controller_rule_execute(const controller_cache_t cache, const f_array_length_t index, const uint8_t type, controller_data_t *data, controller_setting_t *setting) f_gcc_attribute_visibility_internal;
+  extern f_return_status controller_rule_execute(const controller_cache_t cache, const f_array_length_t index, const uint8_t type, const bool simulate, controller_data_t *data, controller_setting_t *setting) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_rule_execute_
 
 /**
@@ -253,6 +258,9 @@ extern "C" {
  *   - controller_rule_action_type_restart
  *   - controller_rule_action_type_start
  *   - controller_rule_action_type_stop
+ * @param simulate
+ *   If TRUE, then run a simulated action (outputing result and executing an empty script).
+ *   If FALSE, perform the real execution.
  * @param program
  *   The program to use (such as "bash").
  * @param arguments
@@ -279,7 +287,7 @@ extern "C" {
  * @see fll_execute_program()
  */
 #ifndef _di_controller_rule_execute_pid_with_
-  extern f_return_status controller_rule_execute_pid_with(const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, controller_data_t *data) f_gcc_attribute_visibility_internal;
+  extern f_return_status controller_rule_execute_pid_with(const uint8_t type, const controller_rule_action_t action, const bool simulate, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, controller_data_t *data) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_rule_execute_pid_with_
 
 /**
@@ -296,6 +304,9 @@ extern "C" {
  *   - controller_rule_action_type_restart
  *   - controller_rule_action_type_start
  *   - controller_rule_action_type_stop
+ * @param simulate
+ *   If TRUE, then run a simulated action (outputing result and executing an empty script).
+ *   If FALSE, perform the real execution.
  * @param program
  *   The program to use (such as "bash").
  * @param arguments
@@ -321,7 +332,7 @@ extern "C" {
  * @see fll_execute_program()
  */
 #ifndef _di_controller_rule_execute_foreground_
-  extern f_return_status controller_rule_execute_foreground(const uint8_t type, const controller_rule_action_t action, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, controller_data_t *data) f_gcc_attribute_visibility_internal;
+  extern f_return_status controller_rule_execute_foreground(const uint8_t type, const controller_rule_action_t action, const bool simulate, const f_string_t program, const f_string_dynamics_t arguments, const uint8_t options, fl_execute_parameter_t * const parameter, fl_execute_as_t * const as, controller_data_t *data) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_rule_execute_foreground_
 
 /**
index bb18ec318c44017bf4535eb59d09913efcc3a4b8..88efe7cf8eae96eb6d846a901b112aeabe648b0d 100644 (file)
@@ -28,4 +28,4 @@ command:
   start whoami
 
 command:
-  start date
+  start date -u
index cb67fd5490052e04d1c8a6c42e9c041b175b5bfd..bf6c405924bc98ac2b6a3786ed228e8861189fb9 100644 (file)
@@ -15,7 +15,7 @@ script:
     var_dump(getenv());
     print("\n");
 
-    print("Now executing 'date' program, assuming that it exists in \$PATH.\n");
-    passthru("date");
+    print("Now executing 'date -u' program, assuming that it exists in \$PATH.\n");
+    passthru("date -u");
     print("\n");
   }
index 925df1c55aecbc57d538ab9cb83f70c422ca2c28..be066b2caf4771ecc5d1b70f1c7ac11bab470f1f 100644 (file)
@@ -11,7 +11,7 @@ script:
     echo "Hello this is script #1 and should succeed."
     echo
 
-    date
+    date -u
     echo
   }
 
diff --git a/level_3/controller/documents/actions.txt b/level_3/controller/documents/actions.txt
new file mode 100644 (file)
index 0000000..e2ae340
--- /dev/null
@@ -0,0 +1,74 @@
+# fss-0002
+
+Actions Documentation:
+  This describes the intent and purpose of the actions provided for individual Rules (or things related to a Rule).
+
+  Each Action represents a specific intent and purpose but many of these actions are customizable via the rule file.
+  One should expect an Action to operate as described here but the system administrator or distributor is fully capable of doing something different.
+  For those doing something different, appropriate documentation is suggested.
+
+  These actions should be usable by any "control" program that communicates with this "controller" program.
+  Should any "control" or "controller" program implementation not support any particular Action for any reason, one should report that the Action is unsupported.
+
+  Freeze Action\:
+    The Freeze Action is an extension of a Control Group.
+    This is internal to the "controller" program and is not customizable via any Rule file.
+    For a customizable "freeze"-like capability, look into the Pause and Resume Actions.
+    This is complemented by the Thaw Action.
+
+    This designates that a processes Control Group is to be frozen.
+    All Rules (or any process not controlled by the "controller") that is within the same Control Group will be frozen.
+    (@todo consider instead designing this around the Control Groups instead of a "rule".)
+    (This documentation will likely change with consideration to the above @todo once this gets implemented.)
+
+    This must not attempt to freeze (or unfreeze) the Control Group that the "controller" belongs to.
+    Therefore, if a Rule does not specify a Control Group, then it is likely that the Freeze Action will be unsupported for that Rule/Control Group.
+
+  Kill Action\:
+    Forcefully terminate some process controlled by the "controller".
+    This action cannot be blocked and it is recommended to use a Stop Action instead for a more proper termination.
+
+  Pause Action\:
+    The Pause Action will pause (or freeze) the process controlled by the Rule.
+    Although similar to the Freeze Action, this is intended to communicate to an individual process and inform to Pause.
+    This is complemented by the Resume Action.
+
+  Restart Action\:
+    The Restart Action will either perform a Stop Action and then a Restart Action or it will perform the Restart Action designated in some Rule file.
+    Ideally this should inform some process to perform its own restart routines.
+
+  Resume Action\:
+    The Resume Action will unpause (or unfreeze) the process controlled by the Rule.
+    Although similar to the Thaw Action, this is intended to communicate to an individual process and inform to Resume.
+    This is complemented by the Pause Action.
+
+  Reload Action\:
+    The Reload Action will perform the Reload Action designated in some Rule file.
+    Ideally this should inform some process to perform its own reload routines.
+    Many programs often differentiate the concept "reload" from the concept "restart" in that the program remains running during a "reload".
+
+  Start Action\:
+    The Start Action will perform the Start Action designated in some Rule file.
+    This action should be used to start some program or script.
+    This is the action called by Entry file.
+    This is complemented by the Stop Action.
+
+  Stop Action\:
+    The Stop Action will perform the Stop Action designated in some Rule file.
+    This action should be used to stop some program or script.
+    This is the action called for all running controlled processes on shutdown.
+    This is complemented by the Start Action.
+
+  Thaw Action\:
+    The Thaw Action is an extension of a Control Group.
+    This is internal to the "controller" program and is not customizable via any Rule file.
+    For a customizable "thaw"-like capability, look into the "pause" and "resume" Actions.
+    This is complemented by the Freeze Action.
+
+    This designates that a processes Control Group is to be unfrozen.
+    All Rules (or any process not controlled by the "controller") that is within the same Control Group will be unfrozen.
+    (@todo consider instead designing this around the Control Groups instead of a "rule".)
+    (This documentation will likely change with consideration to the above @todo once this gets implemented.)
+
+    This must not attempt to freeze (or unfreeze) the Control Group that the "controller" belongs to.
+    Therefore, if a Rule does not specify a Control Group, then it is likely that the Thaw Action will be unsupported for that Rule/Control Group.
index 45199d6c40c7d9b1f90926978afd594524c19bb9..537c63d919f7c43c107e6d79f4c0142c343144b7 100644 (file)
@@ -62,13 +62,15 @@ Rule Documentation:
   A "script" is assumed to be in GNU Bash, which is the default expected behavior, but the specification does not explicitly require this.
   Another scripting language can be used but changing this incurs the responsibility to ensure all rules are updated to the appropriate scripting language.
 
-  There are five primary inner Content to perform: "kill", "restart", "reload", "start", and "stop".
+  There are seven primary inner Content to perform: "kill", "pause", "restart", "resume", "reload", "start", and "stop".
 
   The "kill" Content is performed whenever this rule is executed using the kill action (which is, in general, a forced stop).
-  The "start" Content is performed whenever this rule is executed using the start action.
-  The "stop" Content is performed whenever this rule is executed using the stop action.
+  The "pause" Content is performed whenever this rule is executed using the pause action.
   The "restart" Content is performed whenever this rule is executed using the restart action.
+  The "resume" Content is performed whenever this rule is executed using the resume action.
   The "reload" Content is performed whenever this rule is executed using the reload action.
+  The "start" Content is performed whenever this rule is executed using the start action.
+  The "stop" Content is performed whenever this rule is executed using the stop action.
 
   When "restart" Content is not provided, then "start" and "stop" is called when the rule is executed using the restart action, if both "start" and "stop" are provided.
   When "reload", "start", or "stop" Content are not provided, then no respective action is performed.
diff --git a/level_3/controller/documents/simulate.txt b/level_3/controller/documents/simulate.txt
new file mode 100644 (file)
index 0000000..5a45319
--- /dev/null
@@ -0,0 +1,24 @@
+# fss-0002
+
+Simulate Documentation:
+  This describes the intent and purpose of the simulation (and testing) parameters.
+
+  The "controller" program is design to support being run as an alternative to an init program (such as Sysvinit or SystemD).
+  To help prevent problems, testing and simulation functionality is provided.
+
+  The "test" functionality, by itself will simply check the syntax of the Entry and Rule files (for Rule files specified in the Entry file).
+  Errors are reported and nothing is executed.
+
+  The "test" functionality, when specified along with the "simulate" functionality, will perform just like the "test" functionality without the "simulate" except that additional information of the Rules to be executed will be printed.
+  There will be no execution or simulated execution of any Rule when both "test" and "simulate" are used togethor.
+
+  The "simulate" functionality, by itself will perform a simulated execution of all Rules designated by the Entry file.
+  The simulation is not a true simulation in that no program is ever called to pretend to perform any operations.
+  Furthermore, any "script" specified inside a Rule is only simulated as a whole and not its individual parts.
+
+  When a Rule is simulated, an empty script command (generally defaulting to "bash") is executed in place of the actual program being executed for each program or script in the Rule file that is to be executed.
+  This allows for testing the designated permissions and other settings that would be applied when calling some program.
+  At this time, any Control Groups are not simulated but are actually created and the simulating process will actually be placed within the Control Group.
+  (@todo consider adding an additional parameter optionally to disable this behavior and ignore Control Groups during simulation.)
+
+  (@todo both "test" and "simulate" functionality will need to consider being supported for testing individual Rules when requested by some "control" program.)
index 32d1100f7c3a8cff5f04c513b845c14240de73cd..afd0b9e7df0a5d596b0aa7051eea25fa2b659d14 100644 (file)
@@ -55,6 +55,8 @@ Rule Specification:
 
   The "command" and "script" Rule Types allow the following the FSS-0001 (Extended)\:
     "kill": One or more Content representing a program being executed and its arguments.
+    "pause": One or more Content representing a program being executed and its arguments.
+    "resume": One or more Content representing a program being executed and its arguments.
     "restart": One or more Content representing a program being executed and its arguments.
     "reload": One or more Content representing a program being executed and its arguments.
     "start": One or more Content representing a program being executed and its arguments.
@@ -62,6 +64,8 @@ Rule Specification:
 
   The "command" and "service" Rule Types allow the following the FSS-0003 (Extended List)\:
     "kill": A list repesenting multiple programs and their respective arguments to execute.
+    "pause": A list repesenting multiple programs and their respective arguments to execute.
+    "resume": A list repesenting multiple programs and their respective arguments to execute.
     "restart": A list repesenting multiple programs and their respective arguments to execute.
     "reload": A list repesenting multiple programs and their respective arguments to execute.
     "start": A list repesenting multiple programs and their respective arguments to execute.
@@ -69,6 +73,8 @@ Rule Specification:
 
   The "script" Rule Types allow the following the FSS-0003 (Extended List)\:
     "kill": A list repesenting the contents of a (Bash) shell script.
+    "pause": A list repesenting the contents of a (Bash) shell script.
+    "resume": A list repesenting the contents of a (Bash) shell script.
     "restart": A list repesenting the contents of a (Bash) shell script.
     "reload": A list repesenting the contents of a (Bash) shell script.
     "start": A list repesenting the contents of a (Bash) shell script.