我使用chef-cookbook-hostname cookbook来设置节点的主机名。我不希望我的主机名在属性文件中被硬编码(默认[' 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
答案 0 :(得分:13)
问题的根源在于您在ruby_block的范围内设置变量fqdn并且正在尝试在编译阶段引用该变量。 ruby_block资源允许在收敛阶段运行ruby代码。
鉴于您似乎正在使用fqdn来设置资源集,看起来好像您可以从ruby代码周围删除ruby块。 e.g。
fqdn = // logic to get fqdn
file '/tmp/file' do
content "fqdn=#{fqdn}"
end
答案 1 :(得分:7)
我在Chef docs中找到了这个。我遇到了类似的问题。我打算试试node.run_state
。此信息位于本页底部https://docs.chef.io/recipes.html
使用
node.run_state
在Chef-client运行期间存储瞬态数据。该数据可以在资源之间传递,然后在执行阶段进行评估。run_state
是一个空哈希,在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
答案 2 :(得分:0)
请点击此链接 http://lists.opscode.com/sympa/arc/chef/2015-03/msg00266.html 您可以使用node.run_state [:variables]将一个变量解析为另一个配方
这是我的代码:: file.rb
node.run_state [:script_1] =“foo” include_recipe'provision :: copy'
并在其他copy.rb文件中放入以下代码::
<强> copy.rb 强>
filename = node.run_state [:script_1] 把“名字是#{filename}”
答案 3 :(得分:0)
我使用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
我希望它会有所帮助。