在 Chef 食谱中使用变量
Posted
技术标签:
【中文标题】在 Chef 食谱中使用变量【英文标题】:Using a variable inside a Chef recipe 【发布时间】:2014-06-26 09:30:38 【问题描述】:我正在使用 chef-cookbook-hostname 食谱来设置节点的主机名。我不希望我的主机名在属性文件中被硬编码(默认 ['set_fqdn'])。
相反,主机名将从 VM 定义 XML 文件中读取。我想出了以下默认配方,但显然变量 fqdn 没有给出值。是否知道为什么会发生这种情况或更好地完成我的任务?
ruby_block "Find-VM-Hostname" do
block do
require 'rexml/document'
require 'net/http'
url = 'http://chef-workstation/services.xml'
file = Net::HTTP.get_response(URI.parse(url)).body
doc = REXML::Document.new(file)
REXML::XPath.each(doc, "service_parameters/parameter") do |element|
if element.attributes["name"].include?"Hostname"
fqdn = element.attributes["value"] #this statement does not give value to fqdn
end
end
end
action :nothing
end
if fqdn
fqdn = fqdn.sub('*', node.name)
fqdn =~ /^([^.]+)/
hostname = Regexp.last_match[1]
case node['platform']
when 'freebsd'
directory '/etc/rc.conf.d' do
mode '0755'
end
file '/etc/rc.conf.d/hostname' do
content "hostname=#fqdn\n"
mode '0644'
notifies :reload, 'ohai[reload]'
end
else
file '/etc/hostname' do
content "#hostname\n"
mode '0644'
notifies :reload, 'ohai[reload]', :immediately
end
end
【问题讨论】:
【参考方案1】:这里问题的根源是您将变量 fqdn 设置在 ruby_block 的范围内,并试图在编译阶段引用该变量。 ruby_block 资源允许在收敛阶段运行 ruby 代码。
鉴于您似乎使用 fqdn 来设置资源集,看起来您可以从 ruby 代码周围删除 ruby 块。例如
fqdn = // logic to get fqdn
file '/tmp/file' do
content "fqdn=#fqdn"
end
【讨论】:
它解决了问题并且效果很好!感谢您的快速回复。【参考方案2】:我在 Chef 文档中找到了这个。我遇到了类似的问题。我要试试node.run_state
。此信息位于本页底部https://docs.chef.io/recipes.html
在 chef-client 运行期间使用
node.run_state
存储临时数据。该数据可以在资源之间传递,然后在执行阶段进行评估。run_state
是一个空 Hash,总是在 chef-client 运行结束时被丢弃。例如,以下配方将安装 Apache Web 服务器,随机选择 php 或 Perl 作为脚本语言,然后安装该脚本语言:
package "httpd" do action :install end ruby_block "randomly_choose_language" do block do if Random.rand > 0.5 node.run_state['scripting_language'] = 'php' else node.run_state['scripting_language'] = 'perl' end end end package "scripting_language" do package_name lazy node.run_state['scripting_language'] action :install end
【讨论】:
我已经尝试过类似的方法(在 run_state 中分配一个变量并在模板中检索它)并且 node.run_state 命令总是在包调用中返回一个空值,所以这并不普遍看起来。 有run_state,忘了懒惰。谢谢!【参考方案3】:请点击此链接 http://lists.opscode.com/sympa/arc/chef/2015-03/msg00266.html 您可以使用 node.run_state[:variables] 将一个变量解析为另一个配方
这是我的代码:: 文件.rb
node.run_state[:script_1] = "foo" include_recipe 'provision::copy'
并在其他 copy.rb 文件中放入以下代码::
copy.rb
文件名 = node.run_state[:script_1] puts "名字是#filename"
【讨论】:
【参考方案4】:我出于同样的目的使用了node.run_state['variable']
,并且成功地做到了。请在下面找到基本示例代码。
ruby_block "resource_name" do
block do
node.run_state['port_value'] = 1432
end
end
ruby_block "resource_name2" do
block do
num = node.run_state['variable']
end
end
我希望它会有所帮助。
【讨论】:
要在配方中获取 run_state 的值而不是用于赋值,请使用#node.run_state['variable']
以上是关于在 Chef 食谱中使用变量的主要内容,如果未能解决你的问题,请参考以下文章