Search code examples
rubychef-infrachef-recipe

Chef - Run resource on other resource's failure


I have two execute resources called command_1 and command_2.

If command_1 fails, I want to run command_2and then re-run command_1.

Pretty much like this:

execute 'command_1' do
  command "ipa host-del #{machine_name}"
  action :run
  ignore_failure true
  on_failure { notifies :run, 'execute['command_2']', :immediately }
end

execute 'command_2' do
  command "ipa host-mod --certificate  #{machine_name}"
  action :nothing
  notifies :run, 'execute['command_1']', :immediately
end

How can I replace on_failure (would be great if Chef had this one) by something that actually works ?


Solution

  • Your best bet is to put command_2 first and then guard it by checking if it needs to be run or not. I'm not sure what that command does, but if it is possible to verify somehow if it is needed or not, then you could do things this way.

    If there is no way to verify whether or not command_2 is needed, then you could do something like this instead:

    execute 'command_1' do
      command "ipa host-del #{machine_name} && touch /tmp/successful"
      action :run
      ignore_failure true
    end
    
    execute 'command_2' do
      command "ipa host-mod --certificate  #{machine_name}"
      action :run
      notifies :run, 'execute['command_1']', :immediately
      not_if { ::File.exist? '/tmp/successful' }
    end
    
    file '/tmp/successful' do
      action :delete
    end
    

    This will run command_1 and if it is successful it will touch /tmp/successful. command_2 will then run, but only if /tmp/successful does not exist. IF command_2 does run, it will then notify command_1 to run again immediately. To clean up for the next run, we then add the file resource to ensure /tmp/successful is removed