Forum: Cfengine Help
Subject: Promise outcomes flip-flopping during runtime
Author: Authority
Link to topic: https://cfengine.com/forum/read.php?3,17077,17077#msg-17077

I was trying to write a classes body that would ensure that one, and only one, 
of two classes would be set based on the outcome of a promise.  I start with 
the concept of a "YES" class and a "NO" class.  If the promise is kept or 
repaired, I want the "YES" class set and for completeness' sake, the "NO" class 
to be cancelled (even though it should have never been added anyway).  If the 
promise was not kept, it should trigger the "NO" class and cancel the "YES."  
And being a fan of verboseness, I began by adding every possible attribute to 
my classes body to leave no ambiguity of what was happening.  Unfortunately, I 
got quite the opposite.

I've found that a promise would be called kept even if the repair failed, which 
was making for a very difficult time trying to determine why my promises were 
not doing what I expected.  Based on my own logic and the implied logic of the 
classes body (as I'm not a source code guy), it would seem to me that if the 
repair failed a promise should not be called "kept" at any point.  Cfengine 
seems to be a bit premature in calling a promise kept.  The following input 
file demonstrates what I've found:

body common control
{
    bundlesequence => { "test" };
}

bundle agent test
{
    files:
        "/tmp/touchme"
            touch => "true" ,
            classes => xor("yes");

        "/tmp/notouching"
            touch => "true" ,
            classes => xor("no");

    reports:
        yes_YES::
            "YES!";
        yes_NO::
            "NO?";
        no_YES::
            "YES?";
        no_NO::
            "NO!";
}    
body classes xor(str)
{
    promise_repaired => { "$(str)_YES" };
    promise_kept =>     { "$(str)_YES" };
    #cancel_notkept =>   { "$(str)_YES" };

    repair_failed =>    { "$(str)_NO" };
    repair_denied =>    { "$(str)_NO" };
    repair_timeout =>   { "$(str)_NO" };
    #cancel_kept =>      { "$(str)_NO" };
    #cancel_repaired =>  { "$(str)_NO" };
}



My "xor" classes body if very similar to the "if_else" classes body from the 
COBPL (which has an undeclared variable in the copy included in the 3.0.4 
source) except I've added the promise_kept attribute because I want the "YES" 
class to be effective whether corrective action had to be taken or not.

In order to make the 2nd touch promise to fail, I've set the immutable 
attribute on the file (chattr +i).

# cf-agent -IKf ./xor_classes.cf
 -> Touched (updated time stamps) /tmp/touchme
Touch /tmp/notouching failed to update timestamps
 !!! System reports error for utime: "Permission denied"
R: YES!
R: YES?
R: NO!


As you can see, both the kept and failure classes are set for the 2nd promise.  
If I then add the cancel_notkept attribute, it will cancel the "YES" class and 
give me what I'm expecting (at least in this case).  If I then add in the 
cancel_kept and cancel_repaired attributes, both outcomes are cancelled since 
the promise is first marked kept, cancelling the "NO," and then marked unkept, 
cancelling the "YES" and not resetting the "NO."  I guess the normal ordering 
of classes bodies is something along the lines of "Kept or not? Failed or not?  
Apply cancels."

Now since English is the only language I speak (silly American, I know), I tend 
to think I have a pretty good understanding of it (although I probably use 
commas too much) and the English construction of logic and this just doesn't 
make sense.  Even Cfengine's own logic seems to correspond to my own since it 
obviously considers the promise "not kept" when it triggers the 
"cancel_notkept" class, but after first triggering the "promise_kept" or 
"promise_repaired" class.  If you don't have the "cancel_notkept" attribute, 
you can have a failed promised marked as kept.  Does that really make sense 
and/or is there some use case for this sort of convoluted logic?

Once again I find myself asking, is this a failure of my own logic or 
Cfengine's?  I, of course, tend to think the latter.

_______________________________________________
Help-cfengine mailing list
Help-cfengine@cfengine.org
https://cfengine.org/mailman/listinfo/help-cfengine

Reply via email to