Search code examples
puppet

Puppet: Evaluating variables inside onlyif close


I have a variable that I set at a very early stage, the variable is boolean, then at some point I want to exec a command based on the fact if this variable is true or false, something like this:

exec { 'update-to-latest-core': 
  command     => "do something",
  user        => 'root',
  refreshonly => true,
  path        => [ "/bin/bash", "sbin/" , "/usr/bin/", "/usr/sbin/" ], 
  onlyif      => 'test ${latest} =      true',
  notify      => Exec["update-to-latest-database"],
}

So this command doesn't work (onlyif => ['test ${latest} = true'],) I tried several other ways too, but didn't work. Something so simple cannot be so hard to do. Can someone help me with this, and also explain the rules behind getting commands to execute inside onlyif close. (also I cannot use if-close on a higher level because I have other dependencies )


Solution

  • Since $latest is a Puppet variable, it is not useful to defer checking its value until the catalog is applied. Technically, in fact, you cannot do so: Puppet will interpolate the variable's value into the Exec resource's catalog representation, so there is no variable left by the time the catalog is applied, only a literal.

    Since the resource in question is notified by another resource, you must not suppress it altogether. If the code presented in your question does not work, then it is likely because the interpolated value of $latest is different than you expect -- for example, '1' instead of 'true'. Running the agent in --debug mode should show you the details of the command being executed.

    Alternatively, you could approach it a different way:

    exec { 'update-to-latest-core': 
      command     => $latest ? { true => "do something", default => '/bin/true' },
      user        => 'root',
      refreshonly => true,
      path        => [ "/bin/bash", "sbin/" , "/usr/bin/", "/usr/sbin/" ], 
      notify      => Exec["update-to-latest-database"],
    }
    

    That will execute (successfully, and with no external effect) whenever $latest is false, and it will run your do something command whenever $latest is true. The choice of command is made during catalog building.