Chef-клиент не может найти поваренные книги, используя berkshelf

Я новичок в поваре и столкнулся с проблемами с berkshelf и chef-client. Я хочу иметь свою собственную кулинарную книгу с зависимостями и применять ее. Моя первоначальная поваренная книга выглядит так:

.
├── 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

Любые предложения, почему кулинарные книги не могут быть найдены?

EDIT:

Спасибо за быстрый ответ. Решение было таким, как Джон Беллоун сказал bundle exec berks vendor и изменил мою конфигурацию client.rb на:

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

Ответ 1

Есть несколько каталогов, которые Chef Client будет искать поварами по умолчанию. Один из них - $CWD/cookbooks, который мы можем использовать с помощью команды berks vendor cookbooks. Мне гораздо легче сделать это во время моего тестирования (особенно с автоматизированным процессом), поскольку он гарантирует, что я получаю новую копию кулинарных книг, а не кешированную, устаревшую.

Если вы хотите просто создать среду и запустить, я бы предложил использовать Vagrantfile с плагином vagrant-berkshelf. Это автоматически будет продавать все кулинарные книги в каталоге кеша и загружать их на гостевую машину. Это даже будет работать, если поставщик, который вы используете, является облачным, например. Amazon, Backspace, поскольку он будет использовать rsync вместо общих каталогов.

Ответ 2

Я использую следующий script, это позволяет мне использовать репозиторий git с моими кулинарами, которые зависят от кулинарных книг в супермаркете, но без сервера шеф-повара. Поместите ниже содержимое в файл с именем 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 "[email protected]"
popd

Ответ 3

Все кредиты @revau.lt отвечают, поскольку я только сделал пару настроек для моего собственного использования. Для этого может потребоваться определенная версия Berkshelf, но вся документация, которую я видел, подразумевает, что вы можете использовать "PATH" в конце, чтобы сообщить, где разместить зависимости. Это также явно очищает $tmpdir после того, как некоторые из файлов в конечном итоге принадлежат root из прогона.

Я запускаю этот путь с любым рефавтом cookbook повара с ./local-chef-client my_cookbook_name или ./local-chef-client path/to/chef-repos/specific_repo, где путь разрешается с помощью pwd -P и cookbook - это basename $1, на который ссылается script.

#!/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

Это должно обрабатывать случай, когда кто-то запускает его из INSIDE репо или почти любой путь к репо. Мне нужно будет когда-нибудь написать некоторые тесты BATS, чтобы доказать это, но на данный момент это работает великолепно.

Я обновил его, чтобы обрабатывать папки, которые не соответствуют имени поваренной книги, в случае, если имя репозитория не соответствует или кто-то клонирован к настраиваемому пути. Я действительно попробовал это под моим руководством, а затем пришлось немного поработать с шеф-поваром и выяснить, почему это не сработало, получается, что имя папки имеет значение чуть меньше названия рецепта/кулинарной книги.