'if'/'ifvarclass' is not defined"

44 views
Skip to first unread message

mt...@quoininc.com

unread,
Sep 26, 2017, 1:49:34 PM9/26/17
to help-cfengine
After talking with some people in the cfengine freenode.net irs room, it was suggested that I submit this to the mail group to get more eyes on a possible bug I've found.

1. Using Vagrant, I've got an Ubuntu 14.04.5 server, and I'm using CFEngine Core 3.11.0.  I've set both of those up without any initial changing (Vagrantfile below in case it's of interest).

2. As root, I run this command:

/var/cfengine/bin/cf-agent --no-lock --verbose

3. I see a lot of messages indicating promises are being skipped, and all for the same reason 'if'/'ifvarclass' is not defined".  Example:

verbose: BEGIN parsing file: /var/cfengine/inputs/controls/def.cf
verbose: END   parsing file: /var/cfengine/inputs/controls/def.cf
verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined

The log indicates that this happens in the "Loading policy" section, right after the def.cf file is parsed.  I see these messages multiple times on the same run, so I don't think it's a matter of it not being defined on the first pass and then being defined later.  I think it's not getting defined during this run, period.

4. Looking at the "mailto" promise in the def.cf policy file...

      "mailto"
        string => "root@$(def.domain)",
        ifvarclass => not(isvariable("mailto"));

... gives me the impression this promise is supposed to define "mailto" as "root@$(def.domain)" if it's not already defined.

5. To test whether this is happening, I created a small test policy (provided in detail below) to report the value of "mailto."  It was not defined when I ran my policy.  It's not even getting a default, apparently.

6. For a workaround, I can define "def.mailto" in /var/cfengine/inputs/def.json (file provided below), and then the message goes away for mailto.  But there are many other variables that still have this message in the logs, and it seems like I shouldn't have to do this when def.cf is supposed to be defining default values if they aren't defined.

I suspect that the error isn't actually saying that the variable "mailto" isn't defined.  I suspect that the issue is that "ifvarclass" itself is not defined at this point.  Could that be?



VagrantFile

Vagrant.configure("2") do |config|

 config.vm.define "policy_server", primary: true do |policy_server| 
   policy_server.vm.box = "ubuntu/trusty64" 
   policy_server.vm.hostname = "cfengine-policy-server" 
   policy_server.vm.network "private_network", ip: "192.168.50.2" 

   policy_server.vm.provider :virtualbox do |v| 
     v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 
     v.customize ["modifyvm", :id, "--memory", 512] 
     v.customize ["modifyvm", :id, "--name", "cfengine-policy-server"] 
   end 

   policy_server.vm.provision "shell", inline: <<-SHELL 
     /var/cfengine/bin/cf-agent --bootstrap 192.168.50.2 
     apt-get install -y git 
     git config --global user.name "********" 
     git config --global user.email "*********" 
   SHELL 
 end 

 config.vm.define "host" do |host| 
   host.vm.box = "ubuntu/trusty64" 
   host.vm.hostname = "cfengine-host" 
   host.vm.network "private_network", ip: "192.168.50.3" 

   host.vm.provider :virtualbox do |v| 
     v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 
     v.customize ["modifyvm", :id, "--memory", 512] 
     v.customize ["modifyvm", :id, "--name", "cfengine-host"] 
   end 

   host.vm.provision "shell", inline: <<-SHELL 
     dpkg -i cfengine-community_3.10.2-1_amd64-debian4.deb 
     /var/cfengine/bin/cf-agent --bootstrap 192.168.50.2 
   SHELL 

 end 

end


/var/cfengine/inputs/testing.cf

body common control
{
  bundlesequence => { 'testing' };
}

bundle agent testing
{
  reports:
    "def.mailto is set to $(def.mailto)";


/var/cfengine/inputs/def.json

{
  "vars": {
    "def.mailto": "te...@example.com"
  }
}






Nick Anderson

unread,
Sep 26, 2017, 10:49:21 PM9/26/17
to help-cfengine
Hi

Thanks for the vagrant source to reproduce your environment, very helpful.

I also see all of the verbose promise skip messages but I think they may be
misleading us. I added a reports promise in =services/main.cf= to emit =mailto
$(def.mailto)= and it did report =mailto root@= (there is no domain configured
on the hub in the vagrant environment). I removed that promise and then I
checked the final evaluation state and it also showed that =def.mailto= was
defined as =root@=.

 #+BEGIN_EXAMPLE
 cf-agent -Kv --show-evaluated-vars | grep mailto
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
 verbose: Skipping promise 'mailto' because 'if'/'ifvarclass' is not defined
default:control_executor.mailto          root@                                                        source=promise                          
default:def.mailto                       root@                                                        source=promise    
#+END_EXAMPLE

> To test whether this is happening, I created a small test policy (provided in
> detail below) to report the value of "mailto." It was not defined when I ran
> my policy. It's not even getting a default, apparently.

Your test policy was completely standalone and didn't include the promise to
define =def.mailto=.

#+BEGIN_SRC cfengine3
  body common control
  {
          bundlesequence => { 'testing' };
  }

  bundle agent testing
  {
    reports:
        "def.mailto is set to $(def.mailto)";
  }
#+END_SRC

#+RESULTS:
: R: def.mailto is set to $(def.mailto)

But if your test had included =def.cf=, then your reports promise would have
emitted =root@= as well.

#+BEGIN_SRC cfengine3
  body common control
  {
          bundlesequence => { 'testing' };
          inputs => { "$(sys.inputdir)/controls/def.cf" };
  }

  bundle agent testing
  {
    reports:
        "def.mailto is set to $(def.mailto)";
  }
#+END_SRC

#+RESULTS:
: R: def.mailto is set to root@

Side note: For standalone examples you can call your entry bundle =main= and
then skip the =body common control=.

#+BEGIN_SRC cfengine3
  bundle agent main
  {
    reports:
        "Running CFEngine $(sys.cf_version)";
  }
#+END_SRC

> For a workaround, I can define "def.mailto" in /var/cfengine/inputs/def.json
> (file provided below), and then the message goes away for mailto. But there are
> many other variables that still have this message in the logs, and it seems like
> I shouldn't have to do this when def.cf is supposed to be defining default
> values if they aren't defined.

Also note the augments file (=def.json=) works when it's next to the policy
entry. So =/tmp/testing.cf= with =/tmp/def.json= work the same way.

> I suspect that the error isn't actually saying that the variable "mailto" isn't
> defined. I suspect that the issue is that "ifvarclass" itself is not defined at
> this point. Could that be?

I agree, there is something fishy in the logging.

Reply all
Reply to author
Forward
0 new messages