I recently posted a snippet to perform hierarchical copying in cfengine3. As I was attempting to integrate this mechanism into my copy of cfengine's COPBL, I realized that no additional functions or body components are needed. Thanks to cfengine3's list expansion, all you need to do is include in the existing copy promise the list containing the desired list of suffixes to try. For example:
Becomes:
While this looks at first sight even longer than the original (and of course, in this case you could just specify ${sys.flavour} directly in the copy_from statement), it is much more flexible. Instead of defining different sections for each class that you want to handle (e.g. suse_9, redhat_5, etc.), the same code is able to copy the corresponding binary directory for any operating system, you just have to put the corresponding bin.* directory in your repository.
Furthermore, without modifying the code, you can provide different binaries for specific hosts, for different domains, or for any other classification you want to impose. Just modify the @suffixes variable, ordering them from the most specific to the most general one:
You can do this without any additional functions, just adding ${suffixes} in the appropriate place in the copy arguments. The advantage of using a different function as in my previous post (or even better, modifying your existing copy function), is that you can add hierarchical copying without having to modify all copy promises in your policy.