我正在 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.rb
或knife.rb
,按以下顺序开始$KNIFE_HOME
:$PWD
、 、.chef/
,最后是$HOME/.chef/
*。
- 来源:
lib/chef-config/workstation_config_loader.rb
在chef-config-13.8.5
gem 中调用gem中load_config_file()
的方法client.rb
chef-13.8.5
在您的config.rb
或knife.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