我是Chef的新手,我正在试图找出模板(这看起来很酷).在我的旧部署结构中,我有一个我只想复制的目录.它有许多配置参数分散在目录中的整个文件中.我已经开始尝试将这些参数抽象为一个属性文件(更干净),但是在使用Chef安装它时遇到了麻烦.我用ERB修改了所有文件的扩展名以.erb结尾(我来自Rails背景,所以这对我来说似乎很自然).例如,我有一个名为run.conf的文件,它现在名为run.conf.erb.
理想情况下,我希望在配方中有一个模板块,它只复制目录中的所有文件,并使用我提供的变量更新那些.erb文件(删除.erb扩展名).这是我到目前为止的一个例子:
template "#{node["dcm4chee"]["home"]}" do
source "server/"
variables(
"java_mem_opts" => node["dcm4chee"]["java_mem_opts"],
"db_username" => node["dcm4chee"]["admin"]["username"],
"db_password" => node["dcm4chee"]["admin"]["password"],
"db_hostname" => node["mysql"]["hostname"],
"db_port" => node["mysql"]["port"]
)
end
Run Code Online (Sandbox Code Playgroud)
我在templates/default下放了一个名为server的文件夹,该文件夹包含我想模板化的文件.#{node ["dcm4chee"] ["home"]}变量是我想将文件放在目标机器上的位置.理想情况下,我想在没有命名配方中的特定文件的情况下执行此操作,因为这样,如果我修改服务器目录的内容以进行部署,我就不必触摸配方.
这可能吗?如果是这样,我做错了什么?如果没有,我有什么选择.
谢谢
编辑
在考虑了这一点之后,我尝试使用一些自定义ruby代码来执行此操作.这是我当前尝试失败的NoMethodError引用ruby_block中初始调用的tempate_dir.
def template_dir(file)
Dir.foreach("server") do |file|
if File.file?(file)
template "#{node["dcm4chee"]["home"]}/#{file}" do
source "server/#{file}"
variables(
"java_mem_opts" => node["dcm4chee"]["java_mem_opts"],
"db_username" => node["dcm4chee"]["admin"]["username"],
"db_password" => node["dcm4chee"]["admin"]["password"],
"db_hostname" => node["mysql"]["hostname"],
"db_port" => node["mysql"]["port"]
)
end
else
directory "#{node["dcm4chee"]["home"]}/#{file}" do
action :create
end
template_dir(file)
end
end
end
ruby_block "template the whole server directory" do
block do
template_dir("server")
end
end
Run Code Online (Sandbox Code Playgroud)
你可以template_dir在你的内部ruby_block而不是在顶层定义——这样就可以很好地工作。
find是 Ruby 标准库的一部分,并将递归地遍历目录。使用它会导致一些更干净的东西:
ruby_block "recursive templating" do
block do
require 'find'
root = 'server'
Find.find(root) do |file|
if File.file?(file)
template "#{node["dcm4chee"]["home"]}/#{file}" do
source file
variables(
"java_mem_opts" => node["dcm4chee"]["java_mem_opts"],
"db_username" => node["dcm4chee"]["admin"]["username"],
"db_password" => node["dcm4chee"]["admin"]["password"],
"db_hostname" => node["mysql"]["hostname"],
"db_port" => node["mysql"]["port"]
)
end
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
一般来说,如果您正在编写任何类型的稍微复杂的逻辑,您应该考虑编写 LWRP 而不是将其放入您的配方中。两阶段编译/执行会导致很多不直观的行为(例如块无法查找template_dir),并且因为编写 LWRP 可以让您验证输入、编写测试并更好地确保幂等性。
另外,我对您拥有的“服务器”字符串有点困惑 - 我不确定在什么环境中会解析到您的templates目录。无论如何,如果您想访问食谱中所有模板的列表,这里有一个可用的数组:run_context.cookbook_collection[cookbook_name].template_filenames
| 归档时间: |
|
| 查看次数: |
3277 次 |
| 最近记录: |