Hi,
When the command used in the Mixlib::ShellOut.new does not exist, chef exits with a compilation error
================================================================================
Recipe Compile Error in /tmp/cookbooks/hadoop/recipes/default.rb
Errno::ENOENT
No such file or directory - echo2 ok
In the following example it should start and exists as it should not find package whois2
include_recipe “apt”
package “whois2” do
action :install
end
cmd = Mixlib::ShellOut.new(“echo2 ok”)
cmd.run_command
However, it exists with :
[2014-02-07T18:00:28+00:00] DEBUG: Re-raising exception: Errno::ENOENT - No such file or directory - echo2 ok
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:268:in exec' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:268:in
block in fork_subprocess’
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:256:in fork' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:256:in
fork_subprocess’
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:40:in run_command' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout.rb:225:in
run_command’
/tmp/vagrant-chef-1/chef-solo-1/cookbooks/hadoop/recipes/default.rb:19:in from_file' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.8.2/lib/chef/mixin/from_file.rb:30:in
instance_eval’
If I replace “echo2” by “echo” it exits with the expected error.
I suppose it’s not an expected behaviour ? FYI, I used chef-solo 11.8.2
Cyril SCETBON
On Feb 7, 2014, at 10:07 AM, Cyril Scetbon cyril.scetbon@free.fr wrote:
Hi,
When the command used in the Mixlib::ShellOut.new does not exist, chef exits with a compilation error
================================================================================
Recipe Compile Error in /tmp/cookbooks/hadoop/recipes/default.rb
Errno::ENOENT
No such file or directory - echo2 ok
In the following example it should start and exists as it should not find package whois2
include_recipe "apt"
package "whois2" do
action :install
end
cmd = Mixlib::ShellOut.new("echo2 ok")
cmd.run_command
However, it exists with :
[2014-02-07T18:00:28+00:00] DEBUG: Re-raising exception: Errno::ENOENT - No such file or directory - echo2 ok
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:268:in exec' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:268:in
block in fork_subprocess'
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:256:in fork' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:256:in
fork_subprocess'
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout/unix.rb:40:in run_command' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/mixlib-shellout-1.2.0/lib/mixlib/shellout.rb:225:in
run_command'
/tmp/vagrant-chef-1/chef-solo-1/cookbooks/hadoop/recipes/default.rb:19:in from_file' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.8.2/lib/chef/mixin/from_file.rb:30:in
instance_eval'
If I replace "echo2" by "echo" it exits with the expected error.
I suppose it's not an expected behaviour ? FYI, I used chef-solo 11.8.2
Chef uses a two-pass system, first it evaluates all recipes to build the resource collection, then it converges each resource. Any top-level ruby code happens in the first phase, so that error happens first.
--Noah
On Fri, Feb 7, 2014 at 1:07 PM, Cyril Scetbon cyril.scetbon@free.fr wrote:
When the command used in the Mixlib::ShellOut.new does not exist, chef exits with a compilation error
Yes, it will fail if you tell it to run a command that dos not exist.
In the following example it should start and exists as it should not find package whois2
include_recipe "apt"
package "whois2" do
action :install
end
cmd = Mixlib::ShellOut.new("echo2 ok")
cmd.run_command
I'm guessing you're expecting it to fail on on the package line,
because that package is made up and doesn't exist, but it's failing on
the later line.
This is because the chef-client run reads the recipes to create the
Resource Collection (often called compilation), before it actually
makes any changes to the system by running the providers (often called
convergence). The first time it reads the package resource, it hasn't
tried to install it yet, so it doesn't fail even though it doesn't
exist. But your ruby code below that (the mixlib calls) is executed in
that first phase, and since the ruby code fails, the recipe fails
there.
If you put your ruby code in a "ruby_block" resource, it wouldn't
actually be run until the later phase. The purpose of a ruby_block
resources is to be able to run and notify ruby code during convergence
in a specific order.
ruby_block "run a command that doesn't exist" do
block do
cmd = Mixlib::ShellOut.new("echo2 ok")
cmd.run_command
end
end
Bryan
Thank you guys you're right
The ruby_block resource is used to execute Ruby code during a chef-client run. Ruby code in theruby_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.
Cyril Scetbon
Le 7 févr. 2014 à 19:28, Bryan McLellan btm@loftninjas.org a écrit :
On Fri, Feb 7, 2014 at 1:07 PM, Cyril Scetbon cyril.scetbon@free.fr wrote:
When the command used in the Mixlib::ShellOut.new does not exist, chef exits with a compilation error
Yes, it will fail if you tell it to run a command that dos not exist.
In the following example it should start and exists as it should not find package whois2
include_recipe "apt"
package "whois2" do
action :install
end
cmd = Mixlib::ShellOut.new("echo2 ok")
cmd.run_command
I'm guessing you're expecting it to fail on on the package line,
because that package is made up and doesn't exist, but it's failing on
the later line.
This is because the chef-client run reads the recipes to create the
Resource Collection (often called compilation), before it actually
makes any changes to the system by running the providers (often called
convergence). The first time it reads the package resource, it hasn't
tried to install it yet, so it doesn't fail even though it doesn't
exist. But your ruby code below that (the mixlib calls) is executed in
that first phase, and since the ruby code fails, the recipe fails
there.
Chef Infra Client Overview
If you put your ruby code in a "ruby_block" resource, it wouldn't
actually be run until the later phase. The purpose of a ruby_block
resources is to be able to run and notify ruby code during convergence
in a specific order.
ruby_block Resource
ruby_block "run a command that doesn't exist" do
block do
cmd = Mixlib::ShellOut.new("echo2 ok")
cmd.run_command
end
end
Bryan