厨师配方执行顺序 [英] Chef recipe execution order

查看:167
本文介绍了厨师配方执行顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我用来在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆