### The following bodies were plucked from the standard library. They have been ### prefixed with =u_=. body classes u_results(scope, class_prefix) # @brief Define classes prefixed with `class_prefix` and suffixed with # appropriate outcomes: _kept, _repaired, _not_kept, _error, _failed, # _denied, _timeout, _reached # # @param scope The scope in which the class should be defined (`bundle` or `namespace`) # @param class_prefix The prefix for the classes defined # # This body can be applied to any promise and sets global # (`namespace`) or local (`bundle`) classes based on its outcome. For # instance, with `class_prefix` set to `abc`: # # * if the promise is to change a file's owner to `nick` and the file # was already owned by `nick`, the classes `abc_reached` and # `abc_kept` will be set. # # * if the promise is to change a file's owner to `nick` and the file # was owned by `adam` and the change succeeded, the classes # `abc_reached` and `abc_repaired` will be set. # # This body is a simpler, more consistent version of the body # `scoped_classes_generic`, which see. The key difference is that # fewer classes are defined, and only for outcomes that we can know. # For example this body does not define "OK/not OK" outcome classes, # since a promise can be both kept and failed at the same time. # # It's important to understand that promises may do multiple things, # so a promise is not simply "OK" or "not OK." The best way to # understand what will happen when your specific promises get this # body is to test it in all the possible combinations. # # **Suffix Notes:** # # * `_reached` indicates the promise was tried. Any outcome will result # in a class with this suffix being defined. # # * `_kept` indicates some aspect of the promise was kept # # * `_repaired` indicates some aspect of the promise was repaired # # * `_not_kept` indicates some aspect of the promise was not kept. # error, failed, denied and timeout outcomes will result in a class # with this suffix being defined # # * `_error` indicates the promise repair encountered an error # # * `_failed` indicates the promise failed # # * `_denied` indicates the promise repair was denied # # * `_timeout` indicates the promise timed out # # **Example:** # # ```cf3 # bundle agent example # { # commands: # "/bin/true" # classes => results("bundle", "my_class_prefix"); # # reports: # my_class_prefix_kept:: # "My promise was kept"; # # my_class_prefix_repaired:: # "My promise was repaired"; # } # ``` # # **See also:** `scope`, `scoped_classes_generic`, `classes_generic` { scope => "$(scope)"; promise_kept => { "$(class_prefix)_reached", "$(class_prefix)_kept" }; promise_repaired => { "$(class_prefix)_reached", "$(class_prefix)_repaired" }; repair_failed => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_failed" }; repair_denied => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_denied" }; repair_timeout => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_timeout" }; } body depth_search u_cfe_internal_recurse(d) # @brief Search for files recursively to a depth of `d` across file system boundaries # @param d Number of levels deep to traverse { depth => "$(d)"; xdev => "true"; } body classes u_kept_successful_command_results(scope, class_prefix) # @brief Set command to "kept" instead of "repaired" if it returns 0 and define # classes suffixed with the appropriate outcomes. # # @param scope The scope in which the class should be defined (`bundle` or `namespace`) # @param class_prefix The prefix for the classes defined # # **See also:** `scope`, `scoped_classes_generic`, `classes_generic`, `results` { inherit_from => u_results( "$(scope)", "$(class_prefix)" ); kept_returncodes => { "0" }; failed_returncodes => { "1" }; } body service_method u_systemd_services # @brief Define service method for systemd { service_autostart_policy => "none"; service_dependence_chain => "ignore"; service_type => "generic"; service_args => ""; } bundle agent u_systemd_services(service,state) # @brief Manage standard systemd services # @param service The name of the service # @param state The desired state the service should be in. { vars: # We explicitly guard for systemd to avoid unnecessary agent time in # pre-eval systemd:: "systemctl" string => "/bin/systemctl"; "call_systemctl" string => "$(systemctl) --no-ask-password --global --system"; "systemd_properties" string => "-pLoadState,CanStop,UnitFileState,ActiveState,LoadState,CanStart,CanReload"; "systemd_service_info" slist => string_split(execresult("$(call_systemctl) $(systemd_properties) show $(service)", "noshell"), "\n", "10"); classes: systemd:: # define a class named after the desired state "$(state)" expression => "any"; "non_disabling" or => { "start", "stop", "restart", "reload" }; # A collection of classes to determine the capabilities of a given systemd # service, then start, stop, etc. the service. Also supports a custom action # for anything not supported "service_enabled" expression => reglist(@(systemd_service_info), "UnitFileState=enabled"); "service_active" expression => reglist(@(systemd_service_info), "ActiveState=active"); "service_loaded" expression => reglist(@(systemd_service_info), "LoadState=loaded"); "service_notfound" expression => reglist(@(systemd_service_info), "LoadState=not-found"); "can_stop_service" expression => reglist(@(systemd_service_info), "CanStop=yes"); "can_start_service" expression => reglist(@(systemd_service_info), "CanStart=yes"); "can_reload_service" expression => reglist(@(systemd_service_info), "CanReload=yes"); "request_start" expression => strcmp("start", "$(state)"); "request_stop" expression => strcmp("stop", "$(state)"); "request_reload" expression => strcmp("reload", "$(state)"); "request_restart" expression => strcmp("restart", "$(state)"); "action_custom" expression => "!(request_start|request_stop|request_reload|request_restart)"; "action_start" expression => "request_start.!service_active.can_start_service"; "action_stop" expression => "request_stop.service_active.can_stop_service"; "action_reload" expression => "request_reload.service_active.can_reload_service"; "action_restart" or => { "request_restart", # Possibly undesirable... if a reload is # requested, and the service "can't" be # reloaded, then we restart it instead. "request_reload.!can_reload_service.service_active", }; # Starting a service implicitly enables it "action_enable" expression => "request_start.!service_enabled"; # Respectively, stopping it implicitly disables it "action_disable" expression => "request_stop.service_enabled"; commands: systemd.service_loaded:: # note this class is defined in `inventory/linux.cf` # conveniently, systemd states map to `services` states, except # for `enable` "$(call_systemctl) -q start $(service)" if => "action_start"; "$(call_systemctl) -q stop $(service)" if => "action_stop"; "$(call_systemctl) -q reload $(service)" if => "action_reload"; "$(call_systemctl) -q restart $(service)" if => "action_restart"; "$(call_systemctl) -q enable $(service)" if => "action_enable"; "$(call_systemctl) -q disable $(service)" if => "action_disable"; # Custom action for any of the non-standard systemd actions such a # status, try-restart, isolate, et al. "$(call_systemctl) $(state) $(service)" if => "action_custom"; reports: DEBUG|DEBUG_u_systemd_service:: "DEBUG $(this.bundle): using systemd layer to $(state) $(service)"; "DEBUG $(this.bundle): Service $(service) unit file is not loaded; doing nothing" if => "systemd.!service_loaded"; "DEBUG $(this.bundle): Could not find service: $(service)" if => "systemd.service_notfound"; } body perms u_mog(mode,user,group) # @brief Set the file's mode, owner and group # @param mode The new mode # @param user The username of the new owner # @param group The group name { owners => { "$(user)" }; groups => { "$(group)" }; mode => "$(mode)"; #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end }