厨师配方执行顺序 [英] Chef recipe execution order
问题描述
以下是我用来在Windows服务器上复制并安装软件的食谱.
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
批处理资源创建了一个文本文件,其中包含已安装软件的列表.然后,我读取此文件以检查软件是否已安装.是的,我打印一条消息.否则,该食谱将移至我的else部分,在那里我从远程存储库下载设置,然后使用静默安装进行安装. 但是在客户端运行时,出现如下错误:
[2014-08-22T05:26:38-07:00] FATAL: Errno::ENOENT: No such file or directory - C:
/InstallList.txt
在执行第一批resource("Get installed Software List")
之前,我的客户端以某种方式在if块中执行File.read
代码.任何想法可能出了什么问题,以及解决方法.
if
代码是在编译阶段执行的,而您的batch
资源是在收敛阶段执行的,请参见 batch "Get installed software list" do
code "wmic /output:C:\\InstallList.txt product get name,version"
action :nothing
end.run_action(:run)
在您的情况下,将代码包含在not_if
块中,并且除去if/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 { `wmic /output:C:\\InstallList.txt product get name,version` =~ /.NET Framework 4/ }
end
远程文件可能带有保护措施,以避免每次都下载:
not_if { File::exists(...) }
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.
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(...) }
这篇关于厨师配方执行顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!