Forum: CFEngine Help
Subject: classnames constructed with "$(foo)": how to canonify in "common"?
Author: davidlee
Link to topic: https://cfengine.com/forum/read.php?3,27082,27082#msg-27082

(cfengine community 3.3.4; RHEL 5.8)

There is a neat feature available in "classes:" which, given a list, allows a 
class to set for each item in the list.

But I've hit a warning-message problem in apparently different behaviour of it 
between "bundle agent" and "bundle common".

(Aside: Although the feature is used in a few places in the standard library, 
it seems undocumented in the reference manual.  I've just opened 1029 in the 
new bugtracker about this documentation aspect.  But you may ignore that 
documentation aspect for this my query here.)

Starting with "bundle agent":


bundle agent testbundle
{
  vars:
    "list" slist => { "one", "two", "three", "/weird/", };

  classes:
    "exists_$(list)" expression => "any";

...
}


Note that the "classes:" clause sets multiple classes, one per element in the 
list, by using "$(list)" within the name of the class being defined.

My final element "/weird/" is non-canonical.  So "cf-agent" canonifies this to 
"_weird_".  Under the "-v" flag it also produces a warning message:


cf3>    =========================================================
cf3>    classes in bundle testbundle (1)
cf3>    =========================================================
cf3>
cf3>  ?> defining explicit local bundle class exists_one
cf3>  ?> defining explicit local bundle class exists_two
cf3>  ?> defining explicit local bundle class exists_three
cf3> Class identifier "exists_/weird/" contains illegal characters - canonifying
cf3>  ?> defining explicit local bundle class exists__weird_
cf3> Initiate variable convergence...
cf3>
cf3>      +  Private classes augmented:
cf3>      +       exists__weird_
cf3>      +       exists_three
cf3>      +       exists_two
cf3>      +       exists_one


That is to be expected.  Fine.  The workaround is to do something like:


  vars:
    "list" slist => { "one", "two", "three", "/weird/", };
    "c_list[$(list)]" string => canonify("$(list)");

  classes:
    "exists_$(list)" expression => "any";
    "c_exists_$(c_list[$(list)])" expression => "any";


to get everything into canonical form (my "c_" prefix) early, then to base 
subsequent processing on that.   Although that is somewhat ugly, it is 
manageable and works.


Now, here's my problem:

Suppose I want those classes to be global, not local.  Then my "bundle agent" 
has to become "bundle common".  Something like:


bundle common g_bundle
{
  vars:
    "list" slist => { "one", "two", "three", "/weird/", };
    "c_list[$(list)]" string => canonify("$(list)");

  classes:
    "g_exists_$(list)" expression => "any";
    "g_c_exists_$(c_list[$(list)])" expression => "any";
...
}


I've added a "g_" prefix (for "global") to these classes.  But the name 
generation of the classes seems different and "cf-agent -v" throws up an 
additional bunch of warning messages:


cf3>  -> Checking common class promises...
cf3>  ?> defining additional global class g_exists_one
cf3>  ?> defining explicit global class g_exists_one
cf3>  ?> defining additional global class g_exists_two
cf3>  ?> defining explicit global class g_exists_two
cf3>  ?> defining additional global class g_exists_three
cf3>  ?> defining explicit global class g_exists_three
cf3> Class identifier "g_exists_/weird/" contains illegal characters - 
canonifying
cf3>  ?> defining additional global class g_exists__weird_
cf3>  ?> defining explicit global class g_exists__weird_
cf3> Class identifier "g_c_exists_$(c_list)" contains illegal characters - 
canonifying
cf3>  ?> defining additional global class g_c_exists___c_list_one__
cf3>  ?> defining explicit global class g_c_exists___c_list_one__
cf3> Class identifier "g_c_exists_$(c_list)" contains illegal characters - 
canonifying
cf3>  ?> defining additional global class g_c_exists___c_list_two__
cf3>  ?> defining explicit global class g_c_exists___c_list_two__
cf3> Class identifier "g_c_exists_$(c_list)" contains illegal characters - 
canonifying
cf3>  ?> defining additional global class g_c_exists___c_list_three__
cf3>  ?> defining explicit global class g_c_exists___c_list_three__
cf3> Class identifier "g_c_exists_$(c_list)" contains illegal characters - 
canonifying
cf3>  ?> defining additional global class g_c_exists___c_list__weird___
cf3>  ?> defining explicit global class g_c_exists___c_list__weird___
cf3> Initiate variable convergence...
cf3>  -> Checking common class promises...
cf3> Class identifier "g_exists_/weird/" contains illegal characters - 
canonifying
cf3> Class identifier "g_c_exists_$(c_list)" contains illegal characters - 
canonifying
cf3> Class identifier "g_c_exists_$(c_list)" contains illegal characters - 
canonifying
cf3> Class identifier "g_c_exists_$(c_list)" contains illegal characters - 
canonifying
cf3> Class identifier "g_c_exists_$(c_list)" contains illegal characters - 
canonifying


My guess is that in this "common" context it is trying to generate name which 
are literally "g_c_exists_$(c_list)".  For instance that the processing of:


  classes:
    "g_c_exists_$(c_list)" ...

 
differs between "bundle agent ..." and "bundle common ..."; that 'agent' does 
"$(foo)" expansion early, so presents "g_c_exists_one" to be defined, whereas 
'common' doesn't attempt "$(foo)" expansion, so presents that literal name with 
all its non-canonical characters as the attempted name, which the subsequent 
processing then tidies up.

Any thoughts?

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

Reply via email to