厨师(Chef):为什么“include_recipe”步骤中的资源被跳过?

28

厨师似乎在以奇怪的顺序处理资源,导致我的构建失败。 我的主配方 (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"
  %w{build-essential binutils-doc}.each do |pkg|
    package pkg do
      action :install
    end
  end
when "centos","redhat","fedora","scientific"
  %w{gcc 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

在运行时,由于我不理解的原因,该build-essential配方被加载但未执行:

[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

也就是说,build-essential配方被"找到"和"加载"了,但是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。

那么,有几个问题:

  1. 为什么build-essential没有被“处理”?
  2. 正确的方式是什么?(我没有编写这些配方,我知道它们适用于作者)
  3. 站点食谱和食谱“shadowing”特性是否仍然有效?它据说已经被弃用:http://tickets.opscode.com/browse/CHEF-2308(我尝试在site-cookbooks/mytardis/recipes/build-essential下创建符号链接,但是没有成功)。

你可以在 build-essential/recipes/default.rb 中添加 Chef::Log.info("I am in #{cookbook_name}::#{recipe_name}"),当加载该 recipe 时,它将打印日志消息。异常处理程序创建的文件(例如 "/var/chef/cache/failed-run-data.json")还将包含所有已加载资源的完整资源集合,这有助于调试是否已添加 recipe 中的资源。 - jtimberman
菜谱阴影功能是指您可以通过将其放在站点菜谱中来覆盖存在于菜谱中的组件,而不仅仅是在两个位置都拥有单独的菜谱。 - jtimberman
2个回答

40

这是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
  }
)

1
今天我在使用另一个依赖于 database::postgresql 的 cookbook 时遇到了这个问题,而 database::postgresql 又依赖于 postgresql::ruby。目前 postgresql::ruby 的配方会在 Chef 运行的 编译 阶段安装 pg gem、libpqpostgresql。正如这个答案所指出的那样,它通过使用 run_action(:install) 来实现。 - TrinitronX
在某些情况下,有另一种解决方法...例如:在包含 postgresql::ruby 的 cookbook 上运行 kitchen test 可能会导致过时的软件包缓存引起 apt 错误。为了解决这个问题,我们可以使用 now cookbook 的 DSL,在 Chef 运行开始时强制执行 apt-get update,像这样:include_recipe_now 'apt' - TrinitronX

6
如果您正在编写一本菜谱,请在属性文件中添加该属性:
node.default['build_essential']['compiletime'] = true

感谢上面的Colin。

这是否仅适用于build_essential配方,还是可以在任何地方使用?有文档记录吗? - Steve Bennett
Steve,这个语法在任何食谱中都可以使用。node是Chef Node的“self”引用,默认是自我标题设置,在烹饪书/食谱使用时会应用,除非再次覆盖。另外两个选项是build_essential特定的。 - toobulkeh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接