How to mark a ruby_block as failed?


#1

Cheers,

I’m using a ruby_block to handle complex operations with mdadm in
Chef. My question is, how do I tell Chef that my block failed and
execution should halt with an error? In pseudo code:

ruby_block “A complex operation” do
block “using mdadm” do
output = do something
if $?.success?
Chef::Log.info output
else
Chef::Log.error output
# tell chef we failed
end
end
end

This would of course be easier if I could just use the execute
resource in the ruby_block…

Thanks,
Jonathan


Jonathan Weiss
http://blog.innerewut.de
http://twitter.com/jweiss


#2

Hi,

On Tue, Dec 21, 2010 at 12:20 PM, Jonathan Weiss jw@innerewut.de wrote:

I’m using a ruby_block to handle complex operations with mdadm in
Chef. My question is, how do I tell Chef that my block failed and
execution should halt with an error? In pseudo code:

ruby_block “A complex operation” do
block “using mdadm” do
output = do something
if $?.success?
Chef::Log.info output
else
Chef::Log.error output
# tell chef we failed
end
end
end

This would of course be easier if I could just use the execute
resource in the ruby_block…

You can use raise to throw an exception:

if !success
Chef::Log.fatal(“here’s some info about why I’m crashing out”)
raise "you can put some msg here too"
end


#3

Hi there!

You can use execute and other resources in ruby_block. It requires setting the runcontext. I’ll paste some code when I get back to my desk.

On Dec 21, 2010, at 1:20 PM, Jonathan Weiss jw@innerewut.de wrote:

Cheers,

I’m using a ruby_block to handle complex operations with mdadm in
Chef. My question is, how do I tell Chef that my block failed and
execution should halt with an error? In pseudo code:

ruby_block “A complex operation” do
block “using mdadm” do
output = do something
if $?.success?
Chef::Log.info output
else
Chef::Log.error output
# tell chef we failed
end
end
end

This would of course be easier if I could just use the execute
resource in the ruby_block…

Thanks,
Jonathan


Jonathan Weiss
http://blog.innerewut.de
http://twitter.com/jweiss


#4

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Here’s an example of using an execute resource in a ruby_block. I’m not aware of an easier semantic.

ruby_block “A complex operation” do
block do
run_context = Chef::RunContext.new(node, {})
e = Chef::Resource::Execute.new(“Something with mdadm”, run_context)
e.command(“put the command/commands here. multi-line with ruby here document”)
e.run_action(:run)
end
end

The key here is the run_context and the Chef::Resource syntax.

On Dec 22, 2010, at 8:27 AM, Joshua Timberman wrote:

Hi there!

You can use execute and other resources in ruby_block. It requires setting the runcontext. I’ll paste some code when I get back to my desk.

On Dec 21, 2010, at 1:20 PM, Jonathan Weiss jw@innerewut.de wrote:

Cheers,

I’m using a ruby_block to handle complex operations with mdadm in
Chef. My question is, how do I tell Chef that my block failed and
execution should halt with an error? In pseudo code:

ruby_block “A complex operation” do
block “using mdadm” do
output = do something
if $?.success?
Chef::Log.info output
else
Chef::Log.error output
# tell chef we failed
end
end
end

This would of course be easier if I could just use the execute
resource in the ruby_block…

Thanks,
Jonathan


Jonathan Weiss
http://blog.innerewut.de
http://twitter.com/jweiss


Opscode, Inc
Joshua Timberman, Technical Evangelist
IRC, Skype, Twitter, Github: jtimberman

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (Darwin)

iEYEARECAAYFAk0SMVQACgkQO97WSdVpzT13LQCeKdVmnEiGBNIRtDSLzHuRnzCh
CWwAnjYk70z9XpfDU6Ffo864mT5GUOM1
=GDzj
-----END PGP SIGNATURE-----


#5

Well,
Here also is the “eval ‘n’ converge” helper method for Chef 0.9.12.

for using within a chef recipe

def eval_and_converge(&blk)
tmp_run_context = Chef::RunContext.new(node, {})
tmp_recipe = Chef::Recipe.new(@cookbook_name, @recipe_name, tmp_run_context)
tmp_recipe.instance_eval(&(blk))
Chef::Runner.new(tmp_run_context).converge
end

Or whilst writing your own Chef::Resource and Chef::Provider

class MyProvider < Chef::Provider
def eval_and_converge(&blk)
tmp_run_context = Chef::RunContext.new(node, {})
tmp_recipe = Chef::Recipe.new(@new_resource.cookbook_name,
@new_resource.recipe_name, tmp_run_context)
tmp_recipe.instance_eval(&(blk))
Chef::Runner.new(tmp_run_context).converge
end
end

Does what it says on the tin. It evaluates the &blk passed into it.
Then it converges and executes any chef resources encountered in &blk.

So from the OP’s usage example:

ruby block do
eval_and_converge do
Chef::Log "Using mdadm…"
execute “do something”
# if the previous line of code has returned a non-zero exit code,
# then Chef will automatically raise an exception for you.
end
end

Which is the same as:

ruby_block “A complex operation” do
block “using mdadm” do
output = do something
if $?.success?
Chef::Log.info output
else
Chef::Log.error output
# tell chef we failed
end
end
end

The advantage of eval_and_converge is that you can wrap it around
whichever and as many chef resources you like. It will guarantee those
resources are converged before the next ruby code is encountered. And
it all reads just like a regular chef recipe - the clever shenanigins
is hidden away in the helper method.

On Wed, Dec 22, 2010 at 5:11 PM, Joshua Timberman joshua@opscode.com wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Here’s an example of using an execute resource in a ruby_block. I’m not aware of an easier semantic.

ruby_block “A complex operation” do
block do
run_context = Chef::RunContext.new(node, {})
e = Chef::Resource::Execute.new(“Something with mdadm”, run_context)
e.command(“put the command/commands here. multi-line with ruby here document”)
e.run_action(:run)
end
end

The key here is the run_context and the Chef::Resource syntax.

On Dec 22, 2010, at 8:27 AM, Joshua Timberman wrote:

Hi there!

You can use execute and other resources in ruby_block. It requires setting the runcontext. I’ll paste some code when I get back to my desk.

On Dec 21, 2010, at 1:20 PM, Jonathan Weiss jw@innerewut.de wrote:

Cheers,

I’m using a ruby_block to handle complex operations with mdadm in
Chef. My question is, how do I tell Chef that my block failed and
execution should halt with an error? In pseudo code:

ruby_block “A complex operation” do
block “using mdadm” do
output = do something
if $?.success?
Chef::Log.info output
else
Chef::Log.error output
# tell chef we failed
end
end
end

This would of course be easier if I could just use the execute
resource in the ruby_block…

Thanks,
Jonathan


Jonathan Weiss
http://blog.innerewut.de
http://twitter.com/jweiss


Opscode, Inc
Joshua Timberman, Technical Evangelist
IRC, Skype, Twitter, Github: jtimberman

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (Darwin)

iEYEARECAAYFAk0SMVQACgkQO97WSdVpzT13LQCeKdVmnEiGBNIRtDSLzHuRnzCh
CWwAnjYk70z9XpfDU6Ffo864mT5GUOM1
=GDzj
-----END PGP SIGNATURE-----