]> Kevux Git Server - fll/commitdiff
Update: The "engine" rule setting should support parameters.
authorKevin Day <thekevinday@gmail.com>
Tue, 5 Jul 2022 15:34:35 +0000 (10:34 -0500)
committerKevin Day <thekevinday@gmail.com>
Tue, 5 Jul 2022 15:34:35 +0000 (10:34 -0500)
level_3/controller/c/common/private-rule.c
level_3/controller/c/common/private-rule.h
level_3/controller/c/rule/private-rule.c
level_3/controller/documents/rule.txt
level_3/controller/specifications/rule.txt

index ecd60b1b4a6b1ed1ba54c69a913f88155f0fc6e9..b25b9d3d0b7105d7b3aa9861626ad00528572fee 100644 (file)
@@ -64,6 +64,7 @@ extern "C" {
     f_string_maps_resize(0, &rule->define);
     f_string_maps_resize(0, &rule->parameter);
 
+    f_string_dynamics_resize(0, &rule->engine_arguments);
     f_string_dynamics_resize(0, &rule->environment);
 
     macro_f_int32s_t_delete_simple(rule->affinity)
index d454a9239a500ced647be58efac2133d5a779467..fc955731043791f9eef4fc88521bb1eaa30aa298 100644 (file)
@@ -261,21 +261,22 @@ extern "C" {
  * A Rule.
  *
  * controller_rule_setting_type_*:
- *   - affinity:    Setting type representing a affinity.
- *   - capability:  Setting type representing a capability.
- *   - cgroup:      Setting type representing a control group.
- *   - define:      Setting type representing a define.
- *   - engine:      Setting type representing a engine.
- *   - environment: Setting type representing a environment.
- *   - group:       Setting type representing a group.
- *   - limit:       Setting type representing a limit.
- *   - name:        Setting type representing a name.
- *   - nice:        Setting type representing a nice.
- *   - on:          Setting type representing a on.
- *   - parameter:   Setting type representing a parameter.
- *   - path:        Setting type representing a path.
- *   - scheduler:   Setting type representing a scheduler.
- *   - user:        Setting type representing a user.
+ *   - affinity:         Setting type representing a affinity.
+ *   - capability:       Setting type representing a capability.
+ *   - cgroup:           Setting type representing a control group.
+ *   - define:           Setting type representing a define.
+ *   - engine:           Setting type representing a engine.
+ *   - engine_arguments: Setting type representing a engine.
+ *   - environment:      Setting type representing a environment.
+ *   - group:            Setting type representing a group.
+ *   - limit:            Setting type representing a limit.
+ *   - name:             Setting type representing a name.
+ *   - nice:             Setting type representing a nice.
+ *   - on:               Setting type representing a on.
+ *   - parameter:        Setting type representing a parameter.
+ *   - path:             Setting type representing a path.
+ *   - scheduler:        Setting type representing a scheduler.
+ *   - user:             Setting type representing a user.
  *
  * controller_rule_has_*:
  *   - cgroup:    Has type representing a control group.
@@ -284,30 +285,31 @@ extern "C" {
  *   - scheduler: Has type representing a scheduler.
  *   - user:      Has type representing a user.
  *
- * affinity:      The cpu affinity to be used when executing the Rule.
- * alias:         The distinct ID (machine name) of the Rule, such as "service/ssh".
- * capability:    The capability setting if the Rule "has" a capability.
- * cgroup:        The control group setting if the Rule "has" a control group.
- * define:        Any defines (environment variables) made available to the Rule for IKI substitution or just as environment variables.
- * engine:        The program or path to the program of the scripting engine to use when processing scripts in this Rule.
- * environment:   All environment variables allowed to be exposed to the Rule when processing.
- * group:         The group ID if the Rule "has" a group.
- * groups:        A set of group IDs to run the process with (first specified group is the primary group).
- * has:           Bitwise set of "has" codes representing what the Rule has.
- * items:         All items associated with the Rule.
- * limits:        The cpu/resource limits to use when executing the Rule.
- * name:          A human name for the Rule (does not have to be distinct), such as "Bash Script".
- * nice:          The niceness value if the Rule "has" nice.
- * on:            A set of parameters for defining dependencies and how they are needed, wanted, or wished for.
- * parameter:     Any parameters made available to the Rule for IKI substitution.
- * path:          The path to the Rule file.
- * scheduler:     The scheduler setting if the Rule "has" a scheduler.
- * status:        A set of action-specific success/failure status of the Rule. Each index represents a controller_rule_action_type_* enum value. Index 0 represents a global status.
- * timeout_kill:  The timeout to wait relating to using a kill signal.
- * timeout_start: The timeout to wait relating to starting a process.
- * timeout_stop:  The timeout to wait relating to stopping a process.
- * timestamp:     The timestamp when the Rule was loaded.
- * user:          The User ID if the Rule "has" a user.
+ * affinity:         The cpu affinity to be used when executing the Rule.
+ * alias:            The distinct ID (machine name) of the Rule, such as "service/ssh".
+ * capability:       The capability setting if the Rule "has" a capability.
+ * cgroup:           The control group setting if the Rule "has" a control group.
+ * define:           Any defines (environment variables) made available to the Rule for IKI substitution or just as environment variables.
+ * engine:           The program or path to the program of the scripting engine to use when processing scripts in this Rule.
+ * engine_arguments: Any arguments to pass to the engine program.
+ * environment:      All environment variables allowed to be exposed to the Rule when processing.
+ * group:            The group ID if the Rule "has" a group.
+ * groups:           A set of group IDs to run the process with (first specified group is the primary group).
+ * has:              Bitwise set of "has" codes representing what the Rule has.
+ * items:            All items associated with the Rule.
+ * limits:           The cpu/resource limits to use when executing the Rule.
+ * name:             A human name for the Rule (does not have to be distinct), such as "Bash Script".
+ * nice:             The niceness value if the Rule "has" nice.
+ * on:               A set of parameters for defining dependencies and how they are needed, wanted, or wished for.
+ * parameter:        Any parameters made available to the Rule for IKI substitution.
+ * path:             The path to the Rule file.
+ * scheduler:        The scheduler setting if the Rule "has" a scheduler.
+ * status:           A set of action-specific success/failure status of the Rule. Each index represents a controller_rule_action_type_* enum value. Index 0 represents a global status.
+ * timeout_kill:     The timeout to wait relating to using a kill signal.
+ * timeout_start:    The timeout to wait relating to starting a process.
+ * timeout_stop:     The timeout to wait relating to stopping a process.
+ * timestamp:        The timestamp when the Rule was loaded.
+ * user:             The User ID if the Rule "has" a user.
  */
 #ifndef _di_controller_rule_t_
   enum {
@@ -364,6 +366,7 @@ extern "C" {
     f_string_maps_t define;
     f_string_maps_t parameter;
 
+    f_string_dynamics_t engine_arguments;
     f_string_dynamics_t environment;
 
     f_int32s_t affinity;
@@ -410,6 +413,7 @@ extern "C" {
     f_string_maps_t_initialize, \
     f_string_maps_t_initialize, \
     f_string_dynamics_t_initialize, \
+    f_string_dynamics_t_initialize, \
     f_int32s_t_initialize, \
     f_capability_t_initialize, \
     f_control_group_t_initialize, \
index 1ca1958117d0a01bd2d2a53a84b782afd368f840..65b7adff86c4b75caf0736830ca64b5b3ae9c05a 100644 (file)
@@ -765,6 +765,7 @@ extern "C" {
 
     destination->alias.used = 0;
     destination->engine.used = 0;
+    destination->engine_arguments.used = 0;
     destination->name.used = 0;
     destination->path.used = 0;
 
@@ -778,13 +779,21 @@ extern "C" {
     destination->scheduler.policy = source.scheduler.policy;
     destination->scheduler.priority = source.scheduler.priority;
 
-    for (f_array_length_t i = 0; i < destination->ons.size; ++i) {
+    {
+      f_array_length_t i = 0;
 
-      destination->ons.array[i].action = 0;
-      destination->ons.array[i].need.used = 0;
-      destination->ons.array[i].want.used = 0;
-      destination->ons.array[i].wish.used = 0;
-    } // for
+      for (; i < destination->ons.size; ++i) {
+
+        destination->ons.array[i].action = 0;
+        destination->ons.array[i].need.used = 0;
+        destination->ons.array[i].want.used = 0;
+        destination->ons.array[i].wish.used = 0;
+      } // for
+
+      for (i = 0; i < destination->engine_arguments.size; ++i) {
+        destination->engine_arguments.array[i].used = 0;
+      } // for
+    }
 
     destination->ons.used = 0;
     destination->items.used = 0;
@@ -809,6 +818,9 @@ extern "C" {
     status = f_string_maps_append_all(source.parameter, &destination->parameter);
     if (F_status_is_error(status)) return status;
 
+    status = f_string_dynamics_append_all(source.engine_arguments, &destination->engine_arguments);
+    if (F_status_is_error(status)) return status;
+
     status = f_string_dynamics_append_all(source.environment, &destination->environment);
     if (F_status_is_error(status)) return status;
 
@@ -1128,10 +1140,10 @@ extern "C" {
 
           do {
             if (process->rule.engine.used) {
-              status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.engine, arguments_none, options, &execute_set, process);
+              status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.engine, process->rule.engine_arguments, options, &execute_set, process);
             }
             else {
-              status = controller_rule_execute_foreground(process->rule.items.array[i].type, *global.main->default_engine, arguments_none, options, &execute_set, process);
+              status = controller_rule_execute_foreground(process->rule.items.array[i].type, *global.main->default_engine, process->rule.engine_arguments, options, &execute_set, process);
             }
 
             if (status == F_child || F_status_set_fine(status) == F_lock) break;
@@ -1207,7 +1219,7 @@ extern "C" {
             }
 
             do {
-              status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, process->rule.engine.used ? process->rule.engine : *global.main->default_engine, arguments_none, options, process->rule.items.array[i].with, &execute_set, process);
+              status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, process->rule.engine.used ? process->rule.engine : *global.main->default_engine, process->rule.engine_arguments, options, process->rule.items.array[i].with, &execute_set, process);
 
               if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break;
               if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break;
@@ -1362,10 +1374,9 @@ extern "C" {
       }
 
       if (F_status_set_fine(status) != F_interrupt) {
-        const f_string_statics_t simulated_arguments = f_string_statics_t_initialize;
         fl_execute_parameter_t simulated_parameter = macro_fl_execute_parameter_t_initialize(execute_set->parameter.option, execute_set->parameter.wait, process->rule.has & controller_rule_has_environment_d ? execute_set->parameter.environment : 0, execute_set->parameter.signals, &f_string_empty_s);
 
-        status = fll_execute_program(*main->default_engine, simulated_arguments, &simulated_parameter, &execute_set->as, (void *) &result);
+        status = fll_execute_program(*main->default_engine, process->rule.engine_arguments, &simulated_parameter, &execute_set->as, (void *) &result);
       }
     }
     else {
@@ -3480,10 +3491,6 @@ extern "C" {
 
     bool for_item = F_true;
 
-    for (f_array_length_t i = 0; i < controller_rule_action_type__enum_size_e; ++i) {
-      rule->status[i] = F_known_not;
-    } // for
-
     rule->timeout_kill = entry->timeout_kill ? entry->timeout_kill : 0;
     rule->timeout_start = entry->timeout_start ? entry->timeout_start : 0;
     rule->timeout_stop = entry->timeout_stop ? entry->timeout_stop : 0;
@@ -3497,6 +3504,7 @@ extern "C" {
 
     rule->alias.used = 0;
     rule->engine.used = 0;
+    rule->engine_arguments.used = 0;
     rule->name.used = 0;
     rule->path.used = 0;
 
@@ -3511,10 +3519,6 @@ extern "C" {
       rule->capability = 0;
     }
 
-    for (f_array_length_t i = 0; i < rule->cgroup.groups.size; ++i) {
-      rule->cgroup.groups.array[i].used = 0;
-    } // for
-
     rule->cgroup.as_new = F_false;
     rule->cgroup.path.used = 0;
     rule->cgroup.groups.used = 0;
@@ -3527,12 +3531,6 @@ extern "C" {
     rule->scheduler.policy = 0;
     rule->scheduler.priority = 0;
 
-    for (f_array_length_t i = 0; i < rule->ons.size; ++i) {
-      rule->ons.array[i].need.used = 0;
-      rule->ons.array[i].want.used = 0;
-      rule->ons.array[i].wish.used = 0;
-    } // for
-
     rule->ons.used = 0;
     rule->items.used = 0;
 
@@ -3549,10 +3547,6 @@ extern "C" {
     cache->buffer_item.used = 0;
     cache->buffer_path.used = 0;
 
-    for (f_array_length_t i = 0; i < cache->content_items.used; ++i) {
-      cache->content_items.array[i].used = 0;
-    } // for
-
     cache->content_items.used = 0;
     cache->object_items.used = 0;
 
@@ -3560,6 +3554,32 @@ extern "C" {
     cache->action.name_file.used = 0;
     cache->action.name_item.used = 0;
 
+    {
+      f_array_length_t i = 0;
+
+      for (i = 0; i < rule->cgroup.groups.size; ++i) {
+        rule->cgroup.groups.array[i].used = 0;
+      } // for
+
+      for (; i < controller_rule_action_type__enum_size_e; ++i) {
+        rule->status[i] = F_known_not;
+      } // for
+
+      for (i = 0; i < cache->content_items.used; ++i) {
+        cache->content_items.array[i].used = 0;
+      } // for
+
+      for (i = 0; i < rule->engine_arguments.size; ++i) {
+        rule->engine_arguments.array[i].used = 0;
+      } // for
+
+      for (i = 0; i < rule->ons.size; ++i) {
+        rule->ons.array[i].need.used = 0;
+        rule->ons.array[i].want.used = 0;
+        rule->ons.array[i].wish.used = 0;
+      } // for
+    }
+
     status = f_string_dynamic_append_nulless(alias, &rule->alias);
 
     if (F_status_is_error(status)) {
@@ -4422,8 +4442,8 @@ extern "C" {
           setting_value = &rule->engine;
         }
 
-        if (setting_value->used || cache->content_actions.array[i].used != 1) {
-          controller_rule_setting_read_print_error(global.main->error, "requires exactly one Content", i, line_item, global.thread, cache);
+        if (setting_value->used || !cache->content_actions.array[i].used) {
+          controller_rule_setting_read_print_error(global.main->error, "requires one or more Content", i, line_item, global.thread, cache);
 
           if (F_status_is_error_not(status_return)) {
             status_return = F_status_set_error(F_valid_not);
@@ -4435,9 +4455,28 @@ extern "C" {
         if (type == controller_rule_setting_type_name_e || type == controller_rule_setting_type_engine_e) {
           status = fl_string_dynamic_partial_rip_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], setting_value);
 
+          if (type == controller_rule_setting_type_engine_e) {
+            rule->engine_arguments.used = 0;
+
+            if (cache->content_actions.array[i].used > 1) {
+              status = f_string_dynamics_increase_by(cache->content_actions.array[i].used - 1, &rule->engine_arguments);
+
+              for (j = 1; F_status_is_error_not(status) && j < cache->content_actions.array[i].used; ++j, ++rule->engine_arguments.used) {
+
+                rule->engine_arguments.array[rule->engine_arguments.used].used = 0;
+
+                status = f_string_dynamic_partial_append(cache->buffer_item, cache->content_actions.array[i].array[j], &rule->engine_arguments.array[rule->engine_arguments.used]);
+              } // for
+            }
+          }
+
           if (F_status_is_error(status)) {
             setting_value->used = 0;
 
+            if (type == controller_rule_setting_type_engine_e) {
+              rule->engine_arguments.used = 0;
+            }
+
             if (F_status_set_fine(status) == F_memory_not) {
               status_return = status;
 
@@ -4448,7 +4487,7 @@ extern "C" {
               status_return = status;
             }
 
-            // get the current line number within the settings item.
+            // Get the current line number within the settings item.
             cache->action.line_item = line_item;
             f_fss_count_lines(state, cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item);
 
@@ -4464,7 +4503,7 @@ extern "C" {
           if (status == F_false || F_status_set_fine(status) == F_complete_not_utf) {
             if (global.main->error.verbosity != f_console_verbosity_quiet_e) {
 
-              // get the current line number within the settings item.
+              // Get the current line number within the settings item.
               cache->action.line_item = line_item;
               f_fss_count_lines(state, cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item);
 
@@ -5614,7 +5653,21 @@ extern "C" {
     f_print_dynamic_raw(f_string_eol_s, main->output.to.stream);
 
     // Engine.
-    fl_print_format("  %[%r%] %Q%r", main->output.to.stream, main->context.set.important, controller_engine_s, main->context.set.important, rule.engine, f_string_eol_s);
+    if (rule.engine_arguments.used) {
+      fl_print_format("  %[%r%] %Q", main->output.to.stream, main->context.set.important, controller_engine_s, main->context.set.important, rule.engine);
+
+      for (i = 0; i < rule.engine_arguments.used; ++i) {
+
+        if (rule.engine_arguments.array[i].used) {
+          fl_print_format(" %Q", main->output.to.stream, rule.engine_arguments.array[i]);
+        }
+      } // for
+
+      fl_print_format("%r", main->output.to.stream, f_string_eol_s);
+    }
+    else {
+      fl_print_format("  %[%r%] %Q%r", main->output.to.stream, main->context.set.important, controller_engine_s, main->context.set.important, rule.engine, f_string_eol_s);
+    }
 
     // User.
     fl_print_format("  %[%r%]", main->output.to.stream, main->context.set.important, controller_user_s, main->context.set.important);
index 4c6040dae496268037a23213d86f0e4ea777c732..be2c1b26e9be0c396b5fb9ea01207b415ea18721 100644 (file)
@@ -49,6 +49,7 @@ Rule Documentation:
   - In the case of "engine"\:
     This engine is used for both "script" and "utility" Rule Types.
     The program that engine refers to must accept a standard input pipe to be supported.
+    Additional parameters may be passed to the engine.
 
   - In the case of "group" and "user"\:
     Only users and groups that the user the controller program is being run as is allowed to use may be used.
index b4b52d7473297c486227cc23311f461bbf429f99..e1490bb19da89ab69b8e62a2b304eafbabfeff11 100644 (file)
@@ -36,7 +36,7 @@ Rule Specification:
     - "capability": One Content representing capabilities.
     - "cgroup": Two or more Content, the first Content being either "existing" or "new" and the remaining representing a valid cgroup (control group) name, must have at least 1 graph character (non white space printing character) (leading and trailing white space are trimmed off).
     - "define": Two Content, the first Content must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits).
-    - "engine": One Content representing a valid program name or path (such as "bash" or "/bin/bash").
+    - "engine": One or more Content representing a valid program name or path (such as "bash" or "/bin/bash") and any optional arguments.
     - "environment": Zero or more Content, each must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits).
     - "group": One or more Content representing group names or group ids.
     - "limit": Three Content, with the first representing a valid resource type and the second and third being a valid resource limit number (positive whole number or 0).