Search code examples
dependencieschef-infrachef-solocookbook

Resolving chef-solo cookbook dependencies


I am trying to run chef solo on my workstation to apply some settings locally. My recipe depends on several external cookbooks that I specify in both metadata.rb and Berksfile. The chef-client run fails with the error message below.

I'd like to know if there is a way to download dependencies automatically when chef-solo runs?

user@ubuntu:~/chef-solo$ chef-solo -c solo.rb -j solo.json

Starting Chef Client, version 12.8.1
Installing Cookbook Gems:
Compiling Cookbooks...

Running handlers:
[2016-03-28T16:32:36+00:00] ERROR: Running exception handlers
Running handlers complete
[2016-03-28T16:32:36+00:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated in 03 seconds
[2016-03-28T16:32:36+00:00] FATAL: Stacktrace dumped to /home/user/chef-solo/chef-stacktrace.out
[2016-03-28T16:32:36+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2016-03-28T16:32:36+00:00] ERROR: Cookbook apt not found. If you're loading apt from another cookbook, make sure you configure the dependency in your metadata

solo.rb

root = File.absolute_path(File.dirname(__FILE__))
file_cache_path root
cookbook_path root + '/cookbooks'

solo.json

{
    "run_list": [ "recipe[test::default]" ]
}

Berksfile

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

cookbook 'apt'
metadata

metadata.rb

name 'test'
maintainer 'The Authors'
maintainer_email '[email protected]'
license 'all_rights'
description 'Installs/Configures test'
long_description 'Installs/Configures test'
version '0.1.0'

depends 'apt'

Solution

  • Berkshelf is a popular tool in the Chef world to automate the installation of cookbook dependencies (the Berksfile you mentioned is related to this). If it isn't already, install berkshelf.

    $ gem install berkshelf
    

    Notice in your solo.rb file the line that says...

    cookbook_path root + '/cookbooks'
    

    ...that's where Chef wants you to put the dependencies. Without Berkshelf, you would need to use knife to install apt into that cookbooks folder. (Note: cookbooks/ must be a git repo...)

    $ knife cookbook site install apt
    

    But since you have a Berksfile, you'll probable want to use the command below in the same folder your Berksfile is in...

    $ berks vendor ../
    

    That will install the dependencies for the current folder in the parent directory. You might need to specify a different location depending on where your root cookbooks folder is.

    You might also be wondering why you have to specify the dependencies twice, once in your Berksfile and once in your metadata.rb file. Me too ;)