From 51ffbf2ac70c3a671c81d84d52acb42848348ec7 Mon Sep 17 00:00:00 2001 From: Nick Anderson Date: Tue, 20 Oct 2026 22:37:20 -0500 Subject: [PATCH] Documented the complete list of unsafe functions for --simulate mode The --simulate documentation mentioned "unsafe functions" but only gave execresult() as an example without listing all four unsafe functions. - Added a comprehensive table of all unsafe functions (execresult, execresult_as_data, returnszero, usemodule) to the --simulate section - Restructured the --simulate section with subheadings for clarity - Added a "Simulate mode" note to each of the four unsafe function reference pages linking back to the --simulate documentation - Noted that variables depending on unsafe functions will be unresolved unless simulate_safe is in the promise's meta attribute (cherry picked from commit 0aa225ff730049c96414e69a62b2bcbbaf5c55df) --- .../reference/components/cf-agent.markdown | 58 ++++++++++++------- .../reference/functions/execresult.markdown | 4 ++ .../functions/execresult_as_data.markdown | 4 ++ .../reference/functions/returnszero.markdown | 4 ++ .../reference/functions/usemodule.markdown | 5 ++ 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/content/reference/components/cf-agent.markdown b/content/reference/components/cf-agent.markdown index b21a798ae..6f3e2b6e7 100644 --- a/content/reference/components/cf-agent.markdown +++ b/content/reference/components/cf-agent.markdown @@ -29,13 +29,36 @@ affected by `common` and `agent` control bodies. Like the `--dry-run` option, the `--simulate` option tries to identify changes to your system without making changes to the system, however it goes further -than `--dry-run` by making changes in a `chroot` and making a distinction -between *safe* and *unsafe* functions, e.g. `execresult()`. +than `--dry-run` by making changes in a chroot and making a distinction +between _safe_ and _unsafe_ functions. -The agent will execute promises with unsafe functions when the `--simulate` -options is given only if the promise using the function is tagged `simulate_safe`. +#### Safe and unsafe functions -For example: +Functions that execute external commands or modules are considered _unsafe_ +because they may have side effects. In simulate mode, unsafe functions are +**skipped** and the agent logs a warning for each skipped call: + +``` +warning: Not calling unsafe function 'execresult' in simulate mode +``` + +The complete list of unsafe functions: + +| Function | Description | +| -------------------------------------------- | --------------------------------------------------------------------- | +| [`execresult()`][execresult] | Execute a command and return its output | +| [`execresult_as_data()`][execresult_as_data] | Execute a command and return exit code and output as a data container | +| [`returnszero()`][returnszero] | True if a command exits with status zero | +| [`usemodule()`][usemodule] | Execute a CFEngine module script | + +All other built-in functions are safe and are evaluated normally in simulate mode. + +#### Allowing unsafe functions with `simulate_safe` + +If a promise uses an unsafe function but you know the command is read-only (no +side effects), you can add `simulate_safe` to the promise's +[`meta`][Promise types#meta] attribute to allow it to execute in simulate mode. +For example, this promise runs `execresult()` even in simulate mode: ```cf3 bundle agent __main__ @@ -47,25 +70,20 @@ bundle agent __main__ } ``` -The simulate option takes a parameter, `diff`, `manifest`, or `manifest-full` -which is used to determine the summary output shown at the end of the run. +#### Simulate output modes -* `diff` - Show only things that changed during the simulated run. -* `manifest` - Show files and packages changed by the simulated run. -* `manifest-full` - Show all files evaluated by the simulated run (including unchanged ones) +The simulate option takes a parameter which is used to determine the summary +output shown at the end of the run. - - cf-agent can now simulate the changes done to files in a chroot, printing - diff or manifest information about what it would do in a normal evaluation. - Use the new command line option: `--simulate=diff` or `--simulate=manifest`. - Please note that only files and packages promises are simulated currently. - - - Added a new --simulate=manifest-full mode - New simulation mode that manifests all changed files as well as - all other files evaluated by the agent run which were not skipped - (by file selection rules) (CFE-3506) +- `--simulate=diff` - Show only things that changed during the simulated run. +- `--simulate=manifest` - Show files and packages changed by the simulated run. +- `--simulate=manifest-full` - Show all files evaluated by the simulated run (including unchanged ones). #### Notes -* Supported on Linux for `files` and `packages` type promises + +- Supported on Linux for `files` and `packages` type promises. +- Variables that depend on unsafe functions will be unresolved unless the + promise has `simulate_safe` in its [`meta`][Promise types#meta] attribute. #### History * Introduced in version 3.17.0 diff --git a/content/reference/functions/execresult.markdown b/content/reference/functions/execresult.markdown index fb02dd57d..f18b60c1d 100644 --- a/content/reference/functions/execresult.markdown +++ b/content/reference/functions/execresult.markdown @@ -47,6 +47,10 @@ highly undesirable if the command is expensive. Consider using `commands` promises instead, which have locking and are not evaluated by `cf-promises`. +**Simulate mode:** This function is [_unsafe_][cf-agent#Safe and unsafe functions] +and is skipped in `--simulate` mode unless the promise has `simulate_safe` in +its [`meta`][Promise types#meta] attribute. + **See also:** [`returnszero()`][returnszero], [`execresult_as_data()`][execresult_as_data]. **History:** diff --git a/content/reference/functions/execresult_as_data.markdown b/content/reference/functions/execresult_as_data.markdown index 4b27b4ce4..9651d776b 100644 --- a/content/reference/functions/execresult_as_data.markdown +++ b/content/reference/functions/execresult_as_data.markdown @@ -30,6 +30,10 @@ make changes to the system, or perform lengthy computations. Consider using `commands` promises instead, which have locking and are not evaluated by `cf-promises`. +**Simulate mode:** This function is [_unsafe_][cf-agent#Safe and unsafe functions] +and is skipped in `--simulate` mode unless the promise has `simulate_safe` in +its [`meta`][Promise types#meta] attribute. + **See also:** [`execresult()`][execresult]. **History:** diff --git a/content/reference/functions/returnszero.markdown b/content/reference/functions/returnszero.markdown index 4649f66bd..572256cf1 100644 --- a/content/reference/functions/returnszero.markdown +++ b/content/reference/functions/returnszero.markdown @@ -35,4 +35,8 @@ highly undesirable if the command is expensive. Consider using `commands` promises instead, which have locking and are not evaluated by `cf-promises`. +**Simulate mode:** This function is [_unsafe_][cf-agent#Safe and unsafe functions] +and is skipped in `--simulate` mode unless the promise has `simulate_safe` in +its [`meta`][Promise types#meta] attribute. + **See also:** `execresult()`. diff --git a/content/reference/functions/usemodule.markdown b/content/reference/functions/usemodule.markdown index 83557d37c..57d4ab787 100644 --- a/content/reference/functions/usemodule.markdown +++ b/content/reference/functions/usemodule.markdown @@ -31,4 +31,9 @@ bundle agent test "/bin/echo" args => "test $(user)"; } ``` + +**Simulate mode:** This function is [_unsafe_][cf-agent#Safe and unsafe functions] +and is skipped in `--simulate` mode unless the promise has `simulate_safe` in +its [`meta`][Promise types#meta] attribute. + **See also:** [read_module_protocol()][read_module_protocol], [Module Protocol][commands#module]