0
votes

Simple, albeit newb question regarding convergence v.s. compile time. Say I have the following library in a custom cookbook

libraries/foo.rb

class Chef::Recipe::Foo

  attr_accessor :bar

  def initialize()
    @bar = {}
  end
end

I then try to set the instance property bar within a ruby_block before logging an inspection

recipes/default.rb

foo = Foo.new

ruby_block "set_hash" do
  block do
    foo.bar = {'key' => 'val'}
  end
  action :run
  notifies :write, "log[inspect_hash]", :immediately
end

log "inspect_hash" do
  message foo.bar.inspect
  action :nothing
end

Which outputs an empty hash

INFO: Processing ruby_block[set_hash] action run (cookbook::default line 12)
INFO: ruby_block[set_hash] called
INFO: ruby_block[set_hash] sending write action to log[inspect_hash] (immediate)
INFO: Processing log[inspect_hash] action write (cookbook::default line 20)
INFO: {}

According to the docs, during the above run, class Foo should have been instantiated as the recipe was compiled and the ruby_block evaluated as a Chef resource

Ruby code in the ruby_block resource is evaluated with other resources during convergence, whereas Ruby code outside of a ruby_block resource is evaluated before other resources, as the recipe is compiled.

Am I missing something here?

1

1 Answers

1
votes

You should use the run_state to store such variables spanning over multiple resources:

ruby_block "set_hash" do
  block do
    node.run_state['foo'] = {'key' => 'val'}
  end
  action :run
  notifies :write, "log[inspect_hash]", :immediately
end

log "inspect_hash" do
  lazy { message node.run_state['foo'] }
  action :nothing
end