Reputation: 42154
I need a file fileC
deployed that's the concatenation of two other files fileA
and fileB
. In my current setup, all three files are in the cookbook, declared as Cookbook File resources.
But it feels redundant. I'd like to declare the bigger file as a function of the two others.
When fileC
was first needed, I got it to "almost work" by luck by declaring the file resource's contents as IO.read(file1) + IO.read(file2)
. But that fails as soon as the recipe is deployed to a new node, since fileA
and fileB
aren't present at compile time.
I tried to access the underlying Ruby objects' information on where the cookbook could be deployed. But the more I looked, the less I was convinced it was possible with my level of Chef/Ruby knowledge. The resource↔provider gap seems too wide.
I'd like to avoid the cat fileA fileB >fileC
type of solution, for the following reason: in the future, I'll likely need to disciminate nodes that need C from nodes that need A/B.
Any ideas on how to address the redundancy?
Upvotes: 3
Views: 3602
Reputation: 443
If you used a template, I think you could get away with it. e.g.
template "/var/tmp/fileC.txt" do
source "fileC.erb"
variables(:included_files => ["/var/tmp/file1.txt", "/var/tmp/file2.txt"])
end
And then in your template
<% @included_files.each { |file| %>
<%= File.read(file) %>
<% } %>
Upvotes: 5
Reputation: 2457
Here's my solution. Unfortunately it does involve a "cat" command, but the list of files is abstracted out into a list which can be set or modified using attributes:
files = ["foo", "bar"] # Or retrieve from an attribute
execute "cat files" do
command "cat #{files.map {|f| "/var/tmp/#{f} "}} > /var/tmp/foobar"
action :nothing
end
files.each do |f|
cookbook_file "/var/tmp/#{f}" do
source f
notifies :run, "execute[cat files]", :immediately
end
end
I'm curious what the use case is here though. My guess is two configuration fragments that need to be mashed together for a service that doesn't support a conf.d arrangement.
Upvotes: 1