This policy will look for changes recursively in a directory.

code
body common control

{
      bundlesequence  => { "example"  };
}


bundle agent example

{
  files:

      "/home/mark/tmp/web"  # Directory to monitor for changes.

      changes      => detect_all_change,
      depth_search => recurse("inf");
}


body changes detect_all_change

{
      report_changes => "all";  
      update_hashes  => "true";
}


body depth_search recurse(d)

{
      depth        => "$(d)";
}

This policy can be found in /var/cfengine/share/doc/examples/change_detect.cf and downloaded directly from github.

Here is an example run.

First, let's create some files for CFEngine to monitor:

code
# mkdir /etc/example
# date > /etc/example/example.conf

CFEngine detects new files and adds them to the file integrity database:

command
cf-agent -f unit_change_detect.cf
output
2013-06-06T20:53:26-0700    error: /example/files/'/etc/example':
File '/etc/example/example.conf' was not in 'md5' database - new file found
command
cf-agent -f unit_change_detect.cf -K

If there are no changes, CFEngine runs silently:

command
cf-agent -f unit_change_detect.cf

Now let's update the mtime, and then the mtime and content. CFEngine will notice the changes and record the new profile:

code
# touch /etc/example/example.conf # update mtime
# cf-agent -f unit_change_detect.cf -K
2013-06-06T20:53:52-0700    error: Last modified time for
'/etc/example/example.conf' changed 'Thu Jun  6 20:53:18 2013'
-> 'Thu Jun  6 20:53:49 2013'
# date >> /etc/example/example.conf # update mtime and content
# cf-agent -f unit_change_detect.cf -K
2013-06-06T20:54:01-0700    error: Hash 'md5' for '/etc/example/example.conf' changed!
2013-06-06T20:54:01-0700    error: /example/files/'/etc/example': Updating hash for
'/etc/example/example.conf' to 'MD5=8576cb25c9f78bc9ab6afd2c32203ca1'
2013-06-06T20:54:01-0700    error: Last modified time for '/etc/example/example.conf'
changed 'Thu Jun  6 20:53:49 2013' -> 'Thu Jun  6 20:53:59 2013'
#