使厨师食谱配方只运行一次

Jür*_*aul 4 ruby chef-infra chef-recipe vagrant

所以我使用以下配方:

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
Run Code Online (Sandbox Code Playgroud)

它成功地在我的Vagrant VM上安装了nodejs但是在重新启动时它又被重新执行了.我该如何防止这种情况?我在阅读ruby代码时并不是那么好.

Hol*_*ust 8

要使remote_file资源具有幂等性(即不再下载已经存在的文件),您必须正确指定文件的校验和.您可以使用该node["nodejs"]["checksum"]属性在代码中执行此操作.但是,这只能起作用,如果校验和被正确指定为下载文件的SHA256哈希值,则不支持其他算法(特别是不是MD5).

如果校验和不正确,您的配方仍然有效.但是,在下一次运行时,Chef会注意到现有文件的校验和与您指定的文件不同,并且会再次下载文件,从而通知install noderessource并执行整个编译工作.