duckhunt
duckhunt

Reputation: 333

Chef, File does not exists after force the creation

I have the following logic in a recipe that creates a file if it's missing and then tries to insert some lines in it.

file "/root/myfile" do
  owner 'root'
  group 'root'
  mode '400'
  action :create_if_missing
end

file = Chef::Util::FileEdit.new('/root/myfile') 

data_bag('my_databag').each do |user|

  # ... lines using Chef resources like user, group, etc.

  if node.chef_environment != "my_env"
    line = "something to write in myfile"
    Chef::Log.info("-----> #{line}") 
    file.insert_line_if_no_match(/#{line}/, line)
  end
end

file.write_file

The recipe fails in the case myfile doesn't exist despite I'm forcing the creation of the file before the instruction that causes the exception. So here is the error:

ArgumentError
-------------
File '/root/.testfile' does not exist

Relevant File Content:
----------------------
 18:
 19>> file = Chef::Util::FileEdit.new('/root/.testfile')
 20:

Can anyone help me to understand why this doesn't work? Any help on this would be much appreciated.

UPDATE: I tried to touch the file first but still failing in the same line:

 26:  FileUtils.touch('/root/myfile')
 27>> file = Chef::Util::FileEdit.new('/root/.testfile')

Upvotes: 4

Views: 2320

Answers (1)

Tejay Cardon
Tejay Cardon

Reputation: 4223

This is yet another issue of the two phase nature of chef. Pure ruby code runs in the first pass. This is the "compile" or "resource gathering" phase. The ruby code for the chef resources just adds a resource definition to a list of resources. After that is complete, then the second "execution" phase happens. This phase will actually execute the resources. So your file declaration doesn't actually do anything until after your FileUtils code fails.

Two things you could do:

First, you REALLY should avoid using FileUtils in your recipe if at all possible. It would be far better to create your file with a template if you can.

Second, if you change your file declaration a little, you can hack it to run during the first phase: xz

file "/root/myfile" do
  owner 'root'
  group 'root'
  mode '400'
  action :nothing
end.run_action(:create_if_missing)

Upvotes: 6

Related Questions