chef-client找不到使用berkshelf的食谱

时间:2014-10-25 13:53:10

标签: chef berkshelf

我是厨师的新手,遇到了berkshelf和厨师 - 客户的问题。我想拥有自己的食谱与依赖并应用它。我最初的食谱看起来像这样:

.
├── Berksfile
├── Berksfile.lock
├── chefignore
├── client.rb
├── Gemfile
├── Gemfile.lock
├── metadata.rb
├── README.md
└── recipes
    └── default.rb

#./Berksfile
source 'https://supermarket.getchef.com'

metadata

cookbook 'znc'


#./client.rb
cookbook_path '~/.berkshelf/cookbooks'

当我运行sudo bundle exec chef-client -z -o znc --config=client.rb时,厨师 - 客户找不到食谱:

Starting Chef Client, version 11.16.4
[2014-10-25T15:34:59+02:00] WARN: Run List override has been provided.
[2014-10-25T15:34:59+02:00] WARN: Original Run List: []
[2014-10-25T15:34:59+02:00] WARN: Overridden Run List: [recipe[znc]]
resolving cookbooks for run list: ["znc"]

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

Missing Cookbooks:
------------------
No such cookbook: znc

Expanded Run List:
------------------
* znc


Running handlers:
[2014-10-25T15:34:59+02:00] ERROR: Running exception handlers
Running handlers complete
[2014-10-25T15:34:59+02:00] ERROR: Exception handlers complete
[2014-10-25T15:34:59+02:00] FATAL: Stacktrace dumped to /home/sebastian/.chef/local-mode-cache/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 3.474758165 seconds
[2014-10-25T15:34:59+02:00] ERROR: 412 "Precondition Failed "
[2014-10-25T15:34:59+02:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

还要注意:

ls ~/.berkshelf/cookbooks 
build-essential-2.1.2  znc-0.0.1

为什么无法找到食谱的任何建议?

编辑:

感谢您的快速回答。解决方案就像John Bellone对bundle exec berks vendor说的那样,并将我的client.rb配置更改为:

# ./client.rb
cookbook_path File.dirname(File.expand_path(__FILE__)) + '/berks-cookbooks'

4 个答案:

答案 0 :(得分:12)

默认情况下,Chef Client会查找一些目录。其中一个是我们可以利用$CWD/cookbooks命令的berks vendor cookbooks。我发现在测试期间(特别是使用自动化过程)更容易实现这一点,因为它确保我获得了新的烹饪书副本而不是缓存的陈旧副本。

如果您希望简单地启动并运行环境,我建议您使用带有vagrant-berkshelf插件的Vagrantfile。这将自动供应缓存目录中的所有cookbook并将其上载到来宾计算机。如果您使用的提供商是云提供商,例如,它甚至可以工作。亚马逊,Backspace,因为它将使用rsync而不是共享目录。

答案 1 :(得分:2)

我使用以下脚本,这允许我使用git repo和我的烹饪书,这些食谱依赖于超市里的食谱而没有厨师服务器。将以下内容放在名为local-chef-client的文件中,与您的cookboks目录处于同一级别。然后,您可以将本地计算机与./local-chef-client "recipe[some::default]"聚合在一起。

#!/bin/bash
cmd="berks vendor -b $(pwd)/cookbooks/Berksfile"
pushd /tmp
rm -rf cookbooks
$cmd
mv berks-cookbooks cookbooks
sudo chef-client -z  -r "$@"
popd

答案 2 :(得分:1)

所有归功于@ revau.lt的回答,因为我只为自己的使用做了一些调整。这可能需要某个版本的Berkshelf,但我见过的所有文档都暗示你可以使用" PATH"最后告诉它在哪里放置依赖项。这也明确地清除了$tmpdir,因为一些文件最终以运行方式作为root拥有。

我通过./local-chef-client my_cookbook_name./local-chef-client path/to/chef-repos/specific_repo的任何主厨食谱回购路径运行此路径,其中路径由pwd -P解析,cookbookbasename脚本中引用的$1

#!/bin/bash -x
: ${1:?"Usage: $0 ./path/to/cookbook [doit]"}
case $1 in
 .) cookbook=$(basename $(pwd -P $1));repodir=$(dirname $(pwd -P $1));;
 *) cookbook=$(basename $1);repodir=$(pwd -P $1);;
esac
case $2 in
 doit) whyrun="";;
 *) whyrun="-W ";;
esac
realcookbook=$(grep '^name' $repodir/$cookbook/metadata.rb | sed "s/'//g" | awk '{ print $2 }')
# echo "cookbook is $cookbook"
# echo "realcookbook is $realcookbook"
# echo "repodir is $repodir"
cmd="berks vendor -b $repodir/$cookbook/Berksfile cookbooks"
tmpdir=$(mktemp -d)
pushd $tmpdir
$cmd
sudo chef-client $whyrun -z -o "$realcookbook"
popd
sudo rm -rf $tmpdir
if [ ! "${whyrun}x" == "x" ]; then echo "Append 'doit' after the recipe name to really apply, eg $0 $1 doit"; fi

这应该处理有人从内部仓库运行它的情况,或几乎任何回购路径。我有一天必须写一些BATS测试来证明这一点,但是现在它的工作非常出色。

我更新了它以处理与食谱名称不匹配的文件夹,以防存储库名称不匹配或某人克隆到自定义路径。我实际上有人在我的指导下尝试这个,然后不得不深入了解Chef并找出它为什么不起作用,结果文件夹名称比食谱/食谱名称稍微重要。

答案 3 :(得分:0)

对于本地开发,本地模式会查找config.rbknife.rb,从以下顺序开始$KNIFE_HOME$PWD.chef/,最后{ {1}} *。

    {li> 来源: $HOME/.chef/ lib/chef-config/workstation_config_loader.rb来自chef-config-13.8.5 load_config_file() client.rb chef-13.8.5方法

cookbook_path的{​​{1}}无效,原因有两个:(1)首先,您只能使用命令行中的'~/.berkshelf/cookbooks',来自ruby中的~,以及( 2)该位置具有版本化的烹饪书,例如ENV['HOME'],当主厨正在寻找foo-0.4.6时,它无法解决。

对于本地模式,必须在运行foo后在某处保存下载的食谱,例如本地berks-cookbooks目录。如果你使用berks vendor使用当前的chef13模式,那么你必须从你的食谱中获取超市食谱的所有参考资料。元数据,将其放在主metadata.rb,然后是供应商食谱,然后从您的配置(Berksfile)中引用这个新的berks-cookbooks

使用Berks Pattern的元数据

在您自己的食谱中,knife.rb依赖于行,例如:

metadata.rb

depends 'hostsfile', '~> 3.0.1' 会使用以下内容引用它:

Berksfile

创建Master Berksfile

您需要创建一个引用source 'https://supermarket.chef.io' metadata 目录中所有依赖项的Berksfile。我在chef-repo级别使用shell脚本,如下所示:

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-cookbooksconfig.rb来引用本地开发的两个食谱位置。

knife.rb

可选(本地开发者与主厨服务器)

作为最后一个提示,有许多方法可以将本地开发主厨服务器工作流分开。就个人而言,我使用git子模块,其中chef-repo在其自己的git仓库中,并且拥有自己的chef_repo = File.join(File.dirname(__FILE__), '/path/to/chef-repo') site_cookbooks = "#{chef_repo}/cookbooks" berks_cookbooks = "#{chef_repo}/berks-cookbooks" cookbook_path [site_cookbooks, berks_cookbooks] (由于它具有使用Chef服务器的凭据,因此在.chef中)。

在我的开发环境中,我有一个子目录.gitignore和我的本地开发 ${orgname}-chef-repo配置为使用.chef/knife.rb。当我berks-cookbooks时,我运行shell脚本,创建cd ${orgname}-chef-repoBerksfile目录,然后运行berks-cookbooks,使用本地凭据将所有依赖项上传到服务器。然后berks install返回我的本地开发环境,并使用vagrant,knife-zero和其他工具执行 local dev