Is this "classes" behaviour expected?

36 views
Skip to first unread message

Marco Marongiu

unread,
May 4, 2013, 9:31:38 AM5/4/13
to help-c...@googlegroups.com
Hi all

I need your help on something that is either a bug in "classes:"
promises, or my wrong understanding of how classes promises work.

I am redesigning my location detection policy, and getting some weird
results. I modelled classes and their states on paper beforehand to be
sure I got them right, and that they would be defined/undefined when I
needed that. However, during the testing phase I found out that classes
are not behaving as I expected, and I am wondering if it is a bug. I am
using 3.3.5 here.

First thing first: I expect that _all_ classes are evaluated again at
each pass. Is this correct?

Or maybe only undefined classes are re-evaluated, while classes that are
defined are not touched again?

A set of classes use some heuristics to find out if we know where we are
(e.g.: IP range), and define a class whose name starts with "location_".
Afterwards I have:

> "cached_location"
> comment => "We have a cached location",
> expression => fileexists("$(site.lmodules)/cached_location.sh") ;
>
> "defined_location"
> comment => "We have found where we are",
> expression => classmatch("location_.+") ;
>
> "cache_location"
> comment => "We know where we are, and we should make a note",
> and => { "defined_location","detect_external_ip" } ;
>
> "cached_ip"
> comment => "The cache for our current IP hasn't expired yet",
> expression => "current_ip_$(internal_ip)" ;
>
> "use_cached_location"
> comment => "We should use the location we cached before",
> expression => "cached_ip.cached_location.!defined_location" ;
>
> "detect_external_ip"
> comment => "We don't know where we are, and we must try harder",
> expression => "!defined_location.!use_cached_location" ;
>
> "expire_location"
> comment => "We must forget where we are, and check again",
> expression => "detect_external_ip" ;
>
> "current_ip_$(internal_ip)"
> expression => "any",
> persistence => "60" ;

Let's suppose it's the very first time we run this, and the first pass,
and that that I couldn't find my location using heuristics. If so:

* cached_location is false
* defined_location is also false
* cache_location is false
* cached_ip is false [internal_ip is canonify("$(sys.ipv4)")]
* use_cached_location is false
* detect_external_ip is true
* expire_location is true
* current_ip_$(internal_ip) becomes true, will stay like that for 60m

Afterwards, a module will run to collect information about our location.
Suppose the information it collects allows us to set one of the
location_* classes. What I would expecct at the second pass is:

* cached_location is false
* defined_location is true
* cache_location is true (defined_location and detect_external_ip are)
* cached_ip is true
* use_cached_location is still false (cached_location is false)
* detect_external_ip becomes false (because defined_location is true)
* expire_location becomes false (because detect_external_ip is false)
* current_ip_$(internal_ip) is true, will stay like that for 60m


What I actually get from cfengine is:

> cf3> =========================================================
> cf3> classes in bundle location (2)
> cf3> =========================================================
> cf3>
> cf3>
> cf3> . . . . . . . . . . . . . . . . . . . . . . . . . . . .
> cf3> Skipping whole next promise (essid_detected), as context on_wireless.!essid_detected is not relevant
> cf3> . . . . . . . . . . . . . . . . . . . . . . . . . . . .
> cf3> ?> defining explicit local bundle class location_oslo
> cf3> ?> defining explicit local bundle class defined_location
> cf3> ?> defining explicit local bundle class cache_location
> cf3> ?> defining explicit persistent class current_ip_192_168_10_106 (60 mins)
> cf3> ?> Warning: persistent classes are global in scope even in agent bundles
> cf3> ?> defining explicit local bundle class is_broadband
> cf3> Initiate variable convergence...
> cf3>
> cf3> + Private classes augmented:
> cf3> + cache_location
> cf3> + defined_location
> cf3> + detect_external_ip
> cf3> + expire_location
> cf3> + is_broadband
> cf3> + location_oslo
> cf3>
> cf3> - Private classes diminished:
> cf3>

Reasonably enough, everything breaks at this point...

Is it a bug or a feature?

Thanks, ciao!
-- bronto

Marco Marongiu

unread,
May 4, 2013, 4:37:45 PM5/4/13
to help-c...@googlegroups.com
Il 05/04/2013 03:31 PM, Marco Marongiu ha scritto:
> during the testing phase I found out that classes are not behaving as
> I expected, and I am wondering if it is a bug. I am using 3.3.5
> here.

Same behaviour with 3.4.4. So it's either an old bug, or I didn't
understand a sh... erm, sheep of what happens during the three passes. I
expected all classes to be re-evaluated at each pass, but I seem to be
wrong, as some of them stick with their definiteness despite an
expression that should undefine them. On the contrary, undefined classes
can become defined at a later pass.

Am I understanding it correctly now, that defined classes cannot be
undefined unless you cancel them, even if the expression that made them
defined is now false?

Any help is very much appreciated, because I am *really* confused now...

Thanks in advance, ciao!
-- bronto

Neil Watson

unread,
May 4, 2013, 5:40:33 PM5/4/13
to help-c...@googlegroups.com
On Sat, May 04, 2013 at 10:37:45PM +0200, Marco Marongiu wrote:
>Am I understanding it correctly now, that defined classes cannot be
>undefined unless you cancel them, even if the expression that made them
>defined is now false?

I believe this is a correct assertion. Classes are never undefined.

--
Neil Watson
Linux/UNIX Consultant
http://watson-wilson.ca

Marco Marongiu

unread,
May 5, 2013, 3:40:21 PM5/5/13
to help-c...@googlegroups.com
Il 05/04/2013 11:40 PM, Neil Watson ha scritto:
> On Sat, May 04, 2013 at 10:37:45PM +0200, Marco Marongiu wrote:
>> Am I understanding it correctly now, that defined classes cannot be
>> undefined unless you cancel them, even if the expression that made them
>> defined is now false?
>
> I believe this is a correct assertion. Classes are never undefined.

Thanks Neil, reworked the policy taking that into account, and it's
working wonderfully!

Ciao
-- bronto

Ted Zlatanov

unread,
May 5, 2013, 6:27:33 PM5/5/13
to Marco Marongiu, help-c...@googlegroups.com
On Sun, 05 May 2013 21:40:21 +0200 Marco Marongiu <bront...@gmail.com> wrote:

MM> Il 05/04/2013 11:40 PM, Neil Watson ha scritto:
>> On Sat, May 04, 2013 at 10:37:45PM +0200, Marco Marongiu wrote:
>>> Am I understanding it correctly now, that defined classes cannot be
>>> undefined unless you cancel them, even if the expression that made them
>>> defined is now false?
>>
>> I believe this is a correct assertion. Classes are never undefined.

MM> Thanks Neil, reworked the policy taking that into account, and it's
MM> working wonderfully!

I just wanted to mention that classes can be cancelled explicitly. See
e.g. `cancel_kept' in the classes body: http://cfengine.com/manuals/cf3-Reference#classes-in-_002a

Ted

Ted Zlatanov

unread,
May 5, 2013, 6:31:20 PM5/5/13
to Marco Marongiu, help-c...@googlegroups.com
On Sun, 05 May 2013 18:27:33 -0400 Ted Zlatanov <t...@lifelogs.com> wrote:

TZ> On Sun, 05 May 2013 21:40:21 +0200 Marco Marongiu <bront...@gmail.com> wrote:
MM> Il 05/04/2013 11:40 PM, Neil Watson ha scritto:
>>> On Sat, May 04, 2013 at 10:37:45PM +0200, Marco Marongiu wrote:
>>>> Am I understanding it correctly now, that defined classes cannot be
>>>> undefined unless you cancel them, even if the expression that made them
>>>> defined is now false?
>>>
>>> I believe this is a correct assertion. Classes are never undefined.

MM> Thanks Neil, reworked the policy taking that into account, and it's
MM> working wonderfully!

TZ> I just wanted to mention that classes can be cancelled explicitly. See
TZ> e.g. `cancel_kept' in the classes body: http://cfengine.com/manuals/cf3-Reference#classes-in-_002a

I missed Marco's note about canceling. Sorry for the noise.

Ted

Marco Marongiu

unread,
May 6, 2013, 2:19:44 AM5/6/13
to help-c...@googlegroups.com
Il 05/06/2013 12:31 AM, Ted Zlatanov ha scritto:
> TZ> I just wanted to mention that classes can be cancelled explicitly. See
> TZ> e.g. `cancel_kept' in the classes body: http://cfengine.com/manuals/cf3-Reference#classes-in-_002a
>
> I missed Marco's note about canceling. Sorry for the noise.

No problem at all ;) But since we are at it, any hope that we'll have a
cancelclasses() function, instead of having to rely on classes
attributes only?

Ciao!
-- bronto

Neil Watson

unread,
May 6, 2013, 8:27:43 AM5/6/13
to help-c...@googlegroups.com
On Mon, May 06, 2013 at 08:19:44AM +0200, Marco Marongiu wrote:
>No problem at all ;) But since we are at it, any hope that we'll have a
>cancelclasses() function, instead of having to rely on classes
>attributes only?

https://cfengine.com/dev/issues/1734

Marco Marongiu

unread,
May 6, 2013, 8:34:17 AM5/6/13
to help-c...@googlegroups.com
Il 05/06/2013 02:27 PM, Neil Watson ha scritto:
> On Mon, May 06, 2013 at 08:19:44AM +0200, Marco Marongiu wrote:
>> No problem at all ;) But since we are at it, any hope that we'll have a
>> cancelclasses() function, instead of having to rely on classes
>> attributes only?
>
> https://cfengine.com/dev/issues/1734

Yep, I remember that one :) It was not rejected (yet), so there's still
hope ;-)

Ciao!
-- bronto

Reply all
Reply to author
Forward
0 new messages