问题
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:
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(...) }
来源:https://stackoverflow.com/questions/25447227/chef-recipe-execution-order