无法在本地模式下解决 Chef 外部菜谱依赖关系

无法在本地模式下解决 Chef 外部菜谱依赖关系

我正在 Chef 中制作我的第一道菜谱。我创建了一本名为 common 的食谱书,其中只有一个菜谱 (default.rb):

apt_repository "mariadb-repo" do
  uri "http://tedeco.fi.upm.es/mirror/mariadb/repo/10.1/ubuntu"
  distribution "trusty"
  components ["main"]
  arch "amd64"
  keyserver "keyserver.ubuntu.com"
  key "CBCB082A"
end

我在 metadata.rb 的末尾添加了“depends 'apt'”。如果我运行:

Starting Chef Client, version 12.5.1
resolving cookbooks for run list: ["common"]

================================================================================
Error Resolving Cookbooks for Run List:
================================================================================

Missing Cookbooks:
------------------
No such cookbook: apt

Expanded Run List:
------------------
* common


Running handlers:
[2016-01-28T13:07:17+00:00] ERROR: Running exception handlers
Running handlers complete
[2016-01-28T13:07:17+00:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated in 01 seconds
[2016-01-28T13:07:17+00:00] FATAL: Stacktrace dumped to /home/vagrant/.chef/local-mode-cache/cache/chef-stacktrace.out
[2016-01-28T13:07:17+00:00] ERROR: 412 "Precondition Failed"
[2016-01-28T13:07:17+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

好的,我将其添加到我的 Berksfile 中:

source 'https://supermarket.chef.io'

cookbook 'apt'

metadata

然后尝试将 apt cookbook 安装到几个位置:

$ berks install # installs to ~/.berkshelf/cookbooks/
$ berks vendor --except=common berks-cookbooks/

我注意到的第一件事是第二条命令将 apt 和我的通用食谱都打包到我指定的目录中(甚至传递了 --except=common)。没关系:如果我现在尝试运行:

$ sudo chef-client --local-mode --runlist 'recipe[common]'

从我的 cookbook(我称之为 common)目录和 berks-cookbooks 目录。两者都不起作用,上面的错误仍然存​​在。我还尝试在我的 cookbook 目录中使用以下 client.rb:

cookbook_path = "./berks-cookbooks"
chef_repo_path = "#{cookbook_path}"

以及其中的一些变体...

我错过了什么?在本地模式下,如何才能让 chef-client 正确满足这些依赖关系?

满足这种依赖关系的方法是什么?

'''编辑 1''':没有 sudo 则无法运行。

答案1

本地模式下的 Chef 客户端会将其读取knife.rb为其配置文件,而不是client.rb。当在带有 chef-provisioning 等功能的工作站上使用时,这是有意义的,但当您尝试在生产中使用本地模式时,可能会出现意料之外的情况。

通常,您应该使用本地模式berks vendor来处理导出。与其chef-client从 cookbook 文件夹运行,不如创建一个/root/local_mode_repo或类似文件,然后运行berks vendor /root/local_mode_repo/cookbooks。然后您可以chef-client --local-mode在该文件夹中运行。repo 中的特定文件夹名称(如roles/和)cookbooks/通常是不可配置的。

答案2

对于本地开发,chef-client local-mode 会查找config.rbknife.rb,按以下顺序开始$KNIFE_HOME$PWD、 、.chef/,最后是$HOME/.chef/*。

  • 来源: lib/chef-config/workstation_config_loader.rbchef-config-13.8.5gem 中调用gem中load_config_file()的方法client.rbchef-13.8.5

在您的config.rbknife.rb中,您希望您的 cookbooks_path 包含您的菜谱berks_cookbooks

cookbook_path = ["./cookbooks", "./berks-cookbooks"]

我用来收集所有依赖项的一个技巧是使用一个小型 shell 脚本来创建一个Berksfile然后创建berks-cookbooks目录。

#!/usr/bin/env bash
cat <<-EOF > Berksfile
source 'https://supermarket.chef.io'
$(grep -Rh 'depends' cookbooks/* | sed 's/depends/cookbook/')
EOF

berks vendor
berks install

请注意,berks install将把外部食谱安装到您的 Chef 服务器中,以便远程节点可以使用它们,而berks vendor您可以使用它进行本地开发berks-cookbooks

一个提示,我将本地开发人员保持在一个级别上,并且chef-repo/.chef拥有 chef 服务器的配置:

    .
    ├── .chef
    │   └── knife.rb
    ├── my-chef-repo
    │   ├── berks-cookbooks
    │   ├── .chef
    │   │   └── knife.rb
    │   ├── cookbooks
    │   ├── data_bags
    │   ├── environments
    │   ├── nodes
    │   └── roles
    └── .vagrant
        └── machines

相关内容