影响通知资源的 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).
我对 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).