Manish Joshi
Manish Joshi

Reputation: 3770

Abort Chef recipe at run time not during compilation

I want to abort a recipe at the run time based on a certain condition but use raise or Chef::Application.fatal! as described in this post How do you abort/end a Chef run? my recipe is exiting at the compilation time only.

Here is what I am trying (a part of my script):

execute "Execute somehthing" do
  cwd node['abc']['dir']
  command "something >> #{results}"
  node.default['success'] = "false"
  notifies :run, "ruby_block[jobFailure]", :delayed
  not_if "cd #{node['abc']['dir']} && somecommand >> #{results}"
end

ruby_block "jobFailure" do
  raise "Exiting the script as the job has failed" if (node.default['success'] == "false")
  action :nothing
end

But while running the above script I am getting the error as Chef is exiting at the compilation time only giving the below error:

Running handlers:
[2014-10-27T17:17:03+00:00] ERROR: Running exception handlers
Running handlers complete
[2014-10-27T17:17:03+00:00] ERROR: Exception handlers complete
[2014-10-27T17:17:03+00:00] FATAL: Stacktrace dumped to c:/Users/manish.a.joshi/
.chef/local-mode-cache/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 12.400772 seconds
[2014-10-27T17:17:03+00:00] FATAL: RuntimeError: Exiting the script as the job has failed

Can anyone let me know if there is a way to only execute the raise command based on a condition?

Upvotes: 0

Views: 1898

Answers (2)

Tejay Cardon
Tejay Cardon

Reputation: 4223

It sounds like you only want to execute your execute block if your condition has failed. If that's the case, you could use a single resource to accomplish both tasks.

execute "Execute somehthing" do
  cwd node['abc']['dir']
  command "something >> #{results} && exit 1"
  node.default['success'] = "false"
  notifies :run, "ruby_block[jobFailure]", :delayed
  not_if "cd #{node['abc']['dir']} && somecommand >> #{results}"
end

Adding the && exit 1 will cause the execute resource to fail and thus terminate the chef run.

Of course, this only works if you want to terminate immediately. Your current code uses a :delayed notification, which means your chef run will continue until all resources have executed, and then fail during the delayed notifications. This may nor may not be what you intended.

If you really do want to terminate during the notifications, then try this (notice that setting the node attribute is not helpful)

execute "Execute somehthing" do
  cwd node['abc']['dir']
  command "something >> #{results}"
  notifies :run, "ruby_block[jobFailure]", :delayed
  not_if "cd #{node['abc']['dir']} && somecommand >> #{results}"
end

ruby_block "jobFailure" do
  block
    raise "Exiting the script as the job has failed"
  action :nothing
end

Upvotes: 1

coderanger
coderanger

Reputation: 54247

So first off Chef doesn't work like this and this code won't work as you expect regardless, but you have to put the code in actual block for the ruby_block:

ruby_block "jobFailure" do
  block do
    raise "Exiting the script as the job has failed" if (node.default['success'] == "false")
  end
  action :nothing
end

The node.default['success'] = "false" that you have in the execute resource will happen regardless of the status of the command and will happen at compile time. Chef resources do not have return values in this manner.

Upvotes: 4

Related Questions