Chef:可变参数的惰性评估

Chef: Lazy evaluation of variable argument

我们遇到了 Mapr 客户端安装的情况。我们希望能够复制位于 /opt/mapr/hive/hive-x.y/conf/ 目录下的自定义 hive-site.xml 文件。问题是在一组包(包括 hive)完全安装之后,我们才知道 hive 版本号。所以,像下面这样的代码是失败的:

package 'mapr-client'
...
...
dir_hive = Dir["/opt/mapr/hive/hive-*"]
template "#{dir_hive[0]}/conf/hive-site.xml" do
    source "devg_hive-site.xml.erb"
    mode 0644
end

模板名称似乎是在编译时评估的,此时包安装尚未完成,因此名称评估为 /conf/hive-site.xml 而不是 /opt/mapr/hive/hive-1.2/conf/site.xml。 如果我们等待所有包完全安装并通过单独调用或执行以下代码的手动 运行:

dir_hive = Dir["/opt/mapr/hive/hive-*"]
template "#{dir_hive[0]}/conf/hive-site.xml" do
    source "devg_hive-site.xml.erb"
    mode 0644
end

我们已成功复制配置文件;但是,如果它是您安装和尝试配置过程的一部分,它就不起作用。以下是我们尝试过的其他一些事情:

上面的一些其他变体也没有成功;在所有这些情况下,"#{dir_hive[0]}/conf/hive-site.xml" 似乎在编译时得到评估,因此产生了错误的文件路径。

使用通配符捕获已安装文件路径然后使用该路径进行某些操作(例如用自定义配置文件替换配置文件)的最佳方法是什么。

或者,我们能否在执行某些操作后延迟计算表达式以产生变量名,并且延迟计算的变量名取决于操作后出现的文件名?

感谢您的宝贵时间,感谢您的指点!

它非常 'smelly' 并且它可能会影响您的升级。因为较新的版本会有更高的数字。所以你可以尝试使用 last 而不是 first.

template "hive-site.xml" do
  path lazy { "#{Dir['/opt/mapr/hive/hive-*'].last}/conf/hive-site.xml" }
  source "devg_hive-site.xml.erb"
end

我不确定这在您的代码中有多常见,但您可以考虑 resource/code 将从包(元数据或列表文件)中提取路径。

编辑。我有第二个想法。包可能会记录在 node["packages"] 中,版本可以映射到你的路径,你可以使用它并删除 Dir (你仍然需要惰性块),你可能需要 运行 ohai 插件在安装包后刷新 node["packages"](我想你可以为此使用通知)。

它可能看起来类似于:

ohai "reload packages" do
  plugin "packages"
  action :nothing
end

package "mapr-client" do
  notifies :reload, "ohai[reload packages]", :immediately
end

template "hive-site.xml" do
  path lazy { "/opr/mapr/hive/hive-#{node["packages"]["mapr-client"]["version"]}/conf/hive-site.xml" }
  source "devg_hive-site.xml.erb"
end

不幸的是,版本可能不会映射到目录结构。这个包太糟糕了;-)