【问题标题】:Chef: Lazy evaluation of variable argumentChef:对变量参数的懒惰评估
【发布时间】:2017-01-20 07:14:09
【问题描述】:

我们遇到了 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

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

  • 尝试将代码的config copy部分移动到单独的recipe中并创建了一个运行列表,希望如果保持执行顺序,一旦包安装完成,hive dir将可用,所以我们将有正确的文件路径。那没用。
  • 将配置复制代码放在 ruby​​_block、lazy evluator only_if(检查 /opt/mpar/hive 目录)等下。没有运气。
  • 将源 xml 文件复制到 /tmp/ 目录尝试在 /opt/mapr/hive 目录可用时简单地复制文件,再次使用惰性求值器、ruby_block 等。仍然失败。
  • 尝试通过 ruby​​_block 中的循环尝试检查 if !Dir.glob('/opt/mapr/hive/hive-*/conf/hive-site.xml').empty? 并休眠 5 秒。失败。

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

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

或者,我们是否可以在执行某些操作后对表达式进行惰性求值以产生变量名,并且惰性求值的变量名取决于该操作后出现的文件名?

感谢您的宝贵时间并感谢任何指点!

【问题讨论】:

    标签: chef-infra lazy-evaluation dynamic-variables convergence


    【解决方案1】:

    它非常“臭”,升级时它可能会咬你一口。因为较新的版本将具有更高的数字。所以你可以尝试使用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
    

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

    编辑。我有第二个想法。包可能记录在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
    

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

    【讨论】:

    • 这有帮助,谢谢!我同意包版本控制格式。每个包都不同,如果它们将来发生变化,脚本将会失败。
    猜你喜欢
    • 2014-01-04
    • 1970-01-01
    • 2021-12-25
    • 2019-01-07
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    • 2016-12-14
    • 2018-04-01
    相关资源
    最近更新 更多