所以我使用以下食谱:
include_recipe "build-essential"
node_packages = value_for_platform(
[ "debian", "ubuntu" ] => { "default" => [ "libssl-dev" ] },
[ "amazon", "centos", "fedora", "centos" ] => { "default" => [ "openssl-devel" ] },
"default" => [ "libssl-dev" ]
)
node_packages.each do |node_package|
package node_package do
action :install
end
end
bash "install-node" do
cwd Chef::Config[:file_cache_path]
code <<-EOH
tar -xzf node-v#{node["nodejs"]["version"]}.tar.gz
(cd node-v#{node["nodejs"]["version"]} && ./configure --prefix=#{node["nodejs"]["dir"]} && make && make install)
EOH
action :nothing
not_if "#{node["nodejs"]["dir"]}/bin/node --version 2>&1 | grep #{node["nodejs"]["version"]}"
end
remote_file "#{Chef::Config[:file_cache_path]}/node-v#{node["nodejs"]["version"]}.tar.gz" do
source node["nodejs"]["url"]
checksum node["nodejs"]["checksum"]
notifies :run, resources(:bash => "install-node"), :immediately
end
它成功地在我的Vagrant VM上安装了nodejs但是在重新启动时它再次被执行。我该如何防止这种情况?我在阅读红宝石代码时并不是那么好。
答案 0 :(得分:8)
要使remote_file
资源具有幂等性(即不再下载已经存在的文件),您必须正确指定文件的校验和。您可以使用node["nodejs"]["checksum"]
属性在代码中执行此操作。但是,这仅适用,如果校验和被正确指定为下载文件的SHA256哈希,则不支持其他算法(尤其不是MD5)。
如果校验和不正确,您的食谱仍然有效。但是,在下一次运行时,Chef会注意到现有文件的校验和与您指定的文件不同,并会再次下载文件,从而通知install node
资源并完成整个编译工作。
答案 1 :(得分:2)
对于厨师来说,食谱必须是幂等的。这意味着他们应该能够在不改变结果的情况下反复运行。 Chef希望能够定期运行节点上的所有配方,这应该没问题。
您是否有办法知道该配方中的哪个资源导致您出现问题? remote_file是唯一一个我怀疑是非幂等的,但我不确定。
看着厨师维基,我发现了这个:
不推荐使用的行为在Chef 0.8.x及更早版本中,远程文件也是 用于从cookbook中的files /目录中获取文件。这个 行为现在由#Cookbook文件提供,并使用远程文件 在Chef 0.9.0和。中,这个目的已被弃用(尽管仍然有效) 后面。
无论如何,厨师倾向于工作的方式,它会查看是否存在"#{Chef::Config[:file_cache_path]}/node-v#{node["nodejs"]["version"]}.tar.gz"
解析为什么,如果存在,它应该跳过该资源。 install-node
完成安装后是否可能删除该文件?如果是这样,厨师每次都会重新获取它。
答案 2 :(得分:1)
根据我的经验remote_file
总是在执行chef-client
时运行,即使目标文件已经存在。我不确定为什么(没有挖掘Chef代码来找到错误的确切原因)。
您始终可以编写not_if
或only_if
来控制remote_file
资源的执行,但通常每次都让它运行是无害的。
其余代码看起来已经是幂等的,因此重复运行客户端没有任何害处。
您可以为remote_file
指定一项操作,使其有条件地运行:
remote_file 'target' do
source 'wherever'
action :create_if_missing
end
请参阅the docs。
答案 3 :(得分:1)
只能使用 -o 修饰符覆盖运行列表一次运行配方。
sudo chef-client -o "recipe[cookbook::recipe]"
-o RunlistItem,RunlistItem ...,用指定的项目替换当前运行列表
- 覆盖-运行列表
答案 4 :(得分:0)
如果你想测试你的食谱是否是幂等的,你可能会对ToASTER感兴趣,这是一个系统测试Chef脚本的框架。
http://cloud-toaster.github.io/
在隔离容器环境(Docker VM)中使用不同配置执行Chef配方,ToASTER报告各种指标,如系统状态更改,收敛属性和幂等性问题。