厨师:为啥跳过“include_recipe”步骤中的资源?

Posted

技术标签:

【中文标题】厨师:为啥跳过“include_recipe”步骤中的资源?【英文标题】:Chef: Why are resources in an "include_recipe" step being skipped?厨师:为什么跳过“include_recipe”步骤中的资源? 【发布时间】:2012-07-07 23:48:01 【问题描述】:

Chef 似乎以奇怪的顺序处理资源,导致我的构建失败。我的主要食谱 (mytardis-chef/site-cookbooks/recipes/default.rb) 是这样开始的:

include_recipe "build-essential"
include_recipe "mytardis::deps"
include_recipe "mytardis::nginx"
include_recipe "mytardis::postgresql"

mytardis-chef/cookbooks/build-essential/recipes/default.rb 看起来像这样:

case node['platform']
when "ubuntu","debian"
  %wbuild-essential binutils-doc.each do |pkg|
    package pkg do
      action :install
    end
  end
when "centos","redhat","fedora","scientific"
  %wgcc gcc-c++ kernel-devel make.each do |pkg|
    package pkg do
      action :install
    end
  end
end

...(这是https://github.com/opscode-cookbooks/build-essential/blob/master/recipes/default.rb 的旧版本)

在运行时,由于我不明白的原因,这个构建基本配方被加载但未执行:

[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] Mounting shared folders...
[default] -- v-root: /vagrant
[default] -- v-csr-3: /tmp/vagrant-chef-1/chef-solo-3/roles
[default] -- v-csc-2: /tmp/vagrant-chef-1/chef-solo-2/cookbooks
[default] -- v-csc-1: /tmp/vagrant-chef-1/chef-solo-1/cookbooks
[default] -- v-csdb-4: /tmp/vagrant-chef-1/chef-solo-4/data_bags
[default] Running provisioner: Vagrant::Provisioners::ChefSolo...
[default] Generating chef JSON and uploading...
[default] Running chef-solo...
[Sun, 08 Jul 2012 05:14:32 +0200] INFO: *** Chef 10.12.0 ***
[Sun, 08 Jul 2012 05:14:32 +0200] DEBUG: Building node object for lucid32
[Sun, 08 Jul 2012 05:14:32 +0200] DEBUG: Extracting run list from JSON attributes provided on command line
[Sun, 08 Jul 2012 05:14:32 +0200] INFO: Setting the run_list to ["recipe[mytardis]"] from JSON
[Sun, 08 Jul 2012 05:14:32 +0200] DEBUG: Applying attributes from json file
[Sun, 08 Jul 2012 05:14:32 +0200] DEBUG: Platform is ubuntu version 10.04
[Sun, 08 Jul 2012 05:14:32 +0200] INFO: Run List is [recipe[mytardis]]
[Sun, 08 Jul 2012 05:14:32 +0200] INFO: Run List expands to [mytardis]
[Sun, 08 Jul 2012 05:14:32 +0200] INFO: Starting Chef Run for lucid32
[Sun, 08 Jul 2012 05:14:32 +0200] INFO: Running start handlers
[Sun, 08 Jul 2012 05:14:32 +0200] INFO: Start handlers complete.
...
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Loading Recipe mytardis via include_recipe
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Found recipe default in cookbook mytardis
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Loading Recipe build-essential via include_recipe
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Found recipe default in cookbook build-essential
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Loading Recipe mytardis::deps via include_recipe
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Found recipe deps in cookbook mytardis
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Loading Recipe mytardis::nginx via include_recipe
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Found recipe nginx in cookbook mytardis
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Loading Recipe iptables via include_recipe
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Found recipe default in cookbook iptables
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Loading Recipe mytardis::postgresql via include_recipe
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Found recipe postgresql in cookbook mytardis
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Loading Recipe postgresql::server via include_recipe
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Found recipe server in cookbook postgresql
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Loading Recipe postgresql::client via include_recipe
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: Found recipe client in cookbook postgresql
[Sun, 08 Jul 2012 05:14:33 +0200] INFO: Processing package[postgresql-client] action install (postgresql::client line 37)
[Sun, 08 Jul 2012 05:14:33 +0200] DEBUG: package[postgresql-client] checking package status for postgresql-client
....
[Sun, 08 Jul 2012 05:14:45 +0200] ERROR: gem_package[pg] (postgresql::client line 42) has had an error
.
make
sh: make: not found

也就是说,构建基本配方是“找到”和“加载”的,但首先“处理”的是 postgres 配方。而且由于 build-essential(安装 C 编译器)没有运行,后者失败了。

我的 Vagrantfile 的相关部分如下所示:

  config.vm.provision :chef_solo do |chef|
     chef.log_level = :debug
     chef.cookbooks_path = ["mytardis-chef/site-cookbooks", "mytardis-chef/cookbooks"]
     chef.roles_path = "mytardis-chef/roles"
     chef.data_bags_path = "mytardis-chef/data_bags"
     chef.add_recipe "mytardis"    
  end

我之前使用的是稍早版本的 Chef(可能是 10.10.0?)在那个版本中,build-essential 也没有运行,但 mytardis::deps 运行了。现在使用 Chef 10.12.0。物理机是 OSX,VM 是 Ubuntu Lucid。

所以,有几个问题:

    为什么 build-essential 没有被“处理”? 这样做的正确方法是什么? (这些食谱不是我写的,我知道他们为他们的作者做过或曾经为他们工作过。) 站点食谱和食谱的“阴影”功能是否仍然有效?据说已弃用:http://tickets.opscode.com/browse/CHEF-2308(我尝试在 site-cookbooks/mytardis/recipes/build-essential 下创建一个符号链接,但没有任何乐趣)。

【问题讨论】:

您可以将 Chef::Log.info("I am in #cookbook_name::#recipe_name") 放在 build-essential/recipes/default.rb 中,它会打印日志加载配方时的消息。由异常处理程序创建的文件,例如“/var/chef/cache/failed-run-data.json”也将包含它加载的所有资源的完整资源集合,这有助于调试资源是否在配方已添加。 cookbook shadowing 功能是您可以通过将存在于cookbook 中的组件放在站点cookbooks 中来覆盖它们,而不仅仅是在两个位置有单独的cookbook。 【参考方案1】:

事实证明,这是 Chef 工作方式中一个非常正常(但记录不足)的部分:它编译所有内容,然后 然后 开始运行。除了一些配方(如 Postgres)在编译时跳入队列以实际安装,使用如下代码:

  action :nothing
end.run_action(:run)

解决方案是任何需要在 Postgres 之前运行的东西也需要这样做。幸运的是,较新版本的 Build-essentials 允许这样做。您在角色上设置属性如下:

name "myapp"
run_list(
  "recipe[build-essential]",
  "recipe[myapp]"
)
default_attributes(
  "build_essential" => 
    "compiletime" => true
  
)

【讨论】:

我今天遇到了另一个食谱,它依赖于database::postgresql,而这又依赖于postgresql::rubypostgresql::ruby 的当前配方安装 pg gem、libpqpostgresql 都在 Chef 运行的 编译 阶段。正如这个答案所指出的那样,它通过使用run_action(:install) 来做到这一点。 在某些情况下还有另一种解决此问题的方法...例如:在包含 postgresql::ruby 的说明书上运行 kitchen test 可能会导致来自陈旧包缓存的 apt 错误。为了解决这个问题,我们可以使用 now 食谱的 DSL 在 Chef 运行开始时强制使用 apt-get update,如下所示:include_recipe_now 'apt'【参考方案2】:

如果要编写食谱,请将属性添加到您的属性文件中:

node.default['build_essential']['compiletime'] = true

感谢上面的科林。

【讨论】:

这是特定于 build_essential 配方的,还是在任何地方都有效?有记录吗? 史蒂夫,该语法可用于任何配方。节点是厨师节点的“自我”引用,默认是应用于食谱/食谱使用的自我标题设置,除非再次覆盖。其他两个选项是特定于 build_essential 的。

以上是关于厨师:为啥跳过“include_recipe”步骤中的资源?的主要内容,如果未能解决你的问题,请参考以下文章

java讨论:啥是多态和接口,为啥需要?

如何将厨师服务器 11 升级到 12

使用Vagrant驱动程序的厨师供应

多线程和蕃茄炒蛋

为啥 XmlReader 跳过标签?

为啥程序跳过while循环