9

Let us say I have some Chef code like:

require 'mixlib/shellout'
yum_package 'somepackage'
myvar =  Mixlib::ShellOut.new('/bin/somecommand').run_command.stdout.strip

Where /bin/somecommand does not exist yet because it is installed by somepackage. This will fail at recipe compile time for that reason, but will obviously work at convergence time providing the package installs successfully (and if it doesn't then obviously the recipe has failed anyway). This also fails if the package is installed be a previous recipe in the runlist since they are all compiled together upfront. How do I include things in a Chef recipe that that recipe or runlist installs itself?

4
  • This sort of thing isn't a problem in CFEngine
    – Gaius
    Commented Sep 24, 2017 at 13:24
  • 1
    Without insight on the use of myvar there's no real answer, usually I avoid using code evaluation from external commands at compile time unless very necessary to define other resources. In brief, I'd do a ruby_block 'set myvar' { node.run_state['myvar'] = Mixlib::ShellOut.[...] }
    – Tensibai
    Commented Sep 25, 2017 at 8:30
  • @Tensibai node.run_state was exactly what I was looking for - thanks. Make that an answer and I'll accept it!
    – Gaius
    Commented Sep 25, 2017 at 19:24
  • That will have to wait until tomorrow :) too hard to write a correct answer on phone
    – Tensibai
    Commented Sep 25, 2017 at 19:30

2 Answers 2

4

I'd go with node.run_state to store a transient variable in a run and define it in a ruby_block so it happens at converge time, something like this:

yum_package 'somepackage'

ruby_block 'set myvar' do
  block do
    node.run_state['my_var'] = Mixlib::ShellOut.new('/bin/somecommand').run_command.stdout.strip
  end
end

As far as I know requiring 'mixlib/shellout' is not necessary.

2

The specifics depend on the exact use case. If the value is only used as a property on another resource, you would use the lazy helper method. If you don't need the output, you would use the execute resource. In some more complex cases you might use a ruby_block resource or write your own custom resource.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.