影响通知资源的 Chef 资源通知

Chef resource notifications affecting notifying resource

我对 Chef 比较陌生,我第一次尝试使用 :before 计时器来发送一些通知。这个想法很简单:我有一个自定义资源,它从存储库中提取工件,将其保存到暂存目录,然后将其部署到部署目录。如果自定义资源发现必须部署工件,则将当前部署备份到备份目录并部署新工件。如果不需要部署工件(由于下面的 not_if { some_condition } 行),则不会有任何备份步骤 运行(这就是使用通知的全部意义,因为备份步骤仅通过通知触发)。

为了实现此功能,我使用 action :nothing 创建了多个资源,并使用通知和 :before 计时器从我的自定义资源中 运行 连接它们(见下文) .我尝试的每个 运行 都 some_condition 评估为 false。

# SNIPPET 1 - This is my intended code, whose behavior I can't understand. 
# All backup actions are set to :nothing and will be triggered
# only if some_condition is false.

directory "delete #{backup_dir}" do
  recursive true
  path backup_dir
  action :nothing
end

directory "create #{backup_dir}" do
  owner node['my_cookbook']['owner']
  group node['my_cookbook']['group']
  path backup_dir
  mode '0755'
  recursive true
  action :nothing
end

execute 'backup current deployment' do
  command "mv #{deployments_dir} #{backup_dir}"
  action :nothing
  only_if { ::Dir.exists?(deployments_dir) }
end

directory "create #{deployments_dir}" do
  path deployments_dir
  owner node['my_cookbook']['owner']
  group node['my_cookbook']['group']
  mode  "0755"
  recursive true
  action :nothing
end

node['my_cookbook']['artifacts'].each do |artifact_name|
  config = my_environment(artifact_name, node)
  # This custom resource downloads the artifact to a staging directory
  # and then moves it to deployments_dir.
  my_artifact_cache "my_cookbook::deploy_artifacts - Pull cached artifact #{artifact_name}" do
    snapshot      config['repository'] == 'snapshot'
    group_id      config['group_id']
    artifact_id   config['artifact_id']
    version       config['version']
    filetype      config['filename_extension']
    path          deployments_dir
    owner         node['my_cookbook']['owner']
    group         node['my_cookbook']['group']
    mode          "0755"
    action :pull
    not_if { some_condition }
    notifies :delete, "directory[delete #{backup_dir}]", :before
    notifies :create, "directory[create #{backup_dir}]", :before
    notifies :run, 'execute[backup current deployment]', :before
    notifies :create, "directory[create #{deployments_dir}]", :before
  end
end

但是,每次我 运行 上面的代码时,都会跳过 my_artifact_cache 自定义资源 中的某些操作 ,我不知道为什么。这导致 运行 失败,因为暂存目录(与我实际通过通知操作的目录无关)不是从自定义资源中创建的。没有通知,日志显示 - created directory /staging/dir,有通知我得到 - Would create new directory /staging/dir

当我 运行 下面的第二个片段时,一切正常。我希望这两个片段在 some_condition 为假的情况下是等价的。为什么通知似乎会影响通知资源的行为?我错过了什么吗?

# SNIPPET 2 - Commented out the :nothing actions, replaced them with the actions
# from the notifications - this snippet works as expected. I expected
# snippet 1 to be equivalent during runtime if some_condition is false

directory "delete #{backup_dir}" do
  recursive true
  path backup_dir
  #action :nothing
  action :delete
end

directory "create #{backup_dir}" do
  owner node['my_cookbook']['owner']
  group node['my_cookbook']['group']
  path backup_dir
  mode '0755'
  recursive true
  #action :nothing
end

execute 'backup current deployment' do
  command "mv #{deployments_dir} #{backup_dir}"
  #action :nothing
  only_if { ::Dir.exists?(deployments_dir) }
end

directory "create #{deployments_dir}" do
  path deployments_dir
  owner node['my_cookbook']['owner']
  group node['my_cookbook']['group']
  mode  "0755"
  recursive true
  #action :nothing
end

node['my_cookbook']['artifacts'].each do |artifact_name|
  config = my_environment(artifact_name, node)
  # This custom resource downloads the artifact to a staging directory
  # and then moves it to deployments_dir.
  my_artifact_cache "my_cookbook::deploy_artifacts - Pull cached artifact #{artifact_name}" do
    snapshot      config['repository'] == 'snapshot'
    group_id      config['group_id']
    artifact_id   config['artifact_id']
    version       config['version']
    filetype      config['filename_extension']
    path          deployments_dir
    owner         node['my_cookbook']['owner']
    group         node['my_cookbook']['group']
    mode          "0755"
    action :pull
    not_if { some_condition }
    #notifies :delete, "directory[delete #{backup_dir}]", :before
    #notifies :create, "directory[create #{backup_dir}]", :before
    #notifies :run, 'execute[backup current deployment]', :before
    #notifies :create, "directory[create #{deployments_dir}]", :before
  end
end

chef 资源 运行 按写入顺序排列。这意味着您可以按顺序实现您的逻辑。

在我看来你正在使用 notifications in order to achieve code reuse, but notification is not the way to go, since each chef resource must have unique name in order to avoid any resource collision or incorrect notifications, this is why resource cloning has been deprecated

如果是这样的话,在 chef 中有更好的方法来实现它。比如,写一个 custom light weight resource provider (lwrp) (also read this), or writing a library (also read this).