files
Files promises manage all aspects of files. Presence, absence, file content, permissions, and ownership. File content can be fully or partially managed.
Examples
Creating a file with content
bundleagent__main__{files:"/tmp/hello"content=>"Hello, CFEngine";}Before making changes to the system, CFEngine will check what the current state is, and whether it matches the desired state.In this case, CFEngine will create and edit the file only if necessary. If/tmp/hello already exists with the correct content, no changes are made.
Tip: In this and other examples, we use the__main__ bundle.This allows you to easily run a policy file directly.In the real world, when incorporating policy into your policy set, you will want to pick a descriptive and unique bundle name, and ensure this bundle is evaluated by including it in thebundlesequence.
Overwriting the contents of a file only if it exists
Building on the previous example, we can add theif attribute to make CFEngine only edit the file if it exists.
bundleagent__main__{files:"/tmp/hello"content=>"Hello, CFEngine",if=>fileexists("/tmp/hello");}In the example above,fileexists() is a built-in function call.There are many others available to use, see:Functions.
On specific platforms, ensure a file exists by creating it if necessary
bundleagent__main__{files:ubuntu_18|ubuntu_20::"/tmp/hello"create=>"true";}The line withubuntu_18|ubuntu_20:: is called a class guard - it means the promise will only be evaluated if theubuntu_18 orubuntu_20 class is defined.We can say that this defines the context where the promise is relevant.This is similar to how we usedif above.In class guards you cannot have function calls, so they are typically used for more static / high level conditions, such as operating system, machine role, environment, or classes which have already been defined earlier in your policy set.Then, theif attribute can be used for more advanced conditions with function calls, for example checking if a file exists, comparing strings, or even looking at the output of a shell command.
Using the output of another function or shell command
The with attribute and variable expansion allows you to easily store the output of a function in a temporary variable, which you can then expand inside content, or other strings within the same promise:
bundleagent__main__{files:"/tmp/hello"content=>"Output of uname:$(with)",with=>execresult("uname","useshell");}Tip: Shell commands come with their own security risks and performance implications.Whenever you run shell commands within CFEngine policy, usingexecresult(),returnszero(), orcommands promises, be careful what data actually gets sent to the shell, you may want to limit or sanitize that data depending on where it comes from.You should also consider whether you can achieve the same result without shell commands, using built in CFEngine promise types and functions, which is generally preferable.
File copying
Copying is 'backwards'. Instead of the default object being source and theoption being the destination, in CFEngine 3 the destination is paramountand the source is an option. This is because the model of voluntarycooperation tells us that it is the object that is changed, which is theagent making the promise. One cannot force change onto a destinationwith CFEngine, one can only invite change from a source.
Normal ordering of promise attributes
CFEngine has no 'action sequence'. Ordering of operationshas, in most cases, a natural ordering that is assumed by the agent. Forexample, 'delete then create' (normal ordering) makes sense, but'create then delete' does not. This sort of principle can be extendedto deal with all aspects of file promises.
The diagram below shows the ordering. Notice that the same orderingapplies regardless of file type (plain-file or directory). Note alsothat file editing is done "atomically".

The pseudo-code for this logic is shown in the diagram and below:
foreachfilepromise-object{if(depth_search)doDepthSearch(HandleLeaf)else(HandleLeaf)done}HandleLeaf(){Doesleaf-fileexist?NO:createYES:rename,delete,touch,doforallserversin{localhost,@(servers)}{if(server-will-provide)doif(depth_search)embeddedsource-depth-search(usefilesource)breakelse(usefilesource)breakdonedone}doneDoalllinks(alwayslocal)CheckPermissionsDoedits}Depth searches (aka 'recursion') during searches
Recursion is called "depth-search", and CFEngine uses the 'globbing' symbolswith standard regular expressions:
/one/.*/two/thr.*/fourWhen searching for hidden files (files with names starting with a'.') or files with specific extensions, you should take care to escapethe dot (e.g.,\.cshrc or.*\.txt) when you wish it to mean aliteral character and not the any character interpretation provided byregular expression interpretation.
When doing a recursive search, the files '.' and '..' are neverincluded in the matched files, even if the regular expression in theleaf_name specifically allows them.
The filename/dir/ect/ory/. is a special case to avoid ambiguity between filesand directories, especially in the case of creation (both with and without theexplicitcreate attribute). Using /. ensures that a regular file is notcreated when a directory is actually desired. If you really want to specify aregular expression that matches any single-character filename, use/dir/ect/ory/[\w\W] as your promise regular expression (you can't use/dir/ect/ory/[^/], see below for an explanation.
Depth search refers to a search for file objects that starts from theone or more matched base-paths as shown in the example above.
Filenames and regular expressions
CFEngine allows regular expressions within filenames, but only afterfirst doing some sanity checking to prevent some readily avoidableproblems. The biggest rule you need to know about filenames and regularexpressions is thatall regular expressions in filenames are boundedby directory separators, and that each component expression is anchoredbetween the directory separators. In other words, CFEngine splits up anyfile paths into its component parts, and then it evaluates any regularexpressions at a component-level.
What this means is that the path/tmp/gar.* will only match filenameslike/tmp/gar,/tmp/garbage and/tmp/garden. It willnot matchfilename like/tmp/gar/baz; because even though the.* in a regularexpression means "zero or more of any character", CFEngine restrictsthat to mean "zero or more of any characterin a path component".
Correspondingly, CFEngine also restricts where you can use the/character. For example, you cannot use it in a character class like[^/] or in a parenthesized or repeated regular expression component.
This means that regular expressions that include "optional directorycomponents" will not work. You cannot have a files promise to tidy thedirectory(/usr)?/tmp. Instead, you need to be more verbose and specify/usr/tmp|/tmp. Potentially more efficient would be a declarativeapproach. First, create anslist that contains both the strings/tmpand/usr/tmp and then allow CFEngine to iterate over the list.
This also means that the path/tmp/.*/something will match files suchas/tmp/abc/something or/tmp/xyzzy/something. However, even though thepattern.* means "zero or more of any character (except /)", CFEnginematches files bounded by directory separators. So even though thepathname/tmp//something is technically the same as the pathname/tmp/something, the regular expression/tmp/.*/something willnotmatch on the case of/tmp//something (or/tmp/something).
Promises involving regular expressions
CFEngine can only keep (or repair, or fail to keep) a promise on fileswhich actually exist. If you make a promise based on a wildcard match,then the promise is only ever attempted if the match succeeds. However,if you make a promise containing a recursive search that includes awildcard match, then the promise can be kept or repaired, provided thatthe directory specified in the promise exists. Consider the followingtwo examples, which assume that there first exist files named/tmp/gar,/tmp/garbage and/tmp/garden. Initially, the two promises look like theyshould do the same thing; but there is a subtle difference:
bundle agent foobaz{files: "/tmp/gar.*" delete => tidy, classes => if_ok("done");}body classes if_ok(x){ promise_repaired => { "$(x)" }; promise_kept => { "$(x)" };} | bundle agent foobaz{ files: "/tmp" delete => tidy, depth_search => recurse("0"), file_select => gars, classes => if_ok("done");}body file_select gars{leaf_name => { "gar.*" };file_result => "leaf_name";}body classes if_ok(x){ promise_repaired => { "$(x)" }; promise_kept => { "$(x)" };} |
In the first example, when the configuration containing this promise isfirst executed, any file starting with "gar" that exists in the/tmpdirectory will be removed, and the done class will be set. However, whenthe configuration is executed a second time, the pattern/tmp/gar.*will not match any files, and that promise will not even beattempted(and, consequently the done class willnot be set).
In the second example, when the configuration containing this promise isfirst executed, any file starting with "gar" that exists in the/tmpdirectory will also be removed, and the done class will also be set. Thesecond time the configuration is executed, however, the promise on the/tmp directory will still be executed (because/tmp of course stillexists), and the done classwill be set, because all files matchingthefile_select attribute have been deleted from that directory.
Local and remote searches
There are two distinct kinds of depth search:
- A local search over promiser agents.
- A remote search over provider agents.
When we arecopying orlinking to a file source, it is the searchover theremote source that drives the content of a promise (thepromise is a promise to use what the remote source provides). Ingeneral, the sources are on a different device to the images that makethe promises. For all other promises, we search over existing localobjects.
If we specify depth search together with copy of a directory, then theimplied remote source search is assumed, and it is made after the searchover local base-path objects has been made. If you mix complex promisebody operations in a single promise, this could lead to confusion aboutthe resulting behavior, and a warning is issued. In general it is notrecommended to mix searches without a full understanding of theconsequences, but this might occasionally be useful.
Depth search is not allowed withedit_line promises.
Platform notes
Platforms that support named sockets (basically all Unix systems, butnot Windows), may not work correctly when using afiles promise toalter such a socket. This is a known issue, documented inCFE-1782, andCFE-1830.
Attributes
Common attributes
Common attributes are available to all promise types. Full details for commonattributes can be found in theCommon promise attributes section ofthePromise types page. The common attributes are as follows:
action
classes
comment
depends_on
handle
if
unless
meta
with
acl
Type:body acl
See also:Common body attributes
History:
- perms body no longer required for base directory to be considered by files promise 3.7.5, 3.10.0
aces
Description:Native settings for access control entry are defined by 'aces'. POSIX ACL areavailable in CFEngine Community starting with 3.4.0. NTFS ACL are available inwith CFEngine Enterprise.
Type:slist
Allowed input range:((user|group):[^:]+:[-=+,rwx()dtTabBpcoD]*(:(allow|deny))?)|((all|mask):[-=+,rwx()]*(:(allow|deny))?)
Form of the permissions is as follows:
aces={"user:uid:mode[:perm_type]",...,"group:gid:mode[:perm_type]",...,"all:mode[:perm_type]"};userA valid username identifier for the system and cannot be empty. However,
usercan be set to*as a synonym for the entity that owns the filesystem object (e.g.user:*:r).Notes:
- The user id is not a valid alternative.
- This ACL isrequired when
acl_methodis set tooverwrite.
A valid user identifier for the system and cannot be empty. However,
uidcan be set to*as a synonym for the entity that owns the file systemobject (e.g.user:*:r).Note: The username is not a valid alternative.
groupA valid group identifier for the system and cannot be empty. However,
groupcan be set to*as a synonym for the group that owns the POSIXfile system object (group:*:rwx).Notes:
- The group id is not a valid alternative.
- This ACL isrequired when
acl_methodis set tooverwrite.
gidA valid group identifier for the system and cannot be empty. However, insome ACL types,
gidcan be set to*to indicate a special group (e.g. inPOSIX this refers to the file group).Note: The group name is not a valid alternative.
allIndicates that the line applies to every user.
Note: This ACL isrequired when
acl_methodis set tooverwrite.maskA valid mask identifier (e.g.
mask:rwx). In essence the mask is an upperbound of the permissions that any entry in the group class will grant. Whenacl_methodisoverwriteif mask is not supplied, it will default tomask:rwx).One or more strings
op|perms|(nperms); a concatenation ofop,permsand optionally (nperms) separated with commas (e.g.+rx,-w(s)).modeis parsed from left to right.opSpecifies the operation on any existing permissions, if the defined ACEalready exists.
opcan be =, empty, + or -. = or empty sets thepermissions to the ACE as stated. + adds and - removes the permissions fromany existing ACE.nperms(optional)Specifies file system specific (native) permissions. Only valid if
acl_typeis defined and will only be enforced if the file object isstored on a file system supporting this ACL type. Forexample,npermswill be ignored ifacl_type:ntfsand the object isstored on a file system not supporting NTFS ACLs. Valid values fornpermsvaries with different ACL types. Whenacl_typeis set tontfs, thevalid flags and their mappings is as follows:CFEngine nperm flag NTFS Special Permission x Execute File / Traverse Folder r Read Data / List Folder t Read Attributes T Read Extended Attributes w Write Data / Create Files a Append Data / Create Folders b Write Attributes B Write Extended Attributes D Delete Sub-folders and Files d Delete p Read Permissions c Change Permissions o Take Ownership perm_type(optional)Can be set to either
allowordeny, and defaults toallow.denyisonly valid ifacl_typeis set to an ACL type that support denypermissions. AdenyACE will only be enforced if the file object is storedon a file system supporting the acl type set inacl_type.gperms(generic permissions)A concatenation of zero or more of the characters shown in the table below. Ifleft empty, none of the permissions are set.
Flag Description Semantics on file Semantics on directory r Read Read data, permissions, attributes Read directory contents, permissions, attributes w Write Write data Create, delete, rename subobjects x Execute Execute file Access subobjects Notes
- The
rpermission is not necessary to read an object's permissions andattributes in all file systems. For example, in POSIX, havingxon itscontaining directory is sufficient. - Capital
Xwhich is supported by thesetfaclcommand is notsupported by the acl library, and thus not supported by the acl body.
- The
Example:
bodyacltemplate{acl_method=>"overwrite";acl_type=>"posix";acl_default=>"access";aces=>{"user:*:r(wwx),-r:allow","group:*:+rw:allow","mask:x:allow","all:r"};}acl_default
Description: The access control list type for the affected file system is determined byacl_default.
Directories have ACLs associated with them, but they also have the ability toinherit an ACL to sub-objects created within them. POSIX calls the former ACLtype "access ACL" and the latter "default ACL", and we will use the sameterminology.
The constraintacl_default gives control over the default ACL ofdirectories. The default ACL can be left unchanged (nochange),empty (clear), or be explicitly specified (specify). In addition, thedefault ACL can be set equal to the directory's access ACL (access). Thishas the effect that child objects of the directory gets the same access ACL asthe directory.
Type: (menu option)
Allowed input range:
nochangeaccessspecifyclearExample:
bodyacltemplate{acl_method=>"overwrite";acl_type=>"posix";acl_default=>"access";aces=>{"user:*:rwx:allow","group:*:+rw:allow","mask:rx:allow","all:r"};}History: Was introduced in 3.5. Replaces the now deprecatedacl_directory_inherit.
acl_inherit
Description: Defines whether the object inherits its ACL from its parent.
Type: (menu option)
Allowed input range:
truefalseyesnoonoffnochange
Notes: This attribute has an effect only on Windows.
acl_method
Description: Theacl_method menu option defines the editing method foran access control list.
When defining an ACL, we can either use an existing ACL as the starting point,or state all entries of the ACL. If we just care about one entry, say that thesuperuser has full access, themethod constraint can be set toappend,which is the default. This has the effect that all the existing ACL entriesthat are not mentioned will be left unchanged. On the other hand, ifmethodis set tooverwrite, the resulting ACL will only contain the mentionedentries.
Note: Whenacl_method is set tooverwrite the aclmust include the systemowner, group and all. For exampleuser:*:rwx,group:*:rx, andall:---.
Type: (menu option)
Allowed input range:
appendoverwriteExample:
bodyacltemplate{acl_method=>"overwrite";acl_type=>"posix";aces=>{"user:*:rw:allow","group:*:+r:allow","all:"};}acl_type
Description: Theacl_type menu option defines the access control listtype for the affected file system.
ACLs are supported on multiple platforms, which may have different sets ofavailable permission flags. By using the constraintacl_type, wecan specify which platform, or ACL API, we are targeting with the ACL.
The default,generic, is designed to work on all supported platforms.However, if very specific permission flags are required, like TakeOwnership on the NTFS platform, we must setacl_type to indicate the targetplatform. Currently, the supported values areposix andntfs.
Type: (menu option)
Allowed input range:
genericposixntfsExample:
bodyacltemplate{acl_type=>"ntfs";aces=>{"user:Administrator:rwx(po)","user:Auditor:r(o)"};}specify_default_aces
Description: The slistspecify_default_aces specifies the nativesettings for access control entry.
specify_default_aces (optional) is a list of access control entries that areset on child objects. It is also parsed from left to right andallows multiple entries with same entity-type and id. Only valid ifacl_default is set tospecify.
This is an ACL which makes explicit setting for the acl inherited by newobjects within a directory. It is included for those implementationsthat do not have a clear inheritance policy.
Type:slist
Allowed input range:((user|group):[^:]+:[-=+,rwx()dtTabBpcoD]*(:(allow|deny))?)|((all|mask):[-=+,rwx()]*(:(allow|deny))?)
Example:
bodyacltemplate{specify_default_aces=>{"all:r"};}changes
Type:body changes
See also:Common body attributes
hash
Description: Thehash menu option defines the type of hash used for change detection.
Thebest option cross correlates the best two available algorithms known in the OpenSSL library.
Type: (menu option)
Allowed input range:
md5sha1sha224sha256sha384sha512bestExample:
bodychangesexample{hash=>"md5";}report_changes
Description: Specify criteria for change warnings using thereport_changes menu option.
Files can change in permissions and contents, i.e. external or internal attributes. If all is chosen all attributes are checked.
Type: (menu option)
Allowed input range:
allstatscontentnoneExample:
bodychangesexample{report_changes=>"content";}update_hashes
Description: Use ofupdate_hashes determines whether hash values shouldbe updated immediately after a change.
If this is positive, file hashes should be updated as soon as a change isregistered so that multiple warnings are not given about a single change. Thisapplies to addition and removal too.
Type:boolean
Example:
bodychangesexample{update_hashes=>"true";}report_diffs
This feature requires CFEngine Enterprise.
Description: Settingreport_diffs determines whether to generate reportssummarizing the major differences between individual text files.
If true, CFEngine will log a 'diff' summary of major changes to the files. Itis not permitted to combine this promise with a depth search, since this wouldconsume a dangerous amount of resources and would lead to unreadable reports.
The feature is intended as a informational summary, not as a version controlfunction suitable for transaction control. If you want to do versioning onsystem files, you should keep a single repository for them and use CFEngine tosynchronize changes from the repository source. Repositories should not beused to attempt to capture random changes of the system.
Limitations:Diffs will not be reported for files that are larger than 80MB in size.Diffs will not be reported if the number of lines between the first and last change exceed 4500.Diffs for binary files are not generated. Files are considered binary files ifcontrol character 0-32 excluding 9, 10, 13, and 32, or 127 are found in the file.
Type:boolean
Example:
bodychangesexample{report_diffs=>"true";}copy_from
Type:body copy_from
The copy_from body specifies the details for making remote copies.
Note: For improved performance, connections from cf-agent to cf-serverdare re-used. Currently connection caching is done per pass in each bundleactivation.
See also:Common body attributes
source
Description: Thesource string represents the reference source file from which to copy. For remote copies this refers to the file name on the remote server.
Type:string
Allowed input range:.+
Example:
bodycopy_fromexample{source=>"/path/to/source";}servers
Description: Theservers slist names servers in order of preference from which to copy. The servers are tried in order until one of them succeeds.
Type:slist
Allowed input range:[A-Za-z0-9_.:-]+
Example:
bodycopy_fromexample{servers=>{"primary.example.org","secondary.example.org","tertiary.other.domain"};}collapse_destination_dir
Description: Usecollapse_destination_dir to flatten the directory hierarchy during copy. All the files will end up in the root destination directory.
Under normal operations, recursive copies cause CFEngine to tracksubdirectories of files. So, for instance, if we copy recursively from src todest, thensrc/subdir/file will map todest/subdir/file.
By setting this option totrue, the promiser destination directory promises toaggregate files searched from all subdirectories intoitself; in other words, a single destination directory. Sosrc/subdir/file will map todest/file for anysubdir.
Type:boolean
Example:
bodycopy_frommycopy(from,server){source=>"$(from)";servers=>{"$(server)"};collapse_destination_dir=>"true";}compare
Description: The menu option policycompare is used for comparing sourceand image file attributes.
The default copy method ismtime (modification time) orctime (changetime), meaning that the source file is copied to the destination (promiser)file, if the source file has been modified (content, permissions, ownership,moved to a different file system) more recently than the destination. Note thisis special behavior when no comparison is specified as generally only a singlecomparison can be used.
Type: (menu option)
Allowed input range:
CFEngine copies the file if the modification time of the source file is morerecent than that of the promised file
CFEngine copies the file if the creation time of the source file is morerecent than that of the promised file
CFEngine copies the file if the modification time or creation time of thesource file is more recent than that of the promised file. If the times areequal, a byte-for-bye comparison is done on the files to determine if it needsto be copied.
exists
CFEngine copies the file if the promised file does not already exist.
binary
CFEngine copies the file if they are both plain files and abyte-for-byte comparison determines that they are different. If bothare not plain files, CFEngine reverts to comparing themtime andctime of the files. If the source file is on a different machine(e.g. network copy), thenhash is used instead to reduce networkbandwidth.
CFEngine copies the file if they are both plain files and amessage digest comparison indicates that the files are different. InEnterprise versions of CFEngine version 3.1.0 and later, SHA256 isused as a message digest hash to conform with FIPS; in olderEnterprise versions of CFEngine and all Community versions, MD5 isused.
digesta synonym forhash
Default value: mtime or ctime differs
Example:
bodycopy_fromexample{compare=>"digest";}copy_backup
Description: Menu option policy for file backup/version control
Determines whether a backup of the previous version is kept on the system.This should be viewed in connection with default_repository in body agent control, since adefined repository affects the location at which the backup is stored.
Type: (menu option)
Allowed input range:
truefalsetimestampDefault value: true
Example:
bodycopy_fromexample{copy_backup=>"timestamp";}See also:Common body attributes,default_repository inbody agent control,edit_backup inbody edit_defaults
encrypt
Description: Theencrypt menu option policy describes whether to useencrypted data stream to connect to remote hosts.
Client connections are encrypted with using a Blowfish randomly generatedsession key. The initial connection is encrypted using the public/private keysfor the client and server hosts.
Type:boolean
Default value: false
Example:
bodycopy_fromexample{servers=>{"remote-host.example.org"};encrypt=>"true";}Note: When used withprotocol_version 2 or greater this attribute is anoop as the entire session is encrypted.
See also:protocol_version,ifencrypted,protocol_version,tls_ciphers,tls_min_version,allowciphers,allowtlsversion
check_root
Description: Thecheck_root menu option policy checks permissions on theroot directory when copying files recursively by depth_search.
This flag determines whether the permissions of the root directory should beset from the root of the source. The default is to check only copied fileobjects and subdirectories within this root (false).
Type:boolean
Example:
bodycopy_fromexample{check_root=>"true";}copylink_patterns
Description: Thecopylink_patterns slist of patterns are matching filesthat should be copied instead of linked.
The matches are performed on the last node of the filename; in other words,the file without its path. As Windows does not support symbolic links, thisfeature is not available there.
Type:slist
Allowed input range: (arbitrary string)
Example:
bodycopy_fromexample{copylink_patterns=>{"special_node1","other_node.*"};}copy_size
Description: The integers specified incopy_size determines the rangefor the size of files that may be copied.
The use of theirange function is optional. Ranges may also be specified ascomma separated numbers.
Type:irange[int,int]
Allowed input range:0,inf
Default value: any size range
Example:
bodycopy_fromexample{copy_size=>irange("0","50000");}See also:Function: irange()
findertype
Description: Thefindertype menu option policy describes the default finder type on MacOSX.
This applies only to the Mac OS X variants.
Type: (menu option)
Allowed input range:
MacOSXExample:
bodycopy_fromexample{findertype=>"MacOSX";}linkcopy_patterns
Description: Thelinkcopy_patterns contains patterns for matching filesthat should be replaced with symbolic links.
The pattern matches the last node filename; in other words, without theabsolute path. Windows only supports hard links.
Type:slist
Allowed input range: (arbitrary string)
Example:
bodycopy_frommycopy(from){source=>"$(from)";linkcopy_patterns=>{".*"};}See also:link_type.
link_type
Description: Thelink_type menu option policy contains the type of linksto use when copying.
Users are advised to be wary of 'hard links' (see Unix manual pages for the lncommand). The behavior of non-symbolic links is often precarious andunpredictable. However, hard links are the only supported type by Windows.
Note that symlink is synonymous with absolute links, which are different fromrelative links. Although all of these are symbolic links, the nomenclaturehere is defined such that symlink and absolute are equivalent. When verifyinga link, choosing 'relative' means that the linkmust be relative to thesource, so relative and absolute links are mutually exclusive.
Type: (menu option)
Allowed input range:
symlinkhardlinkrelativeabsoluteDefault value: symlink
Example:
bodycopy_fromexample{link_type=>"symlink";source=>"/tmp/source";}missing_ok
Description: Treat a missing source file as a promise kept.
This allows you to override the promise outcome when a source file is missing.When set totrue if the promise is a remote copy and there is a failure toconnect the promise will not be considered kept. If the agent is able to requestthe file and the file is missing the promise will be kept.
Type:boolean
Default value: false
Example:
bundleagentmain{files:"/tmp/copied_from_missing_ok"copy_from=>missing_ok("/var/cfengine/masterfiles/missing"),classes=>results("bundle","copy_from_missing_ok");reports:"$(with)"with=>string_mustache("",sort(classesmatching("copy_from_.*"),lex));}bodycopy_frommissing_ok(file_path){source=>"$(file_path)";missing_ok=>"true";# Run with these classes to try remote copiesremote_copy_self::servers=>{"127.0.0.1"};remote_copy_policy_hub::servers=>{$(sys.policy_hub)};}bodyclassesresults(scope,class_prefix){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"};}In the above example/tmp/copied_from_missing_ok promises to be a copy of the local file/var/cfengine/masterfiles/missing. In themissing_okcopy_from bodymissing_ok is set to true. This causes the promise to be considered kept ifthe source file is missing. Theresults classes body is used to define bundlescoped classes prefixed withcopy_from_missing_ok. Thereports promiseoutputs a sorted list of the classes defined starting withcopy_from_.
R: [ "copy_from_missing_ok_kept", "copy_from_missing_ok_reached"]We can see in the output that the class defined for copying a local file thatdoes not exist is seen to be a promise kept.```
This policy can be found in/var/cfengine/share/doc/examples/missing_ok.cfand downloaded directly fromgithub.
Notes:
This can be useful for opportunistically coping files that are not necessarilyrequired or available at all times. For example if there is a host specific datathat each host attempts to copy this will allow you to not have many promisefailures when a host does not have any data prepared for it.
See also:seed_cp in the MPF,compare in bodycopy_from
History:
- Introduced in 3.12.0
force_update
Description: Theforce_update menu option policy instructs whether toalways force copy update.
Warning: this is a non-convergent operation. Although the end point mightstabilize in content, the operation will never quiesce. Use of this feature isnot recommended except in exceptional circumstances since it creates abusy-dependency. If the copy is a network copy, the system will be disturbedby network disruptions.
Type:boolean
Default value: false
Example:
bodycopy_fromexample{force_update=>"true";}force_ipv4
Description: Theforce_ipv4 menu option policy can determine whether to use ipv4 on an ipv6 enabled network.
IPv6 should be harmless to most users unless you have a partially or mis-configured setup.
Type:boolean
Default value: false
Example:
bodycopy_fromexample{force_ipv4=>"true";}portnumber
Description: Settingportnumber determines the port number to connect toon a server host.
The standard or registered port number is tcp/5308. CFEngine does notpresently use its registered udp port with the same number, but this couldchange in the future.
Type:int
Allowed input range:1,65535
Example:
bodycopy_fromexample{portnumber=>"5308";}preserve
Description: Setting thepreserve menu option policy determines whetherto preserve file permissions on copied files.
This ensures that the destination file (promiser) gets the same file permissions asthe source. For local copies, all attributes are preserved, including ACLs and SELinuxsecurity contexts. For remote copies, only Unix mode is preserved.
Note: This attribute will not preserve ownership (user/group).
Type:boolean
Default value: false
Example:
bodycopy_fromexample{preserve=>"true";}History: Version 3.1.0b3,Nova 2.0.0b1 (2010)
protocol_version
Description: Defines the protocol to use for the outgoing connection in thiscopy operation.
Type: (menu option)
Allowed input range:
1classic2tls3cookielatest
Default value: classic
Note: The value here will override the setting frombody common control.
See also:protocol_version inbody common,allowlegacyconnects
History: Introduced in CFEngine 3.6.0
purge
Description: Thepurge menu option policy instructs on whether to purgefiles on client that do not match files on server when adepth_search isused.
Purging files is a potentially dangerous matter during a file copy it impliesthat any promiser (destination) file which is not matched by a source will bedeleted. Since there is no source, this means the file will be irretrievable.Great care should be exercised when using this feature.
Note this attribute only works when combined withdepth_search and purgingwill also delete backup files generated during the file copying ifcopy_backupis set to true.
Type:boolean
Default value: false
Example:
bodycopy_fromexample{purge=>"true";}stealth
Description: Setting thestealth menu option policy determines whetherto preserve time stamps on copied files. This preserves file access andmodification times on the promiser files.
Type:boolean
Default value: false
Example:
bodycopy_fromexample{stealth=>"true";}timeout
Description: The integer set intimeout is the value for the connectiontimeout, in seconds.
Type:int
Allowed input range:1,3600
Default Value:default_timeout
Example:
bodycopy_fromexample{timeout=>"10";}See also:agentdefault_timeout,cf-runagent timeout
Notes:
cf-serverdwill time out any transfer that takes longer than 10 minutes(this is not currently tunable).
trustkey
Description: Thetrustkey menu option policy determines whether to trustpublic keys from a remote server, if previously unknown.
If the server's public key has not already been trusted,trustkey providesautomated key-exchange.
Note that, as a simple security precaution,trustkey should normally be setto false. Even though the risks to the client low, it is a good securitypractice to avoid key exchange with a server one is not one hundred percentsure about. On the server-side however, trust is often granted to many clientsor to a whole network in which possibly unauthorized parties might be able toobtain an IP address. Thus the trust issue is most important on the serverside.
As soon as a public key has been exchanged, the trust option has no effect. Amachine that has been trusted remains trusted until its key is manuallyrevoked by a system administrator. Keys are stored inWORKDIR/ppkeys.
Type:boolean
Default value: false
Example:
bodycopy_fromexample{trustkey=>"true";}type_check
Description: Thetype_check menu option policy compares file typesbefore copying.
File types at source and destination should normally match in order forupdates to overwrite them. This option allows this checking to be switchedoff.
Type:boolean
Example:
bodycopy_fromexample{type_check=>"false";}verify
Description: Theverify menu option policy instructs whether to verifytransferred file by hashing after copy.
Warning: This is a highly resource intensive option, and is notrecommended for large file transfers.
Type:boolean
Default value: false
Example:
bodycopy_fromexample{verify=>"true";}content
Description: Complete content the promised file should contain.
Type:string
Allowed input range: (arbitrary string)
Example:
bundleagentexample_file_content{vars:"my_content"string=>"Hello from var!";files:"/tmp/hello_string"create=>"true",content=>"Hello from string!";"/tmp/hello_var"create=>"true",content=>"$(my_content)";reports:"/tmp/hello_string"printfile=>cat($(this.promiser));"/tmp/hello_var"printfile=>cat($(this.promiser));}bodyprintfilecat(file){file_to_print=>"$(file)";number_of_lines=>"inf";}bundleagent__main__{methods:"example_file_content";}R: /tmp/hello_stringR: Hello from string!R: /tmp/hello_varR: Hello from var!This policy can be found in/var/cfengine/share/doc/examples/files_content.cfand downloaded directly fromgithub.
History: Was introduced in 3.16.0
Note: You cannotcontent in combination with the other edit operationslikeedit_line,edit_xml,edit_template oredit_template_string.
create
Description: true/false whether to create non-existing file
Directories are created by using the/. to signify a directory type.Note that, if no permissions are specified, mode 600 is chosen for afile, and mode 755 is chosen for a directory. If you cannot accept thesedefaults, youshould specify permissions.
Note that technically,/. is a regular expression. However, it is usedas a special case meaning "directory". Seefilenames and regularexpressions for a more complete discussion.
Type:boolean
Default value: false
Example:
files:"/path/plain_file"create=>"true";"/path/dir/."create=>"true";Notes: In general, you should not usecreate withcopy_from,link_from,template_method, orcontent attributes in files promises. These latterattributes automatically create the promised file, and usingcreate mayactually prevent the copy or link promise from being kept (sincecreate actsfirst, which may affect file comparison or linking operations). Furthermore, anexplicitly created file will be empty in the case of failure to render templateif thecreate attribute is explicitly used.
History:
- 3.20.0 Changed default from
falsetotruefor cases of full file management ( e.g. whentemplate_methodismustache,inline_mustacheorcfengine, or when thecontentorcopy_fromattributes are used ).
delete
Type:body delete
See also:Common body attributes
dirlinks
Description: Menu option policy for dealing with symbolic links todirectories during deletion
Links to directories are normally removed just like any other link orfile objects. By keeping directory links, you preserve the logicaldirectory structure of the file system, so that a link to a directory isnot removed but is treated as a directory to be descended into.
The valuekeep instructs CFEngine not to remove directory links. Thevaluesdelete andtidy are synonymous, and instruct CFEngine toremove directory links.
Type: (menu option)
Allowed input range:
deletetidykeepExample:
bodydeleteexample{dirlinks=>"keep";}Default value (only if body is present):dirlinks = delete
The default value only has significance if there is adelete bodypresent. If there is nodelete body then files (and directory links)arenot deleted.
rmdirs
Description: true/false whether to delete empty directories duringrecursive deletion
Type:boolean
Example:
bodydeleteexample{rmdirs=>"true";}Note the parent directory of a search is not deleted in recursive deletions. Youmust code a separate promise to delete the single parent object. This attribute does not respectinclude_basedir indepth_search bodies. For an exampleseebundle agent rm_rf_depth in the standard library.
Default value (only if body is present):rmdirs = true
The default value only has significance if there is adelete bodypresent. If there is nodelete body then files (and directories) arenot deleted.
depth_search
Description: Apply a promise recursively
When searching recursively from a directory, the promised directory itself is only the anchor point and is not part of the search by default. Setinclude_basedir totrue to include the promised directory in the search.
This should be used in combination withfile_select.
Type:body depth_search
See also:Common body attributes
depth
Description: Maximum depth level for search
Type:int
Allowed input range:0,99999999999
Note that the value inf may be used for an unlimited value.
Example:
bodydepth_searchexample{depth=>"inf";}exclude_dirs
Description: List of regexes of directory names NOT to include in depthsearch
Directory names are treated specially when searching recursively througha file system.
Type:slist
Allowed input range:.*
Example:
bodydepth_search{# no dot directoriesexclude_dirs=>{"\..*"};}include_basedir
Description: true/false include the start/root dir of the searchresults
When checking files recursively (withdepth_search) the promiser is adirectory. This parameter determines whether that initial directoryshould be considered part of the promise or simply a boundary that marksthe edge of the search. If true, the promiser directory will alsopromise the same attributes as the files inside it.rmdirs indelete bodies /ignore/ this attribute. A separate files promise must be made in order to delete the top level directory.
Type:boolean
Example:
rm -rf /tmp/CFE-3217mkdir -p /tmp/CFE-3217/test-delete-nobasedir/one/two/threemkdir -p /tmp/CFE-3217/test-delete/one/two/threemkdir -p /tmp/CFE-3217/test-perms/one/two/threemkdir -p /tmp/CFE-3217/test-perms-nobasedir/one/two/threetouch /tmp/CFE-3217/test-delete-nobasedir/one/two/three/filetouch /tmp/CFE-3217/test-delete/one/two/three/filetouch /tmp/CFE-3217/test-perms/one/two/three/filetouch /tmp/CFE-3217/test-perms-nobasedir/one/two/three/filetouch /tmp/CFE-3217/test-delete-nobasedir/filetouch /tmp/CFE-3217/test-delete/filetouch /tmp/CFE-3217/test-perms/filetouch /tmp/CFE-3217/test-perms-nobasedir/filebundleagentmain{files:"/tmp/CFE-3217/test-delete/."->{"CFE-3217","CFE-3218"}depth_search=>aggressive("true"),file_select=>all,delete=>tidy,comment=>"include_basedir=>'true'willnotresultinthdpromiseddirectorybeingremoved."; "/tmp/CFE-3217/test-delete-nobasedir/." depth_search => aggressive("false"), file_select => all, delete => tidy, comment => "include_basedir=>'false'willnotresultinthdpromiseddirectorybeingremoved."; "/tmp/CFE-3217/test-perms/." perms => m(555), depth_search => aggressive("true"), file_select => all, comment => "include_basedir=>'true'resultsinthdpromiseddirectoryhavingpermissionsmanagedaswell."; "/tmp/CFE-3217/test-perms-nobasedir/." -> { "CFE-3217" } perms => m(555), depth_search => aggressive("false"), file_select => all, comment => "include_basedir=>'false'resultsinthdpromiseddirectorynothavingpermissionsmanaged."; reports: "delete=>tidy"; "/tmp/CFE-3217/test-deletepresentdespiteinclude_basedir=>'true'" if => isdir("/tmp/CFE-3217/test-delete"); "/tmp/CFE-3217/test-delete-nobasedirpresentasexpectedwithinclude_basedir=>'false'" if => isdir("/tmp/CFE-3217/test-delete-nobasedir"); "/tmp/CFE-3217/test-deleteabsent,unexpectedly" unless => isdir("/tmp/CFE-3217/test-delete"); "/tmp/CFE-3217/test-delete-nobasedirabsent,unexpectedly" unless => isdir("/tmp/CFE-3217/test-delete-nobasedir"); "perms=>m(555)"; "/tmp/CFE-3217/test-perms$(with),asexpectedwithinclude_basedir=>'true'" with => filestat( "/tmp/CFE-3217/test-perms", modeoct ), if => strcmp( filestat( "/tmp/CFE-3217/test-perms", modeoct ), "40555" ); "/tmp/CFE-3217/test-perms-nobasedir$(with),not555,asexpectedwithinclude_basedir=>'false'" with => filestat( "/tmp/CFE-3217/test-perms-nobasedir", modeoct ), unless => strcmp( filestat( "/tmp/CFE-3217/test-perms-nobasedir", modeoct ), "40555" );}body depth_search aggressive(include_basedir){ depth => "inf"; # exclude_dirs => { @(exclude_dirs) }; include_basedir => "$(include_basedir)"; # include_dirs => { @(include_dirs) }; # inherit_from => "$(inherit_from)"; # meta => "$(meta)"; meta attribute inside the depth_search body? It's not documented. TODO!? rmdeadlinks => "false"; # Depth search removes dead links, this seems like something that should be in delete body. TODO!? traverse_links => "true"; xdev => "true";}Inlined bodies from the stdlib in the Masterfiles Policy Framework
bodyfile_selectall{leaf_name=>{".*"};file_result=>"leaf_name";}bodydeletetidy{dirlinks=>"delete";rmdirs=>"true";}bodypermsm(mode){mode=>"$(mode)";} info: Deleted file '/tmp/CFE-3217/test-delete/./one/two/three/file' info: Deleted directory '/tmp/CFE-3217/test-delete/./one/two/three' info: Deleted directory '/tmp/CFE-3217/test-delete/./one/two' info: Deleted directory '/tmp/CFE-3217/test-delete/./one' info: Deleted file '/tmp/CFE-3217/test-delete/./file' info: Deleted file '/tmp/CFE-3217/test-delete-nobasedir/./one/two/three/file' info: Deleted directory '/tmp/CFE-3217/test-delete-nobasedir/./one/two/three' info: Deleted directory '/tmp/CFE-3217/test-delete-nobasedir/./one/two' info: Deleted directory '/tmp/CFE-3217/test-delete-nobasedir/./one' info: Deleted file '/tmp/CFE-3217/test-delete-nobasedir/./file' info: Object '/tmp/CFE-3217/test-perms-nobasedir/./file' had permission 0664, changed it to 0555R: delete => tidyR: /tmp/CFE-3217/test-delete present despite include_basedir => 'true'R: /tmp/CFE-3217/test-delete-nobasedir present as expected with include_basedir => 'false'R: perms => m(555)R: /tmp/CFE-3217/test-perms 40555, as expected with include_basedir => 'true'R: /tmp/CFE-3217/test-perms-nobasedir 40775, not 555, as expected with include_basedir => 'false'This policy can be found in/var/cfengine/share/doc/examples/files_depth_search_include_basedir.cfand downloaded directly fromgithub.
See also:rm_rf,rm_rf_depth from the standard library.
include_dirs
Description: List of regexes of directory names to include in depthsearch
This is the complement ofexclude_dirs.
Type:slist
Allowed input range:.*
Example:
bodydepth_searchexample{include_dirs=>{"subdir1","subdir2","pattern.*"};}rmdeadlinks
Description: true/false remove links that point to nowhere
A value of true determines that links pointing to files that do notexist should be deleted; or kept if set to false.
Type:boolean
Default value: false
Example:
bodydepth_searchexample{rmdeadlinks=>"true";}traverse_links
Description: true/false traverse symbolic links to directories
If this is true,cf-agent will treat symbolic links to directories asif they were directories. Normally this is considered a potentiallydangerous assumption and links are not traversed.
Type:boolean
Default value: false
Example:
bodydepth_searchexample{traverse_links=>"true";}xdev
Description: Whentrue files and directories on different devices from the promiser will be excluded fromdepth_search results.
Type:boolean
Default value: false
Example:
bodydepth_searchexample{xdev=>"true";}edit_defaults
Type:body edit_defaults
See also:Common body attributes
edit_backup
Description: Menu option for backup policy on edit changes
Type: (menu option)
Allowed input range:
truefalsetimestamprotateDefault value: true
Example:
A value oftrue (the default behavior) will result in the agent retaining theprevious version of the file suffixed with.cf-before-edit.
bodyedit_defaultsbackup(edit_backup){edit_backup=>"$(edit_backup)";}bundleagentmain{files:"/tmp/example_edit_backup_true"create=>"true";"/tmp/example_edit_backup_true"edit_line=>insert_lines("Hello World"),edit_defaults=>backup("true");vars:"example_files"slist=>sort(lsdir("/tmp/","example_edit_backup_true.*",false),lex);reports:"$(example_files)";}Outputs:
R: example_edit_backup_trueR: example_edit_backup_true.cf-before-editA value oftimestamp will result in the original file be suffixed with theepoch and the canonified form of the date when the file was changed followed by.cf-before-edit. For example_1511292441_Tue_Nov_21_13_27_22_2017.cf-before-edit.
bodyedit_defaultsbackup(edit_backup){edit_backup=>"$(edit_backup)";}bundleagentmain{files:"/tmp/example_edit_backup_timestamp"create=>"true";"/tmp/example_edit_backup_timestamp"edit_line=>insert_lines("Hello World"),edit_defaults=>backup("timestamp");vars:"example_files"slist=>lsdir("/tmp/","example_edit_backup_timestamp.*",false);reports:"$(example_files)";}Outputs:
R: example_edit_backup_timestampR: example_edit_backup_timestamp_1511300904_Tue_Nov_21_15_48_25_2017.cf-before-editA value offalse will result in no retention of the original file.
A value ofrotate will result in the original file be suffixed with.cf-before-edit followed by an integer representing the nth previous versionof the file. The number of rotations is managed by therotate attribute inedit_defaults.
bodyedit_defaultsbackup(edit_backup){edit_backup=>"$(edit_backup)";rotate=>"2";}bundleagentmain{files:"/tmp/example_edit_backup_rotate"create=>"true";"/tmp/example_edit_backup_rotate"edit_line=>insert_lines("Hello World"),edit_defaults=>backup("rotate");"/tmp/example_edit_backup_rotate"handle=>"edit_2",edit_line=>insert_lines("Goodbye"),edit_defaults=>backup("rotate");vars:"example_files"slist=>lsdir("/tmp/","example_edit_backup_rotate.*",false);reports:"$(example_files)";}Outputs:
R: example_edit_backup_rotateR: example_edit_backup_rotate.cf-before-edit.1R: example_edit_backup_rotate.cf-before-edit.2See also:default_repository inbody agent control,copy_backup inbody copy_from,rotate inbody edit_defaults
empty_file_before_editing
Description: Baseline memory model of file to zero/empty beforecommencing promised edits.
Emptying a file before reconstructing its contents according to a fixedrecipe allows an ordered procedure to be convergent.
Type:boolean
Default value: false
Notes:
- Within
edit_linebundles the variable$(edit.empty_before_use)holds this value, allowing for decisions to be bade based on it.
Example:
bodyedit_defaultsexample{empty_file_before_editing=>"true";}inherit
Description: If true this causes the sub-bundle to inherit the privateclasses of its parent
Type:boolean
Example:
bundleagentname{methods:"group name"usebundle=>my_method,inherit=>"true";}bodyedit_defaultsexample{inherit=>"true";}History: Was introduced in 3.4.0, Enterprise 3.0.0 (2012)
Default value: false
Notes:Theinherit constraint can be added to the CFEngine code in twoplaces: foredit_defaults and inmethods promises. If set to true,it causes the child-bundle named in the promise to inherit only theclasses of the parent bundle. Inheriting the variables is unnecessary asthe child can always access the parent's variables by a qualifiedreference using its bundle name. For example,$(bundle.variable).
max_file_size
Description: Do not edit files bigger than this number of bytes
max_file_size is a local, per-file sanity check to make sure the fileediting is sensible. If this is set to zero, the check is disabled andany size may be edited. The default value ofmax_file_size isdetermined by the global control body setting whose default value is100k.
Type:int
Allowed input range:0,99999999999
Example:
bodyedit_defaultsexample{max_file_size=>"50K";}recognize_join
Description: Join together lines that end with a backslash, up to 4kBlimit
If set to true, this option allows CFEngine to process line based fileswith backslash continuation. The default is to not process continuationbackslashes.
Back slash lines will only be concatenated if the file requires editing,and will not be restored. Restoration of the backslashes is not possiblein a meaningful and convergent fashion.
Type:boolean
Default value: false
Example:
files:"/tmp/test_insert"create=>"true",edit_line=>Insert("$(insert.v)"),edit_defaults=>join;}#bodyedit_defaultsjoin{recognize_join=>"true";}rotate
Description: How many backups to store if 'rotate'edit_backupstrategy is selected. Defaults to 1
Used for log rotation. If the file is named foo and the rotate attributeis set to 4, as above, then initially foo is copied to foo.1 and the oldfile foo is zeroed out. In other words, the inode of the originallogfile does not change, but the original logfile will be empty afterthe rotation is complete.
The next time the promise is executed, foo.1 will be renamed foo.2, foois again copied to foo.1 and the old file foo is again zeroed out.
A promise may typically be executed as guarded by time-based orfile-size-based classes. Each time the promise is executed the files arecopied/zeroed or rotated (as above) until there are rotate numberedfiles, plus the one "main" file. In the example above, the file foo.3will be renamed foo.4, but the old version of the file foo.4 will bedeleted (that is, it "falls off the end" of the rotation).
Type:int
Allowed input range:0,99
Example:
bodyedit_defaultsexample{edit_backup=>"rotate";rotate=>"4";}See also:edit_backup inbody edit_defaults
edit_line
Type:edit_line
edit_template
Description: Path to Mustache or native-CFEngine template file to expand
Type:string
Allowed input range:"?(/.*)
Example:
bundleagentexample{files:!use_mustache::"/etc/motd"create=>"true",edit_template=>"$(this.promise_dirname)/templates/motd.tpl",template_method=>"cfengine";use_mustache::"/etc/motd"create=>"true",edit_template=>"$(this.promise_dirname)/templates/motd.mustache",template_method=>"mustache";}History: Was introduced in 3.3.0, Nova 2.2.0 (2012). Mustache templates were introduced in 3.6.0.
See also:template_method,template_data,readjson(),parsejson(),readyaml(),parseyaml(),mergedata(),data,Customize message of the day
edit_template_string
Description: Mustache string to expand
Type:string
Allowed input range: (arbitrary string)
Example:
bundleagentexample_using_template_method_inline_mustache{vars:# Here we construct a data container that will be passed to the mustache# templating engine"d"data=>'{"host":"docs.cfengine.com"}';# Here we specify a string that will be used as an inline mustache template"mustache_template_string"string=>"Welcome to host '{{{host}}}'";files:# Here we render the file using the data container and inline template specification"/tmp/example.txt"create=>"true",template_method=>"inline_mustache",edit_template_string=>"$(mustache_template_string)",template_data=>@(d);reports:"/tmp/example.txt"printfile=>cat($(this.promiser));}bodyprintfilecat(file){file_to_print=>"$(file)";number_of_lines=>"inf";}bundleagent__main__{methods:"example_using_template_method_inline_mustache";}R: /tmp/example.txtR: Welcome to host 'docs.cfengine.com'This policy can be found in/var/cfengine/share/doc/examples/template_method-inline_mustache.cfand downloaded directly fromgithub.
History: Was introduced in 3.12.0
See also:template_method,template_data,readjson(),parsejson(),readyaml(),parseyaml(),mergedata(),data,Customize message of the day
edit_xml
Type:edit_xml
file_select
Type:body file_select
See also:Common body attributes
leaf_name
Description: List of regexes that match an acceptable name
This pattern matches only the node name of the file, not its path.
Type:slist
Allowed input range: (arbitrary string)
Example:
bodyfile_selectexample{leaf_name=>{"S[0-9]+[a-zA-Z]+","K[0-9]+[a-zA-Z]+"};file_result=>"leaf_name";}path_name
Description: List of pathnames to match acceptable target
Path name and leaf name can be conveniently tested for separately by useof appropriate regular expressions.
Type:slist
Allowed input range:"?(/.*)
Example:
bodyfile_selectexample{leaf_name=>{"prog.pid","prog.log"};path_name=>{"/etc/.*","/var/run/.*"};file_result=>"leaf_name.path_name"}search_mode
Description: A list of mode masks for acceptable file permissions
The mode may be specified in symbolic or numerical form with + and -constraints. Concatenationug+s impliesu ORg, andu+s,g+simpliesu ANDg.
Type:slist
Allowed input range:[0-7augorwxst,+-]+
Example:
bundleagenttestbundle{files:"/home/mark/tmp/testcopy"file_select=>by_modes,transformer=>"/bin/echo DETECTED$(this.promiser)",depth_search=>recurse("inf");}bodyfile_selectby_modes{search_mode=>{"711","666"};file_result=>"mode";}bodydepth_searchrecurse(d){depth=>"$(d)";}search_size
Type:irange[int,int]
Allowed input range:0,inf
Description: Integer range of file sizes in bytes
Example:
bodyfile_selectexample{search_size=>irange("0","20k");file_result=>"size";}search_owners
Description: List of acceptable user names or ids for the file, orregexes to match
A list ofanchored regular expressions any of which must match the entireuserid.
Type:slist
Allowed input range: (arbitrary string)
Example:
bodyfile_selectexample{search_owners=>{"mark","jeang","student_.*"};file_result=>"owner";}Notes:Windows does not have user ids, only names.
search_groups
Description: List of acceptable group names or ids for the file, orregexes to match
A list ofanchored regular expressions, any of which must match the entire group.
Type:slist
Allowed input range: (arbitrary string)
Example:
bodyfile_selectexample{search_groups=>{"users","special_.*"};file_result=>"group";}Notes:On Windows, files do not have group associations.
search_bsdflags
Description: String of flags for bsd file system flags expected set
Extra BSD file system flags (these have no effect on non-BSD versions ofCFEngine). See the manual page forchflags for more details.
Type:slist
Allowed input range:[+-]*[(arch|archived|nodump|opaque|sappnd|sappend|schg|schange|simmutable|sunlnk|sunlink|uappnd|uappend|uchg|uchange|uimmutable|uunlnk|uunlink)]+
Example:
bodyfile_selectxyz{search_bsdflags=>"archived|dump";file_result=>"bsdflags";}ctime
Description: Range of change times (ctime) for acceptable files
The file's change time refers to both modification of content andattributes, such as permissions. On Windows,ctime refers to creationtime.
Type:irange[int,int]
Allowed input range:0,2147483647
Example:
bodyfiles_selectexample{ctime=>irange(ago(1,0,0,0,0,0),now);file_result=>"ctime";}See also:Function: irange()
mtime
Description: Range of modification times (mtime) for acceptable files
The file's modification time refers to both modification of content butnot other attributes, such as permissions.
Type:irange[int,int]
Allowed input range:0,2147483647
Example:
bodyfiles_selectexample{# Files modified more than one year ago (i.e., not in mtime range)mtime=>irange(ago(1,0,0,0,0,0),now);file_result=>"!mtime";}See also:Function: irange()
atime
Description: Range of access times (atime) for acceptable files
A range of times during which a file was accessed can be specified in afile_select body.
Type:irange[int,int]
Allowed input range:0,2147483647
Example:
bodyfile_selectused_recently{# files accessed within the last houratime=>irange(ago(0,0,0,1,0,0),now);file_result=>"atime";}bodyfile_selectnot_used_much{# files not accessed since 00:00 1st Jan 2000 (in the local timezime)atime=>irange(on(2000,1,1,0,0,0),now);file_result=>"!atime";}See also:Function: irange()
exec_regex
Description: Matches file if this regular expression matches any fullline returned by the command
The regular expression must be used in conjunction with theexec_program test. In this way the program must both return exitstatus 0 and its output must match the regular expression. The entireoutput must be matched.
Type:string
Allowed input range:.*
Example:
bodyfile_selectexample{exec_regex=>"SPECIAL_LINE: .*";exec_program=>"/path/test_program$(this.promiser)";file_result=>"exec_program.exec_regex";}exec_program
Description: Execute this command on each file and match if the exitstatus is zero
This is part of the customizable file search criteria. If theuser-defined program returns exit status 0, the file is consideredmatched.
Type:string
Allowed input range:"?(/.*)
Example:
bodyfile_selectexample{exec_program=>"/path/test_program$(this.promiser)";file_result=>"exec_program";}file_types
Description: List of acceptable file types from menu choices
File types vary in details between operating systems. The main POSIXtypes are provided here as menu options, with reg being a synonym forplain. In both cases this means not one of the "special" file types.
Type: (option list)
Allowed input range:
plainregsymlinkdirsocketfifodoorcharblockExample:
bodyfile_selectfilter{file_types=>{"plain","symlink"};file_result=>"file_types";}issymlinkto
Description: List of regular expressions to match file objects
If the file is a symbolic link that points to files matched by one of theseexpressions, the file will be selected.
Type:slist
Allowed input range: (arbitrary string)
Example:
bodyfile_selectexample{issymlinkto=>{"/etc/[^/]*","/etc/init\.d/[a-z0-9]*"};}Notes:Windows does not support symbolic links, so this attribute is not applicable on that platform.
file_result
Description: Logical expression combining classes defined by filesearch criteria
The syntax is the same as for a class expression, since the file selectionis a classification of the file-search in the same way that systemclasses are a classification of the abstract host-search. That is, youmay specify a boolean expression involving any of the file-matchingcomponents.
Type:string
Allowed input range:[!*(leaf_name|path_name|file_types|mode|size|owner|group|atime|ctime|mtime|issymlinkto|exec_regex|exec_program|bsdflags)[|.]*]*
Example:
bodyfile_selectyear_or_less{mtime=>irange(ago(1,0,0,0,0,0),now);file_result=>"mtime";}bodyfile_selectmy_pdf_files_morethan1dayold{mtime=>irange(ago(0,0,1,0,0,0),now);leaf_name=>{".*\.pdf",".*\.fdf"};search_owners=>{"mark"};file_result=>"owner.leaf_name.!mtime";}You may specify arbitrarily complex file-matching parameters, such as what isshown above, "is owned by mark, has the extension '.pdf' or '.fdf', and whosemodification time is not between 1 day ago and now"; that is, it is older than1 day.
See also:process_result
file_type
Description: By default,regular files are created, when specifyingcreate => "true". You can create fifos through this mechanism as well, byspecifyingfifo infile_type.
Type:string
Allowed input range:
regularfifoType: (menu option)
Allowed input range:
regularfifo
Default value: cfengine
link_from
Type:body link_from
See also:Common body attributes
copy_patterns
Description: A set of patterns that should be copied and synchronizedinstead of linked
During the linking of files, it is sometimes useful to buffer changeswith an actual copy, especially if the link is to an ephemeral filesystem. This list of patterns matches files that arise during a linkingpolicy. A positive match means that the file should be copied andupdated by modification time.
Type:slist
Allowed input range: (arbitrary string)
Example:
bodylink_fromexample{copy_patterns=>{"special_node1","/path/special_node2"};}link_children
Description: true/false whether to link all directory's children tosource originals
If the promiser is a directory, instead of copying the children, linkthem to the source.
Type:boolean
Default value: false
Example implementation:
bodylink_fromlinkchildren(tofile){source=>"$(tofile)";link_type=>"symlink";when_no_source=>"force";link_children=>"true";when_linking_children=>"if_no_such_file";# "override_file";}bodylink_fromlinkfrom(source,type){source=>$(source);link_type=>$(type);}Example usage:
bodyfilecontrol{inputs=>{"$(sys.libdir)/stdlib.cf"};}bundleagentmain{files:# This will make symlinks to each file in /var/cfengine/bin# for example:# '/usr/local/bin/cf-agent' -> '/var/cfengine/bin/cf-agent'# '/usr/local/bin/cf-serverd' -> '/var/cfengine/bin/cf-serverd'"/usr/local/bin"link_from=>linkchildren("/var/cfengine/bin"),comment=>"We like for cfengine binaries to be available inside of the common $PATH";}This policy can be found in/var/cfengine/share/doc/examples/symlink_children.cfand downloaded directly fromgithub.
link_type
Description: The type of link used to alias the file
This determines what kind of link should be used to link files. Usersare advised to be wary of 'hard links' (see Unix manual pages for theln command). The behavior of non-symbolic links is often precarious andunpredictable.
Note that symlink is synonymous with absolute links, which are differentfrom relative links. Although all of these are symbolic links, thenomenclature here is defined such that symlink and absolute areequivalent . When verifying a link, choosing 'relative' means that thelinkmust be relative to the source, so relative and absolute linksare mutually exclusive.
Type: (menu option)
Allowed input range:
symlinkhardlinkrelativeabsoluteDefault value: symlink
Example impelementation:
bodylink_fromln_s(x){link_type=>"symlink";source=>"$(x)";when_no_source=>"force";}bodylink_fromexample{link_type=>"symlink";source=>"/tmp/source";}Example usage:
bodyfilecontrol{inputs=>{"$(sys.libdir)/stdlib.cf"};}bundleagentmain{files:# We use move_obstructions because we want the symlink to replace a# regular file if necessary."/etc/apache2/sites-enabled/www.cfengine.com"->{"webmaster@cfengine.com"}link_from=>ln_s("/etc/apache2/sites-available/www.cfengine.com"),move_obstructions=>"true",comment=>"We always want our website to be enabled.";}This policy can be found in/var/cfengine/share/doc/examples/symlink.cfand downloaded directly fromgithub.
Notes:On Windows, hard links are the only supported type.
source
Description: The source file to which the link should point
For remote copies this refers to the file name on the remote server.
Type:string
Allowed input range:.+
Example:
bodylink_fromexample{source=>"/path/to/source";}when_linking_children
Description: Policy for overriding existing files when linkingdirectories of children
The options refer to what happens if the directory already exists, andis already partially populated with files. If the directory being copiedfrom contains a file with the same name as that of a link to be created,it must be decided whether to override the existing destination objectwith a link, or simply omit the automatic linkage for files that alreadyexist. The latter case can be used to make a copy of one directory withcertain fields overridden.
Type: (menu option)
Allowed input range:
override_fileif_no_such_fileExample:
bodylink_fromexample{when_linking_children=>"if_no_such_file";}when_no_source
Description: Behavior when the source file to link to does not exist
This describes how CFEngine should respond to an attempt to create alink to a file that does not exist. The options are to force thecreation to a file that does not (yet) exist, delete any existing link,or do nothing.
Type: (menu option)
Allowed input range:
forcedeletenopDefault value:nop
Example:
bodylink_fromexample{when_no_source=>"force";}move_obstructions
Description: true/false whether to move obstructions to file-objectcreation
If we have promised to make file X a link, but it already exists as afile, or vice-versa, or if a file is blocking the creation of adirectory, then normally CFEngine will report an error. If this is set,existing objects will be moved aside to allow the system to heal withoutintervention. Files and directories are saved/renamed, but symboliclinks are deleted.
Note that symbolic links for directories are treated as directories, notlinks. This behavior can be discussed, but the aim is to err on theside of caution.
Type:boolean
Default value: false
Example:
files:"/tmp/testcopy"copy_from=>mycopy("/tmp/source"),move_obstructions=>"true",depth_search=>recurse("inf");Notes:Some operating systems (Solaris) use symbolic links in path names.Copying to a directory could then result in renaming of the importantlink, if the behavior is different.
pathtype
Description: Menu option for interpreting promiser file object
By default, CFEngine makes an educated guess as to whether the promisepathname involves a regular expression or not. This guesswork is neededdue to cross-platform differences in filename interpretation.
If CFEngine guesses (or is told) that the pathname uses a regularexpression pattern, it will undertake a file search to find possiblematches. This can consume significant resources, and so the guess optionwill always try to optimize this. Guesswork is, however, imperfect, soyou have the option to declare your intention.
Type: (menu option)
Allowed input range:
literalregexguessIf the keywordliteral is invoked, a path will be treated as a literalstring regardless of what characters it contains. If it is declaredregex, it will be treated as a pattern to match.
Note that CFEngine splits the promiser up into path links beforematching, so that each link in the path chain is matched separately.Thus it it meaningless to have a/ in a regular expression, as thecomparison will never see this character.
Default value:guess
Example:
files:"/var/lib\d"pathtype=>"guess",# best guess (default)perms=>system;"/var/lib\d"pathtype=>"regex",# force regex interpretationperms=>system;"/var/.*/lib"pathtype=>"literal",# force literal interpretationperms=>system;In these examples, at least one case implies an iteration over allfiles/directories matching the regular expression, while the last casemeans a single literal object with a name composed of dots and stars.
Notes:On Windows paths usingregex must use the forward slash (/) as pathseparator, since the backward slash has a special meaning in a regularexpression. Literal paths may also use backslash (\) as a pathseparator.
perms
Type:body perms
See also:Common body attributes
bsdflags
Description: List of menu options for BSD file system flags to set
Type:slist
Allowed input range:[+-]*[(arch|archived|nodump|opaque|sappnd|sappend|schg|schange|simmutable|sunlnk|sunlink|uappnd|uappend|uchg|uchange|uimmutable|uunlnk|uunlink)]+
Example:
bodypermsexample{bsdflags=>{"uappnd","uchg","uunlnk","nodump","opaque","sappnd","schg","sunlnk"};}Notes:The BSD Unices (FreeBSD, OpenBSD, NetBSD) and MacOSX have additionalfile system flags which can be set. Refer to the BSDchflagsdocumentation for this.
groups
Description: List of acceptable groups of group ids, first is changetarget
The first named group in the list is the default that will be configuredif the file does not match an element of the list. The reserved wordnone may be used to match files that are not owned by a registeredgroup.
Type:slist
Allowed input range:[a-zA-Z0-9_$.-]+
Example:
bodypermsexample{groups=>{"users","administrators"};}Notes:On Windows, files do not have file groups associated with them,and thus this attribute is ignored. ACLs may be used in place for this.
mode
Description: File permissions
The mode string may be symbolic or numerical, likechmod.
Type:string
Allowed input range:[0-7augorwxst,+-]+
Example:
bodypermsexample{mode=>"a+rx,o+w";}See also:rxdirs
Notes:This is ignored on Windows, as the permission model uses ACLs.
owners
Description: List of acceptable owners or user ids, first is changetarget
The first user is the reference value that CFEngine will set the file toif none of the list items matches the true state of the file. Thereserved wordnone may be used to match files that are not owned by aregistered user.
Type:slist
Allowed input range:[a-zA-Z0-9_$.-]+
Example:
bodypermsexample{owners=>{"mark","wwwrun","jeang"};}Notes:On Windows, users can only take ownership of files, never give it. Thus,the first user in the list should be the user running the CFEngineprocess (usually Administrator). Additionally, some groups may be ownerson Windows (such as the Administrators group).
rxdirs
Description: true/false add execute flag for directories if read flag is set
Whentrue set thex flag on directories automatically if ther flag isspecified inmode.
Default:false
Type:boolean
Example:
bundleagent__main__{vars:"example_dirs"slist=>{"/tmp/rxdirs_example/rxdirs=default(false)-r","/tmp/rxdirs_example/rxdirs=default(false)-rx","/tmp/rxdirs_example/rxdirs=true-r","/tmp/rxdirs_example/rxdirs=true-rx",};files:"$(example_dirs)/."create=>"true";"/tmp/rxdirs_example/rxdirs=default(false)-r"perms=>example:m(600);"/tmp/rxdirs_example/rxdirs=default(false)-rx"perms=>example:m(700);"/tmp/rxdirs_example/rxdirs=true-r"perms=>example:m_rxdirs_on(600);"/tmp/rxdirs_example/rxdirs=true-rx"perms=>example:m_rxdirs_on(700);reports:"$(example_dirs) modeoct='$(with)'"with=>filestat($(example_dirs),modeoct);}bodyfilecontrol{namespace=>"example";}bodypermsm(mode){mode=>"$(mode)";}bodypermsm_rxdirs_on(mode){inherit_from=>m($(mode));rxdirs=>"true";} warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-r), please set it explicitly warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-r), please set it explicitly warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-rx), please set it explicitly warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-rx), please set it explicitlyR: /tmp/rxdirs_example/rxdirs=default(false)-r modeoct='40600'R: /tmp/rxdirs_example/rxdirs=default(false)-rx modeoct='40600'R: /tmp/rxdirs_example/rxdirs=true-r modeoct='40700'R: /tmp/rxdirs_example/rxdirs=true-rx modeoct='40700' warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-r), please set it explicitly warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-rx), please set it explicitly warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-r), please set it explicitly warning: Using the default value 'false' for attribute rxdirs (promiser: /tmp/rxdirs_example/rxdirs=default(false)-rx), please set it explicitlyThis policy can be found in/var/cfengine/share/doc/examples/rxdirs.cfand downloaded directly fromgithub.
See also:mode
Notes:This is ignored on Windows, as the permission model uses ACLs.
History:
- Default value changed from
truetofalsein CFEngine 3.20.0 - Added warning if default value is not explicitly set in 3.18.2, 3.20.0
rename
Type:body rename
See also:Common body attributes
disable
Description: true/false automatically rename and remove permissions
Disabling a file means making it unusable. For executables this meanspreventing execution, for an information file it means making the fileunreadable.
Type:boolean
Default value: false
Example:
bodyrenameexample{disable=>"true";disable_suffix=>".nuked";}disable_mode
Description: The permissions to set when a file is disabled
To disable an executable it is not enough to rename it, you should alsoremove the executable flag.
Type:string
Allowed input range:[0-7augorwxst,+-]+
Example:
bodyrenameexample{disable_mode=>"0600";}disable_suffix
Description: The suffix to add to files when disabling
To disable files in a particular manner, use this string suffix.
Type:string
Allowed input range: (arbitrary string)
Default value:.cfdisabled
Example:
bodyrenameexample{disable=>"true";disable_suffix=>".nuked";}newname
Description: The desired name for the current file
Type:string
Allowed input range: (arbitrary string)
Example:
bodyrenameexample(s){newname=>"$(s)";}rotate
Description: Maximum number of file rotations to keep
Used for log rotation. If the file is namedfoo and the rotate attributeis set to 4, as above, then initiallyfoo is copied tofoo.1 and the oldfilefoo is zeroed out (that is, the inode of the original logfile doesnot change, but the original log file will be empty after the rotationis complete).
The next time the promise is executed,foo.1 will be renamedfoo.2,foois again copied tofoo.1 and the old filefoo is again zeroed out.
Each time the promise is executed (and typically, the promise would beexecuted as guarded by time-based or file-size-based classes), the filesare copied/zeroed or rotated as above until there are rotate numberedfiles plus the one "main" file.
Type:int
Allowed input range:0,99
Example:
bodyrenameexample{rotate=>"4";}In the example above, the filefoo.3 will be renamedfoo.4, but the oldversion of the filefoo.4 will be deleted (that is, it "falls off the end"of the rotation).
repository
Description: Name of a repository for versioning
A local repository for this object, overrides the default.
Note that when a repository is specified, the files are stored using thecanonified directory name of the original file, concatenated with thename of the file. So, for example,/usr/local/etc/postfix.conf wouldordinarily be stored in an alternative repository as_usr_local_etc_postfix.conf.cfsaved.
Type:string
Allowed input range:"?(/.*)
Example:
files:"/path/file"copy_from=>source,repository=>"/var/cfengine/repository";template_data
Description: The data container to be passed to the template (Mustache or inline_mustache). It can come from a function call likemergedata() or from a data container reference like@(mycontainer).
Type:data
Allowed input range: (arbitrary string)
Example:
files:"/path/file"...edit_template=>"mytemplate.mustache",template_data=>parsejson('{"message":"hello"}'),template_method=>"mustache";Example:
vars:"mycontainer"data=>'[1,2,3]';files:"/path/file"...edit_template=>"mytemplate.mustache",template_data=>@(mycontainer),template_method=>"mustache";If this attribute is omitted, the result of thedatastate() functioncall is used instead. Seeedit_template for how you can use the datastate in Mustache.
See also:edit_template,template_method,datastate()
template_method
Description: The template type.
By defaultcfengine requests the native CFEngine templateimplementation, but you can usemustache orinline_mustache as well.
Type: (menu option)
Allowed input range:
cfengineinline_mustachemustache
Default value: cfengine
template_method cfengine
The default native-CFEngine template format (selected whentemplate_method iscfengine or unspecified) uses inline tags tomark regions and classes. Each line represents aninsert_linespromise, unless the promises are grouped into a block using:
[%CFEngineBEGIN%]...[%CFEngineEND%]Variables, scalars and list variables are expanded within each promisebased on the current scope of the calling promise. If lines aregrouped into a block, the whole block is repeated when lists areexpanded (see the Special Topics Guide on editing).
If a class-context modified is used:
[%CFEngineclass-expression::%]then the lines that follow are only inserted if the context matches theagent's current context. This allows conditional insertion.
Note: Because classic templates are built on top ofedit_line, identicallines will not be rendered more than once unless they are included within ablock. This includes blank lines.
Example contrivedcfengine template:
#This is a template file /templates/input.tmplTheselinesapplytoanyone[%CFEnginesolaris.Monday::%]EverythingafterhereappliesonlytosolarisonMondaysuntiloverridden...[%CFEnginelinux::%]Everythingafterherenowappliesnowtolinuxonly.[%CFEngineBEGIN%]ThisisablockoftextThatcontainslistvariables:$(some.list)Withtextbeforeandafter.[%CFEngineEND%]nameserver$(some.list)Examplecfengine template for apache vhost directives:
[%CFEngineany::%]VirtualHost$(sys.ipv4[eth0]):80>ServerAdmin$(stage_file.params[apache_mail_address][1])DocumentRoot/var/www/htdocsServerName$(stage_file.params[apache_server_name][1])AddHandlercgi-scriptcgiErrorLog/var/log/httpd/error.logAddTypeapplication/x-x509-ca-cert.crtAddTypeapplication/x-pkcs7-crl.crlSSLEngineoffCustomLog/var/log/httpd/access.log/VirtualHost>[%CFEnginewebservers_prod::%][%CFEngineBEGIN%]VirtualHost$(sys.ipv4[$(bundle.interfaces)]):443>ServerAdmin$(stage_file.params[apache_mail_address][1])DocumentRoot/var/www/htdocsServerName$(stage_file.params[apache_server_name][1])AddHandlercgi-scriptcgiErrorLog/var/log/httpd/error.logAddTypeapplication/x-x509-ca-cert.crtAddTypeapplication/x-pkcs7-crl.crlSSLEngineonSSLCertificateFile$(stage_file.params[apache_ssl_crt][1])SSLCertificateKeyFile$(stage_file.params[apache_ssl_key][1])CustomLog/var/log/httpd/access.log/VirtualHost>[%CFEngineEND%]template_method inline_mustache
Whentemplate_method isinline_mustache the mustache input is not a filebut a string and you must setedit_template_string. The same rules applyforinline_mustache andmustache. For mustache explanation seetemplate_method mustache
Example:
bundleagentexample_using_template_method_inline_mustache{vars:# Here we construct a data container that will be passed to the mustache# templating engine"d"data=>'{"host":"docs.cfengine.com"}';# Here we specify a string that will be used as an inline mustache template"mustache_template_string"string=>"Welcome to host '{{{host}}}'";files:# Here we render the file using the data container and inline template specification"/tmp/example.txt"create=>"true",template_method=>"inline_mustache",edit_template_string=>"$(mustache_template_string)",template_data=>@(d);reports:"/tmp/example.txt"printfile=>cat($(this.promiser));}bodyprintfilecat(file){file_to_print=>"$(file)";number_of_lines=>"inf";}bundleagent__main__{methods:"example_using_template_method_inline_mustache";}R: /tmp/example.txtR: Welcome to host 'docs.cfengine.com'This policy can be found in/var/cfengine/share/doc/examples/template_method-inline_mustache.cfand downloaded directly fromgithub.
History: Was introduced in 3.12.0
See also:edit_template_string,template_data,datastate()
template_method mustache
Whentemplate_method ismustache data must be provided to render thetemplate with. Data can be provided by functions that return data ( i.e.mergedata(),mapdata(),readdata(),findprocesses(), etc ...), lists ordata variables by reference@(data), or by specifying data as inline json(which can take advantage of data wrapping). For convenience iftemplate_datais not specified the output ofdatastate() will be used. Thus thedatastate() (all variables and classes defined) is the default.
FrommustacheVariables,Sections,Inverted Sections,Comments, andtheSet DelimiterTAG TYPES areimplemented.
NOTE:PartialsandLambdas are notcurrently supported.
template_method mustache Variables
The most basic tag type is the variable. A{{name}} tag in a basictemplate will try to find the name key in the current context. If there is noname key, the parent contexts will be checked recursively. If the top context isreached and the name key is still not found, nothing will be rendered.
All variables are HTML escaped by default. If you want to return unescapedHTML, use the triple mustache:{{{name}}} or an ampersand({{& name}}).
A variable "miss" returns an empty string.
bundleagentmain{vars:"data"data=>'{"key":"Hello World & 3>2!"}';reports:"$(with)"with=>string_mustache("{{key}}{{{key}}}{{&key}}Missing '{{missing}}' varibles render empty strings.",data);}R: Hello World & 3>2!Hello World & 3>2!Hello World & 3>2!Missing '' varibles render empty strings.This policy can be found in/var/cfengine/share/doc/examples/mustache_variables.cfand downloaded directly fromgithub.
template_method mustache Sections
Sections render blocks of text one or more times, depending on the value of thekey in the current context.
A section begins with a pound and ends with a slash. That is,{{#key}}begins a "person" section while{{/key}} ends it.
The behavior of the section is determined by the value of the key.
Empty lists:
If the key exists and has a value of false or an empty list, the HTML betweenthe pound and slash will not be displayed.
bundleagentmain{vars:"data"data=>'{"list":[]}';reports:"The list contains$(with)."with=>string_mustache("{{#list}} {{{.}}}{{/list}}",data);}R: The list contains .This policy can be found in/var/cfengine/share/doc/examples/mustache_sections_empty_list.cfand downloaded directly fromgithub.
Non-Empty Lists:
bundleagentmain{vars:"data"data=>'{"list":["1","2","3"]}';reports:"$(with)"with=>string_mustache("{{#list}} {{{.}}}{{/list}}",data);}R: 1 2 3This policy can be found in/var/cfengine/share/doc/examples/mustache_sections_non_empty_list.cfand downloaded directly fromgithub.
Non-False Values:
When the value is non-false but not a list, it will be used as the context for asingle rendering of the block.
bundleagentmain{vars:"data"data=>parsejson('{"classes":{"example":true}}');reports:"$(with)"with=>string_mustache("{{#classes.example}}This is an example.{{/classes.example}}",data);}R: This is an example.This policy can be found in/var/cfengine/share/doc/examples/mustache_sections_non_false_value.cfand downloaded directly fromgithub.
template_method mustache Inverted Sections
An inverted section begins with a caret (hat) and ends with a slash. That is{{^key}} begins a "key" inverted section while{{/key}} ends it.
While sections can be used to render text one or more times based on the valueof the key, inverted sections may render text once based on the inverse value ofthe key. That is, they will be rendered if the key doesn't exist, is false, oris an empty list.
bundleagentmain{reports:"CFEngine$(with)"with=>string_mustache("{{^classes.enterprise_edition}}Community{{/classes.enterprise_edition}}{{#classes.enterprise_edition}}Enterprise{{/classes.example}}",datastate());}R: CFEngine CommunityThis policy can be found in/var/cfengine/share/doc/examples/mustache_sections_inverted.cfand downloaded directly fromgithub.
template_method mustache Comments
Comments begin with a bang and are ignored. Comments may contain newlines.
bundleagentmain{reports:"$(with)"with=>string_mustache("Render this.{{! But notthis}}",datastate());}R: Render this.This policy can be found in/var/cfengine/share/doc/examples/mustache_comments.cfand downloaded directly fromgithub.
template_method mustache Set Delimiter
Set Delimiter tags start with an equal sign and change the tag delimiters from{{ and}} to custom strings.
bundleagentmain{vars:"data"data=>'{"key":"value of key in data"}';reports:"$(with)"with=>string_mustache("{{=<% %>=}}key has <% key %>",data);}R: key has value of key in dataThis policy can be found in/var/cfengine/share/doc/examples/mustache_set_delimiters.cfand downloaded directly fromgithub.
template_method mustache extensions
The following areCFEngine-specific extensions.
-top- special key representing the complete data given. Useful for iteratingover the top level of a container{{#-top-}} ... {{/-top-}}and rendering json representation of data given with$ and%.
bundleagentmain{vars:"data"data=>'{"key":"value","list":["1","2"]}';reports:"-top- contains$(const.n)$(with)"with=>string_mustache("{{%-top-}}",data);}R: -top- contains{ "key": "value", "list": [ "1", "2" ]}This policy can be found in/var/cfengine/share/doc/examples/mustache_extension_top.cfand downloaded directly fromgithub.
% variable prefix causing data to be rendered as multi-line jsonrepresentation. Like output fromstorejson().
bundleagentmain{reports:"$(with)"with=>string_mustache("{{%mykey}}",'{"mykey":{"msg":"Hello World"}}');}R: { "msg": "Hello World"}This policy can be found in/var/cfengine/share/doc/examples/mustache_extension_multiline_json.cfand downloaded directly fromgithub.
$ variable prefix causing data to be rendered as compact json representation.Like output fromformat() with the%S format string.
bundleagentmain{vars:"msg"string=>"Hello World";"report"string=>string_mustache("{{$-top-}}",bundlestate($(this.bundle))),unless=>isvariable($(this.promiser));# Careful to not include# ourselves so we only grab the# state of the first pass.reports:"$(report)";}R: {"msg":"Hello World"}This policy can be found in/var/cfengine/share/doc/examples/mustache_extension_compact_json.cfand downloaded directly fromgithub.
@ expands the current key being iterated to complement the value as accessedwith..
bundleagentmain{reports:"$(with)"with=>string_mustache("datastate() provides {{#-top-}} {{{@}}}{{/-top-}}",datastate());}R: datastate() provides classes varsThis policy can be found in/var/cfengine/share/doc/examples/mustache_extension_expand_key.cfand downloaded directly fromgithub.
See also:edit_template,template_data,datastate()
touch
Description: true/false whether to touch time stamps on file
Type:boolean
Example:
files:"/path/file"touch=>"true";transformer
Description: Command (with full path) used to transform current file(no shell wrapper used)
A command to execute, usually for the promised file to transform it tosomething else.
Notes:
The promised filemust exist or the transformer will not be triggered.
The transformershould result in the promised file no longer existing.
By default, if the transformer returns zero, the promise will be consideredrepaired, even if the transformation does not result in the promised filebecoming absent. Depending on other context restrictions this may result inthe transformer being executed during each agent execution. For example:
codetransformer=>"/bin/echo I found a file named$(this.promiser)",The interpretation of the transformer return code can be managed similarly to
commandstype promises by using aclassesbody withkept_returncodes,repaired_returncodesandfailed_returncodesattributes.stdoutandstderrare redirected by CFEngine, and will not appear in anyoutput unless you runcf-agentwith verbose logging.The command is not run in a shell. This means that you cannot perform fileredirection or create pipelines.
Type:string
Allowed input range:"?(/.*)
Example:
rm -f /tmp/example-files-transformer.txtrm -f /tmp/example-files-transformer.txt.gzrm -f /tmp/this-file-does-not-exist-to-be-transformed.txtrm -f /tmp/this-file-does-not-exist-to-be-transformed.txt.gzbundleagentmain{vars:"gzip_path"string=>ifelse(isexecutable("/bin/gzip"),"/bin/gzip","/usr/bin/gzip");files:linux::"/tmp/example-files-transformer.txt"content=>"Hello World";"/tmp/example-files-transformer.txt"transformer=>"$(gzip_path)$(this.promiser)";# The transformer in the following promise results in the promised file# being absent on completion. Note: It is the expectation and# responsibility of the transformer itself that the transformation results# in the promised file no longer existing."/tmp/example-files-transformer.txt"transformer=>"$(gzip_path)$(this.promiser)";# Since this file does not exist, the transformer will not be triggered# and neither the text file nor a gzip file will exist"/tmp/this-file-does-not-exist-to-be-transformed.txt"transformer=>"$(gzip_path)$(this.promiser)";reports:"/tmp/example-files-transformer.txt$(with)"with=>ifelse(fileexists("/tmp/example-files-transformer.txt"),"exists","does not exist");"/tmp/example-files-transformer.txt.gz$(with)"with=>ifelse(fileexists("/tmp/example-files-transformer.txt.gz"),"exists","does not exist");"/tmp/this-file-does-not-exist-to-be-transformed.txt$(with)"with=>ifelse(fileexists("/tmp/this-file-does-not-exist-to-be-transformed.txt"),"exists","does not exist");"/tmp/this-file-does-not-exist-to-be-transformed.txt.gz$(with)"with=>ifelse(fileexists("/tmp/this-file-does-not-exist-to-be-transformed.txt.gz"),"exists","does not exist");}R: /tmp/example-files-transformer.txt does not existR: /tmp/example-files-transformer.txt.gz existsR: /tmp/this-file-does-not-exist-to-be-transformed.txt does not existR: /tmp/this-file-does-not-exist-to-be-transformed.txt.gz does not existThis policy can be found in/var/cfengine/share/doc/examples/files_transformer.cfand downloaded directly fromgithub.
In the example, the promise is made on the file that we wish to transform. Ifthe promised file exists, the transformer will change the file to a compressedversion (and the next time CFEngine runs, the promised file will no longerexist, because it now has the.gz extension).
- Overview
- Getting started
- Reference
- Components
- Functions
- accessedbefore
- accumulated
- ago
- and
- basename
- bundlesmatching
- bundlestate
- callstack_callers
- callstack_promisers
- canonify
- canonifyuniquely
- cf_version_after
- cf_version_at
- cf_version_before
- cf_version_between
- cf_version_maximum
- cf_version_minimum
- changedbefore
- classesmatching
- classfiltercsv
- classify
- classmatch
- concat
- countclassesmatching
- countlinesmatching
- data_expand
- data_readstringarray
- data_readstringarrayidx
- data_regextract
- data_sysctlvalues
- datastate
- difference
- dirname
- diskfree
- escape
- eval
- every
- execresult
- execresult_as_data
- expandrange
- file_hash
- fileexists
- filesexist
- filesize
- filestat
- filter
- findfiles
- findfiles_up
- findprocesses
- format
- getclassmetatags
- getenv
- getfields
- getgid
- getindices
- getuid
- getuserinfo
- getusers
- getvalues
- getvariablemetatags
- grep
- groupexists
- hash
- hash_to_int
- hashmatch
- host2ip
- hostinnetgroup
- hostrange
- hostsseen
- hostswithclass
- hubknowledge
- ifelse
- int
- intersection
- ip2host
- iprange
- irange
- isdir
- isexecutable
- isgreaterthan
- isipinsubnet
- islessthan
- islink
- isnewerthan
- isplain
- isreadable
- isvariable
- join
- lastnode
- laterthan
- ldaparray
- ldaplist
- ldapvalue
- length
- lsdir
- makerule
- maparray
- mapdata
- maplist
- max
- mean
- mergedata
- min
- network_connections
- none
- not
- now
- nth
- on
- or
- packagesmatching
- packageupdatesmatching
- parseintarray
- parsejson
- parserealarray
- parsestringarray
- parsestringarrayidx
- parseyaml
- peerleader
- peerleaders
- peers
- processexists
- product
- randomint
- read_module_protocol
- readcsv
- readdata
- readenvfile
- readfile
- readintarray
- readintlist
- readjson
- readrealarray
- readreallist
- readstringarray
- readstringarrayidx
- readstringlist
- readtcp
- readyaml
- regarray
- regcmp
- regex_replace
- regextract
- registryvalue
- regldap
- regline
- reglist
- remoteclassesmatching
- remotescalar
- returnszero
- reverse
- rrange
- selectservers
- shuffle
- some
- sort
- splayclass
- splitstring
- storejson
- strcmp
- strftime
- string
- string_downcase
- string_head
- string_length
- string_mustache
- string_replace
- string_reverse
- string_split
- string_tail
- string_trim
- string_upcase
- sublist
- sum
- sysctlvalue
- translatepath
- type
- unique
- url_get
- usemodule
- userexists
- validdata
- validjson
- variablesmatching
- variablesmatching_as_data
- variance
- version_compare
- Language concepts
- Masterfiles Policy Framework
- promises.cf
- .no-distrib/
- update.cf
- standalone_self_upgrade.cf
- cfe_internal/
- cfe_internal/CFE_cfengine.cf
- cfe_internal/core/
- cfe_internal/core/watchdog
- cfe_internal/core/watchdog/watchdog.cf
- cfe_internal/enterprise/
- cfe_internal/enterprise/federation/
- cfe_internal/enterprise/federation/federation.cf
- cfe_internal/recommendations.cf
- cfe_internal/update/
- cfe_internal/update/cfe_internal_dc_workflow.cf
- cfe_internal/update/cfe_internal_update_from_repository.cf
- cfe_internal/update/lib.cf
- cfe_internal/update/systemd_units.cf
- cfe_internal/update/update_bins.cf
- cfe_internal/update/update_policy.cf
- cfe_internal/update/update_processes.cf
- controls/
- controls/cf_agent.cf
- controls/cf_execd.cf
- controls/cf_hub.cf
- controls/cf_monitord.cf
- controls/cf_runagent.cf
- controls/cf_serverd.cf
- controls/def.cf
- controls/def_inputs.cf
- controls/reports.cf
- controls/update_def.cf
- controls/update_def_inputs.cf
- inventory/
- inventory/any.cf
- inventory/debian.cf
- inventory/freebsd.cf
- inventory/generic.cf
- inventory/linux.cf
- inventory/lsb.cf
- inventory/macos.cf
- inventory/os.cf
- inventory/redhat.cf
- inventory/suse.cf
- inventory/windows.cf
- lib/
- lib/autorun.cf
- lib/bundles.cf
- lib/cfe_internal.cf
- lib/cfe_internal_hub.cf
- lib/cfengine_enterprise_hub_ha.cf
- lib/commands.cf
- lib/common.cf
- lib/databases.cf
- lib/edit_xml.cf
- lib/event.cf
- lib/examples.cf
- lib/feature.cf
- lib/files.cf
- lib/guest_environments.cf
- lib/monitor.cf
- lib/packages.cf
- lib/paths.cf
- lib/processes.cf
- lib/reports.cf
- lib/services.cf
- lib/stdlib.cf
- lib/storage.cf
- lib/testing.cf
- lib/users.cf
- lib/vcs.cf
- modules/
- modules/mustache/
- modules/packages/
- modules/packages/vendored/
- modules/promises/
- modules/promises/cfengine.py
- modules/promises/cfengine.sh
- services/
- services/autorun/
- services/main.cf
- Macros
- Promise types
- Special variables
- All promise and body types
- Release notes
- Web UI
- Settings
- Health
- Hosts
- Alerts and notifications
- Custom actions for alerts
- Enterprise reporting
- Federated reporting
- Measurements app
- Hub administration
- Decommissioning hosts
- Extending Mission Portal
- Extending query builder in Mission Portal
- Adjusting schedules
- Backup and restore
- Configure a custom LDAP port
- Custom LDAPs certificate
- Custom SSL certificate
- Enable plain http
- Lookup license info
- Policy deployment
- Public key distribution
- Re-installing Enterprise hub
- Regenerate self signed SSL certificate
- Reset administrative credentials
- Debugging Mission Portal
- License
- Examples and tutorials
- Example snippets
- General examples
- Administration examples
- Measuring examples
- Software administration examples
- Commands, scripts, and execution examples
- File and directory examples
- File template examples
- Interacting with directory services
- Database examples
- Network examples
- System security examples
- System information examples
- System administration examples
- System file examples
- Windows registry examples
- File permissions
- User management examples
- Common promise patterns
- Aborting execution
- Change detection
- Check filesystem space
- Copy single files
- Create files and directories
- Customize message of the day
- Distribute ssh keys
- Ensure a process is not running
- Ensure a service is enabled and running
- Find the MAC address
- Install packages
- Mount NFS filesystem
- Restart a process
- Set up name resolution with DNS
- Set up sudo
- Set up time management through NTP
- Updating from a central policy server
- Tutorials
- JSON and YAML support in CFEngine
- Installing CFEngine Enterprise agent
- Managing local users
- Managing network time protocol
- Managing processes and services
- Package management
- Writing CFEngine policy
- Distributing files from a central location
- File editing
- Reporting and remediation of security vulnerabilities
- Masterfiles Policy Framework upgrade
- Tags for variables, classes, and bundles
- Custom inventory
- Dashboard alerts
- Integrating alerts with PagerDuty
- Integrating alerts with ticketing systems
- Integrating with Sumo Logic
- Rendering files with Mustache templates
- Reporting
- File comparison
- High availability
- Writing and serving policy
- Example snippets
- Resources
- FAQ
- Why knowledge management?
- Requesting a CFEngine Enterprise License
- Uninstalling / reinstalling
- Agent output email
- Debugging slow queries
- Enterprise Report Filtering
- Enterprise report collection
- Enterprise reporting database
- How can I tell what classes and variables are defined?
- How do I find the public key for a given host
- How do I fix trust after an IP change?
- How do I fix undefined body errors?
- How do I integrate custom policy?
- How do I pass a data type variable?
- Manual execution
- Mustache templating
- Unable to log into Mission Portal
- Users
- What is promise locking?
- Why are remote agents not updating?
- Why are some files inside masterfiles not being updated/distributed?
- Why does CFEngine install into /var/cfengine instead of following the FHS?
- Bootstrapping
- Tuning PostgreSQL
- What did CFEngine do?
- External resources
- Additional topics
- Best practices
- FAQ
- API
- Enterprise API examples
- Enterprise API reference
- Actions API
- Build API
- CMDB API
- Changes REST API
- Federated reporting configuration API
- File changes API
- Health diagnostic API
- Host REST API
- Import & export API
- Import & export compliance report API
- Inventory API
- LDAP authentication API
- Personal groups API
- Query REST API
- SQL schema
- SSH keys API
- Shared groups API
- Status and settings REST API
- Two-factor authentication API
- Users and access-control REST API
- VCS settings API
- Web RBAC API