如何使用 Ruby 块在厨师食谱中分配变量

Posted

技术标签:

【中文标题】如何使用 Ruby 块在厨师食谱中分配变量【英文标题】:How to use a Ruby block to assign variables in chef recipe 【发布时间】:2015-08-06 02:27:32 【问题描述】:

我正在尝试在 Chef 配方中动态执行 Ruby 逻辑,并相信实现此目的的最佳方法是使用块。

我在将块内分配的变量转移到主厨食谱的主代码时遇到困难。这是我尝试过的:

ruby_block "Create list" do
  block do
    to_use ||= []
    node['hosts'].each do |host|
      system( "#path/command --all" \
              " | awk 'print $2; print $3'" \
              " | grep #host > /dev/null" )
      unless $? == 0
        to_use << host
      end
    end
    node['hosts'] = to_use.join(',')
  end
  action :create
end

execute "Enable on hosts" do
  command "#path/command --enable -N #node['hosts']"
end

我没有尝试即时重新分配 chef 属性,而是尝试在块中创建新变量,但仍然找不到在 execute 语句中访问它们的方法。

我最初使用一个类和调用方法,但是它是在配方之前编译的,我真的需要在运行时执行逻辑,在配方期间。

【问题讨论】:

最好的厨师收据是 idpotent,因此动态执行 ruby​​ 逻辑通常不是一个好主意。你到底想做什么? node['hosts'].select! 会就地修改它。 【参考方案1】:

您的问题是compile time versus converge time。您的块将在收敛时间运行,但此时执行资源中的 node['host'] 已被评估。

在这种情况下,最好的解决方案是使用lazy evaluation,以便在资源收敛而不是编译时扩展变量:

execute "Enable on hosts" do
  command lazy  "#path/command --enable -N #node['hosts']" 
end

这里有一点警告,惰性运算符必须包含完整的 command 属性文本,而不仅仅是变量,它只能作为属性名称之后的第一个关键字。

【讨论】:

效果很好——正是我需要的,谢谢!

以上是关于如何使用 Ruby 块在厨师食谱中分配变量的主要内容,如果未能解决你的问题,请参考以下文章

ruby 厨师中级班的处理程序食谱

如何使用厨师将 opsworks 变量提取到 .env 文件中?

如何将厨师“执行资源”的输出放入变量中

如何从厨师食谱在后台运行java程序

如何在测试中使用在 beforeAll() 钩子中分配了值的变量

如何在蒸汽叶中分配变量?