Autodefine Bliss

From Cfwiki

Jump to: navigation, search

The Problem

You have successfully implemented Singlecopy Nirvana, only to realize that when certain files are updated, other actions need to be, such as a a stanza from a shellcommand or process. The obvious solution is to move the files for the special applications that need further actions into separate copy sections and use the define parameters to define classes when files are copied. Soon, this grows tedious--all the work you put into the nice, clean directory structure for Singlecopy Nirvana has become unwieldy because more and more things can--and should--be done with a copy trigger. Enter autodefine.

The Solution

autodefine seems to be scarcely known. It is not mentioned in the tutorial or the SAGE booklet, nor was it mentioned here prior to this article. The directive is, however, mentioned deep in the [reference manual].

It is also an odd feature, because it appears that it would not actually work, but it does. Here is an example that should be self-explanatory, along with sample output:

control:
   any::
       actionsequence = ( copy shellcommands )
       AddInstallable = ( test_autodefine )
   test_autodefine::
       autodefine = ( /tmp/test-autodefine )
copy:
   any::
       /etc/hosts
           dest=/tmp/test-autodefine
shellcommands:
   test_autodefine::
       "/bin/echo '***** Shellcommand was run *****'"
alerts:
   test_autodefine::
       "Autodefine worked!"
       ifelapsed=0


Sample output from version 2.2.2:

cfengine:zeus: Copying from localhost:/etc/hosts
cfengine:zeus: Object /tmp/test-autodefine had permission 600, changed it to 444
cfengine:zeus: Image /tmp/test-autodefine was set to autodefine class test_autodefine
cfengine:zeus: 
Executing script /bin/echo '***** Shellcommand was run *****'...(timeout=0,uid=-1,gid=-1)
cfengine:zeus:/bin/echo '****: ***** Shellcommand was run *****
cfengine:zeus: Finished script /bin/echo '***** Shellcommand was run *****'
cfengine:zeus: Autodefine worked!
cfengine:zeus: Outcome of version (not specified): Promises still kept 0%, Promises repaired 100%, Promises not kept 0%

In this example, the test_autodefine class becomes defined if the file /tmp/test-autodefine is copied. When the class is defined, the alert is triggered and the message prints.

Caveats

There are, however, a few things to be aware of with autodefine.

One is that to use an autodefined class to trigger shellcommands or other actions, it is necessary to add the class name to the list of AddInstallable classes.

Another is that multiple classes cannot be defined with the logical operators, like "|" or ".". For example, this modification to the above example does not work:

# Does not work
control:
  test_autodefine|test_autodefine_also::
    autodefine = ( /tmp/test-autodefine )

As of 2.2.1, a class named test_autodefine|test_autodefine_also is defined, which is probably not what is desired. There can be multiple classes defined with the same patterns, however:

# This does work
control:
  test_autodefine::
    autodefine = ( /tmp/test-autodefine )
  test_autodefine_also::
    autodefine = ( /tmp/test-autodefine )

Both the test_autodefine and test_autodefine_also will be defined as expected.


As the reference manual mentions, wildcards may be used in the pattern on the right-hand side:

 # This also works
 control:
   test_autodefine::
       autodefine = ( /tmp/test-autodef* )

You can list many patterns, separating them with spaces (not colons ":" as in other cfengine lists):

 # This works too
 control:
   test_autodefine::
       autodefine = ( /tmp/test-autodefine /tmp/test-autodefine2 )

In 2.1.17, however, patterns do not seem to work. In 2.1.11, autodefine does not seem to work at all.

Personal tools