这种事情在厨师食谱中很常见:
%w{foo bar baz}.each do |x|
file "#{x}" do
content "whatever"
end
end
但是我想从与食谱保存的文件中读取要循环的项目,例如:
File.open('files/default/blah.txt').each do |x|
file "#{x}" do
content "whatever"
end
end
如果我给出blah.txt
的完整路径,其中chef-client恰好缓存它,但它不可移植,这是有效的。如果我像在示例中那样编写它,它“无效”,“希望”当前目录是cookbook的根目录。有没有办法在编制食谱时获取cookbook根目录?
答案 0 :(得分:4)
在Chef 11中,你可以变得聪明并使用Dir globbing来实现你想要的行为:
禁用延迟加载资源。启用延迟资源加载后,Chef将在Chef Client运行期间请求资产(如cookbook文件,模板等)。在您的用例中,您需要在>强大的配方执行开始之前服务器上存在这些资产。将以下内容添加到client.rb
:
no_lazy_load true
在磁盘上查找cookbook缓存的路径。这有点神奇和实验,但是:
"#{Chef::Config[:file_cache_path]}/cookbooks/NAME"
获取正确的文件:
path = "#{Chef::Config[:file_cache_path]}/cookbooks/NAME/files/default/blah.txt"
File.readlines(path).each do |line|
name = line.strip
# Whatever chef execution here...
end
如果您关心使用文件特定性处理程序,您可能还需要查看Cookbook.preferred_filename_on_disk
。
答案 1 :(得分:4)
另一个解决方案,对于那些不需要文件内容直到收敛时间但不需要任何client.rb修改的人来说,是使用cookbook_file将资源读入你的file_cache_path然后延迟加载它。这是一个示例,我在一个groovy脚本中读取嵌入到xml模板中。
script_file = "#{Chef::Config['file_cache_path']}/bootstrap-machine.groovy"
cookbook_file script_file do
source 'bootstrap-machine.groovy'
end
config_xml = "#{Chef::Config['file_cache_path']}/bootstrap-machine-job.xml"
template config_xml do
source 'bootstrap-machine-job.xml.erb'
variables(lazy {{
:groovy_script => File.open(script_file).read
}})
end
答案 2 :(得分:0)
为了整洁'为了这个,我喜欢使用File.join()
和{。}的组合
" cookbook_name"变量
File.join(
Chef::Config[:file_cache_path],
'cookbooks',
cookbook_name,
'path/to/blah.txt'
)