Dynamic recipe depended in run time


I’m trying to create a recipe that unzip some files then the behavior is depend on the content of the zipfile.
but I can’t figure put how to overcome the Compile vs Converge phase.

The directories are not exists before the recipe is executed so the command to get the sub directories must be inside a ruby block to fetch the data in runtime.

But once the command is inside the ruby block I can’t “read” the new values of the variables or attributes.

here is a sample:

ruby_block 'update patch attributes' do
   block do
      Subdir_list = Dir.glob("#{OPatchPath}/*/")

      Subdir_list.each do |dir|
         Subdir_list.map! {|dir| dir.sub("#{OPatchPath}/", "")}
         Subdir_list.map! {|dir| dir.sub('/', "")}


## if there are no directories with numberes 
if Subdir_list.find { |e| /^\d+$/ =~ e } == nil
   do something
   if Subdir_list.count == 2
      do something else
      do some other something

I did a deep research online and tried a lot of suggestions include using lazy, node.set, node.default node.run_state with no luck.
what am I missing?
any suggestions?

Thanks, Ofir.

help anyone?

For me it would depend on what you were going to use the “do something”, “do something else” or “do some other something”.

I would personally use only_if or not_if as they are executed just before the resource is executed.

Lazy is good for when you need to lazy and attribute that is in a resource. This doesn’t work for all resources though.

You can always create chef resources within a ruby block. For example you can create a ruby block with the if and construct the necessary resource

ruby_block “#{cookbook_name}_#{recipe_name}_add_sql_service_2_group” do
block do
res = Chef::Resource::Group.new(‘Administrators’, run_context)
res.members [service_account]
res.append true
res.run_action :modify