Howto use real hostnames in multiple environments according "Learning CFEngine 3" book?

36 views
Skip to first unread message

HJ Coal

unread,
Sep 30, 2015, 11:04:50 AM9/30/15
to help-cfengine
Hi,

I want to set up multiple environments according the "Learning CFEngine 3" book.
These are my files, different in environments:


root@cfe-hub:/var/cfengine/masterfiles# cat environment_none/env_promises.cf
bundle agent env_main
{
  reports
:
    cfengine
::
     
"Environment none: $(environments.active)";
}
root@cfe
-hub:/var/cfengine/masterfiles# cat environment_production/env_promises.cf
bundle agent env_main
{
  reports
:
    cfengine
::
     
"Environment prod: $(environments.active)";
}




This works:

root@cfe-hub:/var/cfengine/masterfiles# cat env1.cf
bundle common environments
{
  classes
:
     
"environment_production" or => {
                       
"cfe_hub",
     
};
  vars
:
    any
::
     
"active" string=>"none", policy=>"overridable";
    environment_production
::
     
"active" string=>"production", policy=>"overridable";
}

body common control
{
      inputs
=>{
       
"lib/3.7/stdlib.cf",
       
"environment_$(environments.active)/env_promises.cf",
     
};
      bundlesequence
=>{
           
"environments",
           
"env_main",
     
};
}
root@cfe
-hub:/var/cfengine/masterfiles# cf-agent -KIf /var/cfengine/masterfiles/env1.cf
R
: Environment prod: production




Now, I want to have real hostnames, this works too:

root@cfe-hub:/var/cfengine/masterfiles# cat /var/cfengine/masterfiles/env2.cf
bundle common environments
{
  classes
:
     
"environment_production" expression  => classify("cfe-hub");

  vars
:
    any
::
     
"active" string=>"none", policy=>"overridable";
    environment_production
::
     
"active" string=>"production", policy=>"overridable";
}

body common control
{
      inputs
=>{
       
"lib/3.7/stdlib.cf",
       
"environment_$(environments.active)/env_promises.cf",
     
};
      bundlesequence
=>{
           
"environments",
           
"env_main",
     
};
}
root@cfe
-hub:/var/cfengine/masterfiles# cf-agent -KIf /var/cfengine/masterfiles/env2.cf
R
: Environment prod: production



But when I want to use a slist for the hosts:

root@cfe-hub:/var/cfengine/masterfiles# cat /var/cfengine/masterfiles/env3.cf
bundle common environments
{
  vars
:
    any
::
     
"prod_hosts" slist => {
               
"cfe-hub",
     
};

  classes
:
     
"environment_production" expression  => classify("$(prod_hosts)");

  vars
:
    any
::
     
"active" string=>"none", policy=>"overridable";
    environment_production
::
     
"active" string=>"production", policy=>"overridable";
}

body common control
{
      inputs
=>{
       
"lib/3.7/stdlib.cf",
       
"environment_$(environments.active)/env_promises.cf",
     
};
      bundlesequence
=>{
           
"environments",
           
"env_main",
     
};
}
root@cfe
-hub:/var/cfengine/masterfiles# cf-agent -KIf /var/cfengine/masterfiles/env3.cf
R
: Environment none: production



What is my mistake? What is the right way?
How can I use real hostnames (not canonified) with multiple environment?


root@cfe-hub:/var/cfengine/masterfiles# cf-agent -V
CFEngine Core 3.7.1



HJ

Nick Anderson

unread,
Sep 30, 2015, 11:17:44 AM9/30/15
to help-cfengine, HJ Coal
Try canonify instead of classify

Sent from my mobile device.
--
You received this message because you are subscribed to the Google Groups "help-cfengine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to help-cfengin...@googlegroups.com.
To post to this group, send email to help-c...@googlegroups.com.
Visit this group at http://groups.google.com/group/help-cfengine.
For more options, visit https://groups.google.com/d/optout.

HJ Coal

unread,
Oct 1, 2015, 5:43:20 AM10/1/15
to help-cfengine, hjk...@gmail.com


Am Mittwoch, 30. September 2015 17:17:44 UTC+2 schrieb Nick Anderson:
Try canonify instead of classify

I replaced classify with canonify, but the result is the same.


The following works:
 
  classes:
     
"environment_production" or  => {
                    classify
("cfe-hub"),
                    classify
("cfe-2nd"),
                    classify
("cfe-3rd"),
                   
};

(canonifiy does not work here, because of type conflict)

root@cfe-hub:~# cf-agent -KIf /var/cfengine/masterfiles/env4.cf
R
: Environment prod: production






But once I try to use a variable, it behaves strange:

 
  vars:
    any
::
     
"host" string => "cfe-hub";

  classes
:
     
"environment_production" or  => {
                    classify
($(host)),
                    classify
("cfe-2nd"),
                    classify
("cfe-3rd"),
                   
};

root@cfe-hub:~# cf-agent -KIf /var/cfengine/masterfiles/env4.cf
R
: Environment none: production





Neil Watson

unread,
Oct 1, 2015, 7:18:56 AM10/1/15
to help-cfengine
My Guess is that 'or' and iteration are not getting along. Try this
instead:

body common control
{
bundlesequence => { "main", };
}

bundle agent main
{
vars:
"myhosts" slist => { "one", "two", "three", "ettin" };

classes:
"prod_env" expression => classify( "${myhosts}" );

reports:
prod_env::
"I am in prod!";
}

neil@ettin ~/.cfagent/inputs $ cf-agent -Kf ./hjcoal.cf
R: I am in prod!

'Or' expects a list on its right side so or => { @{myhosts} } would
work, but you need to canonify that list. You could do that in vars
before hand, but my example is probably fine.

-
Neil H Watson
Sr. Partner, Architecture and Infrastructure
CFEngine reporting: https://github.com/evolvethinking/delta_reporting
CFEngine policy: https://github.com/evolvethinking/evolve_cfengine_freelib
CFEngine and vim: https://github.com/neilhwatson/vim_cf3
CFEngine support: http://evolvethinking.com

HJ Coal

unread,
Oct 1, 2015, 8:50:00 AM10/1/15
to help-cfengine, cfen...@watson-wilson.ca
Ok, but when I try to adapt your example to dynamically select the environment, it fails:

root@cfe-hub:/var/cfengine/masterfiles# cat /var/cfengine/masterfiles/hjcoel.cf
body common control
{
      bundlesequence
=> { "main", "env_main"};
      inputs
=>{
       
"hjcoel_env_$(main.active).cf",
     
};

}

#bundle common main
bundle agent main
{
  vars
:
     
"myhosts" slist => { "one", "two", "three", "ettin", "cfe-hub" };


  classes
:
     
"prod_env" expression => classify( "${myhosts}" );

     
#"prod_env" or => { "one", "two", "three", "ettin", "cfe_hub" };


  vars
:
    any
::
     
"active" string=>"none", policy=>"overridable";

    prod_env
::

     
"active" string=>"production", policy=>"overridable";


  reports
:
    prod_env
::
     
"Bundle: $(this.bundle), I am in prod! Environment $(main.active)";
}

hjcoel_env_none.cf and hjcoel_env_production.cf have the same content:

root@cfe-hub:/var/cfengine/masterfiles# cat /var/cfengine/masterfiles/hjcoel_env_none.cf
bundle agent env_main
{
  reports
:
     
"Bundle: $(this.bundle), Environment: $(main.active), File: $(this.promise_filename)";
}


I would expect that the file hjcoel_env_production.cf is selected, because $(main.active) is equal to "production", but:

root@cfe-hub:/var/cfengine/masterfiles# cf-agent -Kf /var/cfengine/masterfiles/hjcoel.cf
R
: Bundle: main, I am in prod! Environment production
R
: Bundle: env_main, Environment: production, File: /var/cfengine/masterfiles/hjcoel_env_none.cf


Only if I modify hjcoal.cf to enable the commented entries, the expected output comes:

root@cfe-hub:/var/cfengine/masterfiles# cf-agent -Kf /var/cfengine/masterfiles/hjcoel.cf
R
: Bundle: main, I am in prod! Environment production
R
: Bundle: env_main, Environment: production, File: /var/cfengine/masterfiles/hjcoel_env_production.cf


I find that strange.

Neil Watson

unread,
Oct 1, 2015, 11:51:29 AM10/1/15
to help-cfengine
My guess is it is something to do with how much is evaluated to figure
out inputs and bundlesequence. It's a complex process, which is one
reason that autorun was developed. I recommend you try that instead. It
has the added bonus of not having to mess with promises.cf.

Use CFEngine's mastefiles autorun policy to make cf-agent automatically run
policies in certain directories. See
https://digitalelf.net/2014/07/a-primer-on-cfengine-3-dot-6-autorun/ and a
working example:
https://github.com/evolvethinking/evolve_cfengine_freelib/blob/master/INSTALL.md
and
https://github.com/evolvethinking/evolve_cfengine_freelib/blob/master/masterfiles/services/autorun/efl.cf

--
Reply all
Reply to author
Forward
0 new messages