每个方法中的厨师通知
Chef notification within each method
我有一个在 each
方法中迭代包含 SQL 脚本的散列的方法,并且 - 如果脚本从之前的 运行 改变 - cookbook_file
资源通知 execute
资源到 运行。
问题是它似乎总是 运行s execute
使用散列的最后一个元素。
遵循属性文件
default['sql_scripts_dir'] = 'C:\DBScripts'
default['script_runner']['scripts'] = [
{ 'name' => 'test', 'hostname' => 'local' },
{ 'name' => 'test2', 'hostname' => 'local' },
{ 'name' => 'test3', 'hostname' => 'local' },
{ 'name' => 'test4', 'hostname' => 'local' },
]
还有食谱
directory node['sql_scripts_dir'] do
recursive true
end
node['script_runner']['scripts'].each do |script|
cookbook_file "#{node['sql_scripts_dir']}\#{script['name']}.sql" do
source "#{script['name']}.sql"
action :create
notifies :run, 'execute[Create_scripts]', :immediately
end
execute 'Create_scripts' do
command "sqlcmd -S \"#{script['hostname']}\" -i \"#{node['sql_scripts_dir']}\#{script['name']}.sql\""
action :nothing
end
end
它产生以下输出:
Recipe: test_runner::default
* directory[C:\DBScripts] action create
- create new directory C:\DBScripts
* cookbook_file[C:\DBScripts\test.sql] action create
- create new file C:\DBScripts\test.sql
- update content in file C:\DBScripts\test.sql from none to 8c40f1
--- C:\DBScripts\test.sql 2020-07-30 17:30:30.959220400 +0000
+++ C:\DBScripts/chef-test20200730-1500-11bz3an.sql 2020-07-30 17:30:30.959220400 +0000
@@ -1 +1,2 @@
+select @@version
* execute[Create_scripts] action run
================================================================================
Error executing action `run` on resource 'execute[Create_scripts]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '1'
---- Begin output of sqlcmd -S "local" -i "C:\DBScripts\test4.sql" ----
STDOUT:
STDERR: Sqlcmd: 'C:\DBScripts\test4.sql': Invalid filename.
---- End output of sqlcmd -S "local" -i "C:\DBScripts\test4.sql" ----
Ran sqlcmd -S "local" -i "C:\DBScripts\test4.sql" returned 1
预期的行为是配方 运行 依次显示示例中的 4 个脚本,而不是 运行 仅最后一个。我错过了什么来完成它?
您正在创建 4 个几乎相同的资源,所有资源都命名为 execute[Create_scripts]
,当通知从第一个正在更新的 cookbook_file
资源触发时,它会找到 最后一个 其中的一个将被通知并针对 test4
运行(无论哪个 cookbook_file 资源更新)。
修复方法是使用字符串插值将执行资源的名称更改为唯一的,并根据该唯一名称进行通知:
directory node['sql_scripts_dir'] do
recursive true
end
node['script_runner']['scripts'].each do |script|
cookbook_file "#{node['sql_scripts_dir']}\#{script['name']}.sql" do
source "#{script['name']}.sql"
action :create
notifies :run, "execute[create #{script['name']} scripts]", :immediately
end
execute "create #{script['name']} scripts" do
command "sqlcmd -S \"#{script['hostname']}\" -i \"#{node['sql_scripts_dir']}\#{script['name']}.sql\""
action :nothing
end
end
请注意,这是旧 CHEF-3694 警告消息背后的相同问题的表现,其中会发生的情况是所有四个执行资源将通过“资源克隆”合并到一个资源中,具有后续资源是“last-writer-wins”。
在 Chef 13 中,这已更改为删除资源克隆和警告,并且在大多数情况下,资源集合中有两个名称相同的资源是完全无害的——除非您尝试通知其中一个资源。在这种情况下,资源通知系统应该真正发出警告,而不是静静地选择最后一个匹配的资源(但是在通知、订阅、惰性解析和现在 unified_mode 之间,代码非常复杂,你只希望它在准确的条件下触发合适的条件)。
我有一个在 each
方法中迭代包含 SQL 脚本的散列的方法,并且 - 如果脚本从之前的 运行 改变 - cookbook_file
资源通知 execute
资源到 运行。
问题是它似乎总是 运行s execute
使用散列的最后一个元素。
遵循属性文件
default['sql_scripts_dir'] = 'C:\DBScripts'
default['script_runner']['scripts'] = [
{ 'name' => 'test', 'hostname' => 'local' },
{ 'name' => 'test2', 'hostname' => 'local' },
{ 'name' => 'test3', 'hostname' => 'local' },
{ 'name' => 'test4', 'hostname' => 'local' },
]
还有食谱
directory node['sql_scripts_dir'] do
recursive true
end
node['script_runner']['scripts'].each do |script|
cookbook_file "#{node['sql_scripts_dir']}\#{script['name']}.sql" do
source "#{script['name']}.sql"
action :create
notifies :run, 'execute[Create_scripts]', :immediately
end
execute 'Create_scripts' do
command "sqlcmd -S \"#{script['hostname']}\" -i \"#{node['sql_scripts_dir']}\#{script['name']}.sql\""
action :nothing
end
end
它产生以下输出:
Recipe: test_runner::default
* directory[C:\DBScripts] action create
- create new directory C:\DBScripts
* cookbook_file[C:\DBScripts\test.sql] action create
- create new file C:\DBScripts\test.sql
- update content in file C:\DBScripts\test.sql from none to 8c40f1
--- C:\DBScripts\test.sql 2020-07-30 17:30:30.959220400 +0000
+++ C:\DBScripts/chef-test20200730-1500-11bz3an.sql 2020-07-30 17:30:30.959220400 +0000
@@ -1 +1,2 @@
+select @@version
* execute[Create_scripts] action run
================================================================================
Error executing action `run` on resource 'execute[Create_scripts]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '1'
---- Begin output of sqlcmd -S "local" -i "C:\DBScripts\test4.sql" ----
STDOUT:
STDERR: Sqlcmd: 'C:\DBScripts\test4.sql': Invalid filename.
---- End output of sqlcmd -S "local" -i "C:\DBScripts\test4.sql" ----
Ran sqlcmd -S "local" -i "C:\DBScripts\test4.sql" returned 1
预期的行为是配方 运行 依次显示示例中的 4 个脚本,而不是 运行 仅最后一个。我错过了什么来完成它?
您正在创建 4 个几乎相同的资源,所有资源都命名为 execute[Create_scripts]
,当通知从第一个正在更新的 cookbook_file
资源触发时,它会找到 最后一个 其中的一个将被通知并针对 test4
运行(无论哪个 cookbook_file 资源更新)。
修复方法是使用字符串插值将执行资源的名称更改为唯一的,并根据该唯一名称进行通知:
directory node['sql_scripts_dir'] do
recursive true
end
node['script_runner']['scripts'].each do |script|
cookbook_file "#{node['sql_scripts_dir']}\#{script['name']}.sql" do
source "#{script['name']}.sql"
action :create
notifies :run, "execute[create #{script['name']} scripts]", :immediately
end
execute "create #{script['name']} scripts" do
command "sqlcmd -S \"#{script['hostname']}\" -i \"#{node['sql_scripts_dir']}\#{script['name']}.sql\""
action :nothing
end
end
请注意,这是旧 CHEF-3694 警告消息背后的相同问题的表现,其中会发生的情况是所有四个执行资源将通过“资源克隆”合并到一个资源中,具有后续资源是“last-writer-wins”。
在 Chef 13 中,这已更改为删除资源克隆和警告,并且在大多数情况下,资源集合中有两个名称相同的资源是完全无害的——除非您尝试通知其中一个资源。在这种情况下,资源通知系统应该真正发出警告,而不是静静地选择最后一个匹配的资源(但是在通知、订阅、惰性解析和现在 unified_mode 之间,代码非常复杂,你只希望它在准确的条件下触发合适的条件)。