[chef] Re: Re: Malformed array causing Chef to error out


Chronological Thread 
  • From: Fabien Delpierre < >
  • To: chef < >
  • Subject: [chef] Re: Re: Malformed array causing Chef to error out
  • Date: Thu, 26 Feb 2015 14:07:01 -0500

Ok, thanks. So, really, what I should take away from all this is that Chef::Config[:data_bag_path], for some reason, is an array and I just have to deal with it. That it would be an array didn't make sense to me so I didn't even check to see if it was an array, despite the signs.

irb(main):001:0> test = "1"
=> "1"
irb(main):002:0> puts test
1
=> nil
irb(main):003:0> test.push("2")
NoMethodError: undefined method `push' for "1":String
    from (irb):3
    from /opt/chefdk/embedded/bin/irb:11:in `<main>'
irb(main):004:0> test = ["1"]
=> ["1"]
irb(main):005:0> puts test
1
=> nil
irb(main):006:0> test.push("2")
=> ["1", "2"]


So I learned that if there's only one thing stored in an array, if you display the contents of the array, you can't tell that it is an array from the output, which is why I was confused to begin with:
chef > puts Chef::Config[:data_bag_path]
/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags
 => nil

Doesn't look like an array.

However:
chef > Chef::Config[:data_bag_path].kind_of?(Array)
 => true


Likewise you can push additional values to it.

Alright, so lesson learned! I can work with that now. Thanks!


On Thu, Feb 26, 2015 at 1:20 PM, Brandon Raabe < " target="_blank"> > wrote:
That was less than helpful, let me try again...

When you're creating your array of directories, the first entry is, itself, an array. The second entry is based on the first, and since it is an array being interpolated into a string, you end up with another funky entry in your dirs array.

You can see this in irb:

irb(main):001:0> data_bags_path = [ "/var/chef/cach/data_bags" ]
=> ["/var/chef/cach/data_bags"]
irb(main):002:0> dirs = [ data_bags_path, "#{data_bags_path}/my_data_bag" ]
=> [["/var/chef/cach/data_bags"], "[\"/var/chef/cach/data_bags\"]/my_data_bag"]

Assuming you're not adding any additional custom paths to the data bags path, you can fix this by taking the first entry from the array and using that in your dirs variable like this:

data_bags_path = Chef::Config[:data_bag_path].first
dirs = [ data_bags_path, "#{data_bags_path}/#{node['data_bag']}" ]


Alternatively, you can use the recursive attribute of the directory resource, and skip creating the data_bags_path directory, because it would be recursively created by the resource.

data_bags_path = Chef::Config[:data_bag_path].first
dirs = [ "#{data_bags_path}/#{node['data_bag']}" ]

dirs.each do |dir|
  directory dir do
    recursive true
  end
end

On Thu, Feb 26, 2015 at 11:03 AM, Brandon Raabe < " target="_blank"> > wrote:
It looks like your first entry is an array.

dirs = [ Chef::Config[:data_bag_path], "#{Chef::Config[:data_bag_path]}/#{node['data_bag']}" ]

directory("["/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags"]") do

You can force it to create the entire path by adding the recursive attribute to you directory resource.


On Thu, Feb 26, 2015 at 10:40 AM, Fabien Delpierre < " target="_blank"> > wrote:
Hi there,
I can't figure out what I'm doing wrong with this. It seems trivial enough but I'm not a software developer and this is puzzling me right now. I think my issue has more to do with pure Ruby than Chef but either way, I can't figure it out.
If it matters, I'm working with chef-solo 12.0.3 and provisioning things via Vagrant 1.7.2.

I'm doing something that should be pretty straightforward: creating a number of directories declared in an array:

dirs = [ Chef::Config[:data_bag_path], "#{Chef::Config[:data_bag_path]}/#{node['data_bag']}" ]

dirs.each do |dir|
  directory dir do
    owner "foo"
    group "foo"
    mode 00440
    recursive true
    action :create
  end
end


This results in the following error during provisioning
==> default: Compiled Resource:
==> default: ------------------
==> default: # Declared in /tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/cookbooks/nap/recipes/default.rb:90:in `block in from_file'
==> default:
==> default: directory("["/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags"]") do
==> default:   action [:create]
==> default:   retries 0
==> default:   retry_delay 2
==> default:   default_guard_interpreter :default
==> default:   path ["/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags"]
==> default:   recursive true
==> default:   declared_type :directory
==> default:   cookbook_name :nap
==> default:   recipe_name "default"
==> default:   owner "foo"
==> default:   group "foo"
==> default:   mode 288
==> default: end
==> default:
==> default: [2015-02-26T12:09:20-05:00] INFO: Running queued delayed notifications before re-raising exception
==> default: [2015-02-26T12:09:20-05:00] ERROR: Running exception handlers
==> default: [2015-02-26T12:09:20-05:00] ERROR: Exception handlers complete
==> default: [2015-02-26T12:09:20-05:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
==> default: [2015-02-26T12:09:20-05:00] ERROR: directory[["/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags"]] (nap::default line 90) had an error: Chef::Exceptions::ValidationFailed: Option path must be a kind of String!  You passed ["/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags"].
==> default: [2015-02-26T12:09:21-05:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)


I ran this through chef-shell as well:
$ chef-shell -s -c solo.rb
loading configuration: solo.rb
Session type: solo
Loading.............done.
Ohai2u
chef > puts Chef::Config[:data_bag_path]
/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags
 => nil
chef > dirs = [ Chef::Config[:data_bag_path], "#{Chef::Config[:data_bag_path]}/#{node['foo']['bar']}" ]
NoMethodError: undefined method `[]' for nil:NilClass
    from (irb):3
    from /opt/chef/embedded/apps/chef/lib/chef/shell.rb:75:in `block in start'
    from /opt/chef/embedded/apps/chef/lib/chef/shell.rb:74:in `catch'
    from /opt/chef/embedded/apps/chef/lib/chef/shell.rb:74:in `start'
    from /opt/chef/embedded/apps/chef/bin/chef-shell:37:in `<top (required)>'
    from /usr/bin/chef-shell:40:in `load'
    from /usr/bin/chef-shell:40:in `<main>'
chef > dirs = []
 => []
chef > dirs = [ Chef::Config[:data_bag_path] ]
 => [["/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags"]]
chef > puts dirs
/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags
 => nil
chef > dirs = [ Chef::Config[:data_bag_path], "#{Chef::Config[:data_bag_path]}/test" ]
 => [["/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags"], "[\"/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags\"]/test"]
chef > puts dirs
/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags
["/tmp/vagrant-chef/c0f72feb81f20d85ca657a73371fcecb/data_bags"]/test
 => nil
chef >


So as you can see in the above output, it's adding brackets around some of the things stored in the array and that seems to be why the Chef run is failing, but I don't understand why adding the brackets to begin with.

I also have no idea why this line produces an error:
chef > dirs = [ Chef::Config[:data_bag_path], "#{Chef::Config[:data_bag_path]}/#{node['foo']['bar']}" ]

Would somebody please mind explaining what I'm doing wrong? Thank you!






Archive powered by MHonArc 2.6.16.

§