Chef infra Chef:变量参数的惰性计算

Chef infra Chef:变量参数的惰性计算,chef-infra,lazy-evaluation,dynamic-variables,convergence,Chef Infra,Lazy Evaluation,Dynamic Variables,Convergence,我们有一个Mapr客户端安装的情况。我们希望能够复制一个自定义的hive-site.xml文件,该文件位于/opt/mapr/hive/hive-x.y/conf/dir下。问题是,在一组软件包(包括配置单元)完全安装之后,我们才知道配置单元的版本号。因此,下面这样的代码失败了: package 'mapr-client' ... ... dir_hive = Dir["/opt/mapr/hive/hive-*"] template "#{dir_hive[0]}/conf/hive-site

我们有一个Mapr客户端安装的情况。我们希望能够复制一个自定义的hive-site.xml文件,该文件位于/opt/mapr/hive/hive-x.y/conf/dir下。问题是,在一组软件包(包括配置单元)完全安装之后,我们才知道配置单元的版本号。因此,下面这样的代码失败了:

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
我们成功复制了配置文件;但是,如果它是您安装并尝试配置的过程的一部分,它将不起作用。以下是我们尝试过的其他一些方法:

  • 尝试将代码的config copy部分移动到一个单独的配方中,并创建了一个运行列表,希望如果执行顺序保持不变,那么一旦包安装完成,配置单元目录将可用,这样我们就可以获得正确的文件路径。那没用
  • 将配置副本代码放在ruby_块下,lazy evluator only_if(检查/opt/mpar/hive dir)等。运气不好
  • 将源xml文件复制到/tmp/dir尝试在/opt/mapr/hive dir可用时简单地复制该文件,再次使用惰性计算器、ruby_块等。仍然失败
  • 试图通过ruby_块中的循环检查
    if!Dir.glob('/opt/mapr/hive/hive-*/conf/hive site.xml')。清空?
    并睡眠5秒钟。失败了
除此之外,几乎没有其他的变化是不成功的;在所有这些情况下,似乎
“#{dir_hive[0]}/conf/hive site.xml”
在编译时得到了评估,因此产生了错误的文件路径

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

或者,我们可以在执行某个操作后对表达式进行延迟求值以生成变量名,并且延迟求值的变量名取决于该操作后出现的文件名吗


感谢您的时间,感谢您的指点

它非常“臭”,升级时可能会咬到你。因为更新的版本会有更高的数字。因此,您可以尝试使用
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
我不确定这在您的代码中有多常见,但您可以考虑从包(元数据或列表文件)中提取路径的资源/代码

编辑。我有第二个想法。包可能被记录在
节点[“包”]
中,版本可以映射到您的路径,您可以使用它并删除
目录(您仍然需要惰性块),您可能需要在包安装后运行ohai插件来刷新
节点[“包”]
(我认为您可以为此使用通知)

它可能看起来与此类似:

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
不幸的是,这个版本可能不会映射到目录结构。这个包裹坏了;-)

但是版本给出了1.2.201611292220-1,但我们只需要1.2

下面的代码到底在做什么

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

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

您可以轻松提取版本-
“1.2.201611292220-1”[/\A(\d+\.\d+/,1]
。至于ohai重新加载,它可以,但仅限于插件。只有在包资源发生更改时才会执行更新(ohai reload resource会收到通知),因此在包安装时,不会在每次chef客户端执行时运行更新。这很有帮助,谢谢!我同意包版本控制格式。对于每个包来说都是不同的,如果它们将来发生更改,脚本将失败。
ohai "reload packages" do
  plugin "packages"
  action :nothing
end

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