Chef recipe execution order

2019-08-17 16:49发布

following is a recipe which I use to copy and install a software on my windows server.

batch "Get installed software list" do
  code "wmic /output:C:\\InstallList.txt product get name,version"
end

if File.read('C:/InstallList.txt', mode: 'r:BOM|UTF-16:UTF-8') =~ /.NET Framework 4/
  print "Dotnet framework 4 is already installed."
else
  remote_file 'c:/repo/dotNetFx40_Full_x86_x64.exe' do
    source 'file:////10.132.17.53/e$/CHEFREPO/dotNetFx40_Full_x86_x64.exe'
  end
  batch "Install Dotnet" do
    cwd 'c:/repo/'
    code <<-EOH
        dotNetFx40_Full_x86_x64.exe  #{node['mycloud_dotnet']['passive']} #{node['mycloud_dotnet']['CEIPconsent']} #{node['mycloud_dotnet']['chainingpackage']} #{node['mycloud_dotnet']['createlayout']} #{node['mycloud_dotnet']['lcid']} #{node['mycloud_dotnet']['log']} #{node['mycloud_dotnet']['msioptions']} #{node['mycloud_dotnet']['norestart']} #{node['mycloud_dotnet']['promptrestart']} #{node['mycloud_dotnet']['quit']} #{node['mycloud_dotnet']['repair']} #{node['mycloud_dotnet']['serialdownload']} #{node['mycloud_dotnet']['uninstall']} #{node['mycloud_dotnet']['parameterfolder']} #{node['mycloud_dotnet']['NoSetUpVersionCheck']} #{node['mycloud_dotnet']['uninstallpatch']} 
        del dotNetFx40_Full_x86_x64.exe

    EOH
    not_if {File.read('c:/InstallList.txt', mode: 'r:BOM|UTF-16:UTF-8') =~ /.NET Framework 4/}
  end
end

The batch resource, created a text file which contains the list of already installed software. Then I read this file to check if the software is already installed. It it is, I print a message. Else the recipe moves into my else part, where I download the setup from remote repository and then install it using silent installation. But on the client run, I get an error as following :

[2014-08-22T05:26:38-07:00] FATAL: Errno::ENOENT: No such file or directory - C:
/InstallList.txt

My client is somehow executing the File.read code in the if block, before executing the first batch resource("Get installed Software List"). Any ideas what might be going wrong and a workaround for the same.

1条回答
再贱就再见
2楼-- · 2019-08-17 17:18

Yes, your if code is executed during compile phase, while your batch ressource is executed within the converge phase see details here.

You can achieve what you wish by running the batch resource at compile time like:

batch "Get installed software list" do
  code "wmic /output:C:\\InstallList.txt product get name,version"
  action :nothing
end.run_action(:run)

In your case including your code in the not_if block and getting rid of the if/else part is another option i.e:

remote_file 'c:/repo/dotNetFx40_Full_x86_x64.exe' do
  source 'file:////10.132.17.53/e$/CHEFREPO/dotNetFx40_Full_x86_x64.exe'
end

batch "Install Dotnet" do
  cwd 'c:/repo/'
  code <<-EOH
    dotNetFx40_Full_x86_x64.exe  #{node['mycloud_dotnet']['passive']} #                 {node['mycloud_dotnet']['CEIPconsent']} #{node['mycloud_dotnet']['chainingpackage']} #{node['mycloud_dotnet']['createlayout']} #{node['mycloud_dotnet']['lcid']} #{node['mycloud_dotnet']['log']} #{node['mycloud_dotnet']['msioptions']} #{node['mycloud_dotnet']['norestart']} #{node['mycloud_dotnet']['promptrestart']} #{node['mycloud_dotnet']['quit']} #{node['mycloud_dotnet']['repair']} #{node['mycloud_dotnet']['serialdownload']} #{node['mycloud_dotnet']['uninstall']} #{node['mycloud_dotnet']['parameterfolder']} #{node['mycloud_dotnet']['NoSetUpVersionCheck']} #{node['mycloud_dotnet']['uninstallpatch']} 
    del dotNetFx40_Full_x86_x64.exe
  EOH
  not_if { `wmic /output:C:\\InstallList.txt product get name,version` =~ /.NET Framework 4/ }
end

The remote file could have a guard on it to avoid downloading each time:

not_if { File::exists(...) }
查看更多
登录 后发表回答