厨师循环并通知

chef loop and notifies

为了将两个证书放入盒子中,然后将它们添加到钱包中,我使用了以下代码。

RDS_CA_CERTS = %w[ cert1.cer cert2.cer]
RDS_CA_CERTS.each do |rds_ca_cert|
  cookbook_file "/oracle_home/ssl_wallet/#{rds_ca_cert}" do
    source "certs/#{rds_ca_cert}"
    owner 'oracle'
    group 'dba'
    mode '0644'
    action :create
    notifies :run, 'execute[import_rds_cert]', :immediately
  end

  execute 'import_rds_cert' do
    command "orapki wallet add -wallet /oracle_home/ssl_wallet -trusted_cert -cert /oracle_home/ssl_wallet/#{rds_ca_cert} -auto_login_only"
    user 'oracle'
    group 'dba'
    umask '0025'
    action :nothing
  end
end

我原以为上面的代码会引入一个文件 cert1.cer 并触发相同的执行。然后它将引入 cert2.cer 并触发执行。 这样只有在添加文件时才会触发执行(执行资源的门)

但在 TK 中观察到的行为对我来说有点奇怪。它引入 cert1.cer 文件,然后当它触发执行时失败,说 cert2.cer 不存在。 只有在触发执行之前循环已移动到下一个文件时才会发生这种情况。

你能解释一下这个行为吗? 什么是更好的替代方法?

您的代码生成 2 个 cookbook_file 资源和 2 个执行资源。不幸的是,您的执行资源具有相同的名称,并最终由 Chef 合并为 1 个资源,后一个资源的命令覆盖了前一个资源。所以你的 cookbook_file "/oracle_home/ssl_wallet/cert1.cer" 资源触发 execute 'import_rds_cert' 资源 command "orapki wallet add -wallet /oracle_home/ssl_wallet -trusted_cert -cert /oracle_home/ssl_wallet/cert2.cer -auto_login_only".

要解决您的问题,请更改执行资源的名称,使其依赖于 rds_ca_cert 变量。这样 Chef 也会生成 2 个不同的执行资源。

cookbook_file "/oracle_home/ssl_wallet/#{rds_ca_cert}" do
  [...]
  notifies :run, "execute[import_rds_cert_#{rds_ca_cert}]", :immediately
end

execute "import_rds_cert_#{rds_ca_cert}" do
  [...]
end