Chef infra 影响通知资源的厨师长资源通知

Chef infra 影响通知资源的厨师长资源通知,chef-infra,chef-recipe,Chef Infra,Chef Recipe,我对Chef比较陌生,我第一次尝试使用:before计时器发送一些通知。想法很简单:我有一个自定义资源,它从存储库中提取一个工件,将其保存到暂存目录,然后将其部署到部署目录。如果定制资源发现必须部署工件,则当前部署将备份到备份目录,并部署新工件。如果不需要部署工件(由于下面的not_If{some_condition}行),则不会运行任何备份步骤(这就是使用通知的全部意义,因为备份步骤仅通过通知触发) 为了实现此功能,我使用操作:nothing创建了几个资源,并使用通知和:before计时器(见

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

为了实现此功能,我使用
操作:nothing
创建了几个资源,并使用通知和
:before
计时器(见下文)从自定义资源运行它们。我尝试的每一次跑步都有
某些条件
评估为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\u cache
自定义资源中的一些操作都会被跳过,我不知道为什么。这导致运行失败,因为不是从自定义资源中创建临时目录(它与我通过通知实际操作的目录无关)。在没有通知的情况下,日志显示
-创建的目录/staging/dir
,我收到的通知
-将创建新的目录/staging/dir

当我运行下面的第二个代码段时,一切正常。如果
some\u条件
为false,我希望这两个代码片段是等价的。为什么通知似乎会影响通知资源的行为?我错过什么了吗

# 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中实现它。例如,编写a(还)或编写a(还)。

我不是为了实现代码重用而使用通知,而是为了实现幂等性。我所有的资源都有唯一的名称。另外,我的想法是不必按照资源编写的顺序运行资源,这就是我使用
:before
计时器的原因。你真的读过我的问题吗?:之前的通知可能是错误的方式,但可能的情况是,我的\u工件\u缓存它里面的所有子资源没有正确地写入为什么安全运行,并且正确地报告它们在为什么运行模式下运行时是否会更新。如果您跟踪并修复了所有的why run bug,那么:before通知应该会起作用。将用于备份的代码放入资源本身可能会更好,并且最好使用纯ruby FileUtils/File/Dir调用强制编写,而不是使用声明性chef资源。您使用execute资源触发mv的方式是一些代码气味。