Can't resolve chef external cookbook dependency in local mode
I'm making my first recipes in chef. I created a cookbook i called common with just one recipe (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
I added "depends 'apt'" at the end of my metadata.rb. If i run:
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)
Ok, so i added to my Berksfile:
source 'https://supermarket.chef.io'
cookbook 'apt'
metadata
Then tried installing apt cookbook to several locations:
$ berks install # installs to ~/.berkshelf/cookbooks/
$ berks vendor --except=common berks-cookbooks/
First thing i notice is that the second command packages both cookbooks, apt and my common, to the directory i specify (even passing --except=common). Nevermind: If i now try to run:
$ sudo chef-client --local-mode --runlist 'recipe[common]'
From my cookbook's (the one i called common) directory AND from the berks-cookbooks directory. None of both worked, the error above persist. I tried also with the following client.rb at my cookbook's directory:
cookbook_path = "./berks-cookbooks"
chef_repo_path = "#{cookbook_path}"
And some variations of these...
What am i missing? What's the way to get those dependencies correctly satisfied with chef-client in local mode?
What's the way of satisfying that dependencies?
'''EDIT 1''': Running without sudo does not work.
Chef client in local mode reads knife.rb
as its config file, not client.rb
. This makes sense when using it on a workstation with things like chef-provisioning, but can be quite unexpected when you are trying to use local-mode in production.
In general with local-mode you should use berks vendor
to handle the export. Rather than running chef-client
from the cookbook(s) folder, make a /root/local_mode_repo
or similar, and run berks vendor /root/local_mode_repo/cookbooks
. Then you can run chef-client --local-mode
inside that folder. The specific folder names within the repo like roles/
and cookbooks/
are generally not configurable.
For local development, chef-client local-mode looks for config.rb
or knife.rb
, starting in the following order $KNIFE_HOME
, $PWD
, .chef/
, and finally $HOME/.chef/
*.
-
source:
lib/chef-config/workstation_config_loader.rb
inchef-config-13.8.5
gem called fromload_config_file()
method fromclient.rb
inchef-13.8.5
gem
In your config.rb
or knife.rb
, you want your cookbooks_path to include both location of your cookbooks and berks_cookbooks:
cookbook_path = ["./cookbooks", "./berks-cookbooks"]
One trick I used scoop up all the dependencies is a small shell script that creates a Berksfile
and then creates the berks-cookbooks
directory.
#!/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
Note that berks install
will install the external cookbooks into your Chef Server so they are available to remote nodes, while berks vendor
is what you can use for local development with the berks-cookbooks
.
One tip, I keep my local dev one level up, and my chef-repo/.chef
to have config for chef server:
.
├── .chef
│ └── knife.rb
├── my-chef-repo
│ ├── berks-cookbooks
│ ├── .chef
│ │ └── knife.rb
│ ├── cookbooks
│ ├── data_bags
│ ├── environments
│ ├── nodes
│ └── roles
└── .vagrant
└── machines