Chef - Test for cookbook_file existence
-
03-07-2021 - |
Frage
Is there any way to test that a given cookbook_file exists in a chef recipe? I would like to do something like the following:
cookbook_file "/etc/cron.d/#{service}" do
source "etc/cron.d/#{service}"
owner "root"
group "root"
mode "0644"
end
and have it not fail if the file "etc/cron.d/{service_name}" does not exist, since I may have many services running on a machine, but only some of them have associated cron jobs.
I don't want to have a big list of services that take cron jobs like
['service_1', 'service_2', ...],
since that seems fairly brittle. Ideally, I'd like to have a directory that contains cron jobs for the services that need them, and have the recipe not fail if these files are not present. Is what I'm looking for possible?
Lösung
As far as I know, it is not possible to test in advantage if the cookbook_file exists. But you can make chef continue the run instead of failing, if it didn't find the file.
cookbook_file "/etc/cron.d/#{service}" do
source "etc/cron.d/#{service}"
owner "root"
group "root"
mode "0644"
ignore_failure true
end
Andere Tipps
Give this chef_gem
a try:
http://www.rubydoc.info/github/3ofcoins/chef-helpers
You can then use the has_source
to only_if
the file is in the recipe
For example:
only_if { has_source?("optional.config.file", :files) }
Overall, I would suggest to use the answer provided by @JonathanM.
If you prefer not to depend on a chef_gem
, here the code you need in you recipe. This code was tested on Chef 11.12.8
but I guess it should work with any Chef 11.x
version.
To check for a cookbook_file
's source:
only_if { run_context.has_cookbook_file_in_cookbook?(cookbook_name, "etc/cron.d/#{service}") }
To check for a template
's source:
only_if { run_context.has_template_in_cookbook?(cookbook_name, "etc/cron.d/#{service}") }
The variable cookbook_name
is implicitly available within any recipe and has the current cookbook name as value. To check if another cookbook has a template or file, replace cookbook_name
by an hard-coded string for example "java"
.
Note that twiddling with Chef internal API is risky, since code could change between major release (even between minor releases I think). That's why relying of chef_gem
is a good idea, the gem could deal with multiple versions of Chef, it reduce visual clutters in the recipe code and make the code of the recipe more readable also if the DSL is well thought.