Howdy again,

I tried to send a patch to this list in February
but it bounced due to taking too long to get to
the mailhost.  Not sure what's up with that.  In any
case, I had posted a fix to the SourceForge and I'm
faily certain Mark got CC's, so I didn't sweat it.

However, since this is still broken, I'll try again.

Here, in short, is the problem.

Negated installable classes are treated differently
than other classes depending upon the actionsequence
being processed.

Say I have 3 installable classes A, B and C and
a predefined class that is always true (say "any").
Say they have the current truth values:

  A = true
  B = false
  C = false
  (any = true # by definition in cfengine)

If I write:

   A.!B.!C::  (A and not B and not C which should be true)

then, in my understanding, given 5+ years of using
cfengine, is that the resulting action should be
performed.  However, it is NOT for some actions
(e.g. editfiles).

If I write:

  any.!B.!C:: 

it works however, despite the fact that when the rule
is evaluated both "A" and "any" have the same, true, value.

Furthermore, if I write:

  A.!(B|C):: (A and neither B nor C)

it works, even though DeMorgan's rule says that
not B and not C should be equivalent to neither
B nor C.  [ !B.!C == !(B|C) ]

I don't think I should have to remember which classes
are installable, and thus required to invoke DeMorgan
everytime I use them to get the correct answer.  It pretty
much make installable classes worthless and doesn't inspire
me with confidence [I've been fighting this bug for nearly
a year now and finally think I understand why cfengine refuses
to take care of the things I thought it was taking care of].

So, here again is the patch and the latest test case
which demonstrates the problem almost as concisely as
I can make it.  Could someone, other than Mark who's
been busy, look it over with the latest SVN version
and either:

1) explain to me what I'm not understanding and
   why the current behavior is not a bug/incorrect

or

2) develop a cleaner/better test case and explanation
   since I'm obviously not making a convincing argument
   on why this is wrong and needs to be fixed (and then
   convince Mark)

or

3) develop a better patch to more properly fix the problem
   (and then convince Mark to apply it)

If someone could do one of the 3 before then end of
April when 2.2.6 is due to be release, I would sincerely
appreciate it.  It's a bit frustrating at this point
that I'm either not getting it or I'm not convincing 
others of the, not inconsequential, problem.[*]

Thanks,

jack/Slick

[*] I expect such from Redhat[**] but thought I'd have
    better luck here

[**] https://bugzilla.redhat.com/show_bug.cgi?id=146291
     posted (along with a fix), more than 3 years ago...
     still broken


   



On Tue, 2008-01-08 at 20:38 +0100, Mark Burgess wrote:
> This is a quick reply, as I am very busy and non-urgent bugs will take
> some time to address.
> 
> I have looked through this mail several times now, and I cannot decide
> what bug is being reported. I shall certainly look at the conditional
> evaluation, but you have already found a workaround for that.
> 
> In short, it is not clear to me whether there is an actual bug here as
> there is not enough information to see what you are trying.
> 
> Looking at my current schedule, it will take me several weeks to
> before I can spend any time on this. I recommend finding a workaround
> for the problem you are having, and perhaps providing more information
> about the exact syntax you are using. (Apologies if you have provided
> this on the sourceforge site - I have not gone into depth there)
> 
> Mark
> 
> SiliconSlick wrote:
> > Howdy cfengineers,
> > 
> > I filed a bug last month at the sourceforge and
> > haven't seen any notice of attention.  On
> > #cfengine I was told I'd have better luck here.
> > 
> > The report is at:
> > 
> > http://sourceforge.net/tracker/index.php?func=detail&aid=1848895&group_id=126712&atid=706640
> > 
> > but I'll repeat it here just in case.
> > 
> > ======================================================
> > 
> > I'm having a problem with cfengine 2.2.3 involving
> > conditionals/group testing in the editfiles section.
> > 
> > I've attached a test case. It still has some
> > crud from the original task I was using it for
> > so it has to be run with sudo (in order to stop
> > cups).
> > 
> > Basically, what I was trying to do is:
> > 1) stop cupsd
> > 2) add a printer definition to /etc/cups/printers.conf
> > 3) restart cupsd
> > 
> > However, it didn't work at first. The is something
> > wrong with the conditional testing in the editfiles.
> > I had to rewrite the rule using DeMorgan's law in order
> > for cfengine to do the right thing, but I shouldn't have too.
> > 
> > When I run it, I get something like this:
> > =============
> > $ sudo ./cfbug.cf
> > Password:
> > cfengine:myhost:nit.d/cups stop: Stopping cups: [ OK ]
> > cfengine:myhost:nit.d/cups star: Starting cups: [ OK ]
> > cfengine:myhost: linux, and centos, and cups stopped, and not a print
> > server, and don't have G85 (should foo)
> > cfengine:myhost: linux, and centos, and cups stopped, and not a print
> > server or have G85 (should bar)
> > cfengine:perrymason: did bar
> > $ cat /tmp/foo
> > $ cat /tmp/bar
> > bar
> > =============
> > 
> > Note that conditional for the alert and the edit files is the same. That
> > is, if it shows the "should foo" alert then it should similarly make the
> > edit to /tmp/foo. However, it doesn't.
> > 
> > I have a feeling it has something to do with a limit on
> > the number of conditionals that the editfiles section
> > is looking at (i.e. only seems ot have the problem
> > when there are 5 or more conditions), but I'm
> > not sure.
> >                                                                             
> >                                                                             
> >           
> > ======================================================
> > 
> > The revised/cleaned-up test case is attached.
> > 
> > Any help appreciated.
> > 
> > jack/slick
> > 
> > 
> > 
> > ------------------------------------------------------------------------
> > 
> > _______________________________________________
> > Bug-cfengine mailing list
> > [email protected]
> > https://cfengine.org/mailman/listinfo/bug-cfengine
#!/tmp/cfengine-svn/src/cfagent -f  
## above line uses 2.2.x from SVN in /tmp
##/usr/sbin/cfagent -f                
## above line uses 2.2.x from RPM (RPMForge's)

# example to show bug involving negated installable classes in rule clauses
# fix the path on the first line and chmod 755

control:
  actionsequence = ( shellcommands editfiles shellcommands editfiles 
shellcommands ) # last two are overkill but just in case

groups:
  special = ( hostABC ) # define a group of "special" hosts (not this one)

shellcommands:
  !special:: "/bin/cat /dev/null > /tmp/foo" umask=033 # blank file
  !special:: "/bin/cat /dev/null > /tmp/bar" umask=033 # blank file
  !special:: "/usr/bin/test -S /tmp/foo" define=some_class # should fail to 
define 
  !special.!some_class:: "/bin/echo did something" define=did_something # 
should define

alerts:
  did_something.!special.!some_class::  # this works
    "did something, and not special, and not some class (should foo)"
  did_something.!(special|some_class):: # and this
    "did something, and not special or some class (should bar)"

editfiles:
  # At this poing, the following should be the case:
  #   did_something = true
  #   special = false
  #   some_class = false
  #   any = true

  did_something.!special.!some_class::
  # However, THIS DOESN'T WORK???  same condition as above in the alerts (where 
it works right)
  { /tmp/foo
    AppendIfNoSuchLine "foo"
    DefineClasses "did_foo"
  }

  # DeMorgan's Law to the rescue (works)
  did_something.!(special|some_class)::
  { /tmp/bar
    AppendIfNoSuchLine "bar"
    DefineClasses "did_bar"
  }

  # replace "did_something" from the failed case above with "any"... both of 
which should be true
  any.!special.!some_class::
  # This DOES work????  even though any == true == did_something.
  # Pretty sure this has to do with installable classes and negation in rule 
clauses
  { /tmp/foo
    AppendIfNoSuchLine "foobar"
    DefineClasses "did_foobar"
  }

alerts:
  did_foo:: "did foo"
  did_bar:: "did bar"
  did_foobar:: "did foobar"

shellcommands:
  did_something.(did_foo|did_bar):: "/bin/echo undid something"

# EOF
diff -ur cfengine-2.2.3/src/eval.c cfengine-2.2.3.ss/src/eval.c
--- cfengine-2.2.3/src/eval.c	2007-09-16 14:26:16.000000000 -0500
+++ cfengine-2.2.3.ss/src/eval.c	2008-02-26 15:57:11.000000000 -0600
@@ -561,7 +561,7 @@
    return true;
    }
 
-ret = EvaluateORString(class,VADDCLASSES);
+ret = EvaluateORString(class,VADDCLASSES,0);
 
 return ret;
 }
@@ -597,7 +597,7 @@
  
 /* return (EvaluateORString(buffer,VALLADDCLASSES)||EvaluateORString(class,VADDCLASSES));*/
 
-val = (EvaluateORString(buffer,VALLADDCLASSES)||EvaluateORString(class,VALLADDCLASSES)||EvaluateORString(class,VADDCLASSES));
+val = (EvaluateORString(buffer,VALLADDCLASSES,0)||EvaluateORString(class,VALLADDCLASSES,1)||EvaluateORString(class,VADDCLASSES,0));
 
 if (val)
    {
@@ -650,7 +650,7 @@
 /* Level 2                                                           */
 /*********************************************************************/
 
-int EvaluateORString(char *class,struct Item *list)
+int EvaluateORString(char *class,struct Item *list,int fromIsInstallable)
 
 { char *sp, cbuff[CF_BUFSIZE];
   int result = false;
@@ -683,12 +683,12 @@
       {
       cbuff[strlen(cbuff)-1] = '\0';
 
-      result |= EvaluateORString(cbuff+1,list);
+      result |= EvaluateORString(cbuff+1,list,fromIsInstallable);
       Debug4("EvalORString-temp-result-y=%d (%s)\n",result,cbuff+1);
       }
    else
       {
-      result |= EvaluateANDString(cbuff,list);
+      result |= EvaluateANDString(cbuff,list,fromIsInstallable);
       Debug4("EvalORString-temp-result-n=%d (%s)\n",result,cbuff);
       }
 
@@ -706,7 +706,7 @@
 /* Level 3                                                           */
 /*********************************************************************/
 
-int EvaluateANDString(char *class,struct Item *list)
+int EvaluateANDString(char *class,struct Item *list,int fromIsInstallable)
 
 { char *sp, *atom;
   char cbuff[CF_BUFSIZE];
@@ -744,7 +744,7 @@
       
       cbuff[strlen(cbuff)-1] = '\0';
       
-      if (EvaluateORString(atom,list))
+      if (EvaluateORString(atom,list,fromIsInstallable))
          {
          if (negation)
             {
@@ -813,7 +813,7 @@
       } 
    else if (IsItemIn(list,atom))
       {
-      if (negation)
+      if (negation && !fromIsInstallable)
          {
          Debug4("EvaluateANDString(%s) returns false by negation 2\n",class);
          return false;
diff -ur cfengine-2.2.3/src/filters.c cfengine-2.2.3.ss/src/filters.c
--- cfengine-2.2.3/src/filters.c	2007-07-20 02:40:04.000000000 -0500
+++ cfengine-2.2.3.ss/src/filters.c	2008-02-26 15:57:11.000000000 -0600
@@ -597,7 +597,7 @@
       
       DoProc(&tests,fp->criteria,names,line);
       
-      if (tmpres = EvaluateORString(fp->criteria[filterresult],tests))
+      if (tmpres = EvaluateORString(fp->criteria[filterresult],tests,0))
          {
          AddMultipleClasses(fp->defines);
          }
@@ -649,7 +649,7 @@
       
       DoFilter(&tests,fp->criteria,lstatptr,file);
       
-      if (tmpres = EvaluateORString(fp->criteria[filterresult],tests))
+      if (tmpres = EvaluateORString(fp->criteria[filterresult],tests,0))
          {
          AddMultipleClasses(fp->defines);
          }
@@ -972,7 +972,7 @@
    }
 #endif
  
-if (EvaluateORString(crit,attrib))
+if (EvaluateORString(crit,attrib,0))
    {
    DeleteItemList(attrib);
    return true;
@@ -1173,7 +1173,7 @@
    PrependItem(&attrib,"none",""); 
    }
  
-if (EvaluateORString(crit,attrib))
+if (EvaluateORString(crit,attrib,0))
    {
    DeleteItemList(attrib);
    return true;
@@ -1205,7 +1205,7 @@
    PrependItem(&attrib,"none",""); 
    }
  
-if (EvaluateORString(crit,attrib))
+if (EvaluateORString(crit,attrib,0))
    {
    DeleteItemList(attrib);
    return true;
diff -ur cfengine-2.2.3/src/prototypes.h cfengine-2.2.3.ss/src/prototypes.h
--- cfengine-2.2.3/src/prototypes.h	2007-11-21 11:13:32.000000000 -0600
+++ cfengine-2.2.3.ss/src/prototypes.h	2008-02-26 15:57:11.000000000 -0600
@@ -320,8 +320,8 @@
 int IsInstallable (char *class);
 void AddPrefixedMultipleClasses (char *prefix,char *class);
 void NegateCompoundClass (char *class, struct Item **heap);
-int EvaluateORString (char *class, struct Item *list);
-int EvaluateANDString (char *class, struct Item *list);
+int EvaluateORString (char *class, struct Item *list,int fromIsInstallable);
+int EvaluateANDString (char *class, struct Item *list,int fromIsInstallable);
 int GetORAtom (char *start, char *buffer);
 int GetANDAtom (char *start, char *buffer);
 int CountEvalAtoms (char *class);
_______________________________________________
Bug-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/bug-cfengine

Reply via email to