Reputation: 49
I am reading a file inside a ruby_block in chef. I am storing each line in an array. I want them to be accessible anywhere within my chef recipe, so i did a bit of research and found out that i can use node object.
The problem is whenever i am using the node object its storing the last line only and not each line.
This is my code. Any suggestions?
ruby_block "name" do
block do
CSV.foreach('/tmp/users.txt') do |row|
node['username']=row
end
end
action :run # see actions section below
end
Okay so this is my code now.
ruby_block 'name' do
block do
CSV.foreach('/tmp/users.txt'){ |row| node.run_state['username123'] |= [row] }
end
end
directory "/sftp/#{node.run_state['username123']}/incoming" do
action :create
recursive true
end
and my outputs of chef-run comes up to be.
directory[/sftp//incoming] action create
- create new directory /sftp//incoming
Upvotes: 0
Views: 1073
Reputation: 4223
OK, so your problem is due to the two-stage nature of Chef. You are declaring your directories in the "compile" stage, but you try to do so with data from the inside of your ruby_block
, which doesn't execute until the second stage. If your CSV file is not put into place by chef, you could do this:
# notice this is not in a ruby block
CSV.foreach('/tmp/users.txt'){ |row| node.run_state['username123'] |= [row] }
node.run_state['username123'].each do |next_file|
directory "/sftp/next_file/incoming" do
action :create
recursive true
end
end
If the CSV file is put into place by chef, you'll need to force it to be there before the CSV parsing runs. You MIGHT be able to do this:
cookbook_file 'mycsv file' do
...
end.run_action(:create)
at some point prior to your CSV parsing. If that's not an option (for any of several reasons) then you would need to get fancier. At this point you would probably be best-off creating an LWRP.
Upvotes: 1
Reputation: 4223
SEE new answer (didn't want to confuse anyone with the comments)
Two choices. If you really want to use the node, the you need to use an array, which you are not.
ruby_block 'name' do
block do
CSV.foreach('/tmp/users.txt'){ |row| node['username'] |= [row] }
end
end
But, unless you want that info to be stored in the node object on the server, I'd suggest you actually store it in the run_state
ruby_block 'name' do
block do
CSV.foreach('/tmp/users.txt'){ |row| node.run_state['username'] |= [row] }
end
end
This still makes it accessible to the rest of your recipes, but it keeps it out of the node object which will be sent to the chef server at the end of you run.
Upvotes: 2