【问题标题】:Chef notification within each method每种方法中的厨师通知
【发布时间】:2020-08-05 06:21:24
【问题描述】:

我有一个配方,它在 each 方法中迭代包含 SQL 脚本的哈希,并且——如果脚本从上次运行发生变化——cookbook_file 资源会通知 execute 资源运行。 问题是它似乎总是使用哈希的最后一个元素运行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 个 cookbook_file 资源和 4 个几乎相同的资源,均名为 execute[Create_scripts],当通知触发时,它总是找到最后一个,因此它与 test4 运行。你需要execute "create #{script['name']} scripts" 之类的东西,并类似地更改通知。
  • 好点,会试试
  • 像魅力一样工作,@lamont 请将其转换为答案,以便我接受。谢谢
  • 好的,写下来。

标签: ruby chef-infra devops


【解决方案1】:

您正在创建 4 个几乎相同的资源,均名为 execute[Create_scripts],当通知从第一个正在更新的 cookbook_file 资源触发时,它会发现 最后一个其中一个要被通知并针对 @ 987654323@(无论哪个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 警告消息背后相同问题的表现,其中会发生的情况是所有四个执行资源将通过“资源克隆”与后续资源的属性合并到一个资源中成为“最后一位作家获胜”。

在 Chef 13 中,这已更改为删除资源克隆和警告,并且在大多数情况下,在资源集合中拥有两个命名相同的资源是完全无害的 - 直到您尝试通知其中一个资源。在这种情况下,资源通知系统应该真正发出警告,而不是默默地选择最后一个匹配的资源(但在通知、订阅、延迟解析和现在的统一模式之间,代码非常复杂,你只希望它在完全正确的条件下触发) .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    相关资源
    最近更新 更多