How run cookbook with dependencies in chef?
See here
Or just type knife cookbook upload --help
and it will show you the following line (along others):
--include-dependencies Also upload cookbook dependencies
So knife cookbook upload myCookbook --include-dependencies
is your answer
You'll need to have the maven
cookbook on your workstation too, by knife cookbook site install maven
or any other way to have a directory called maven
in your local cookbook_path
containing a cookbook where the metatada.rb
file as a key name
with value maven
Resolving chef-solo cookbook dependencies
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 ;)
Chef cookbook dependency and recipe inclusion
This will work fine, but you don't NEED the third cookbook. You could create a recipe in cookbook B which is a no-op. Then add that recipe to the runlist of the node. This will cause the cookbook B to load on the node. You could alternatively set the node attribute inside that recipe rather than in node's attributes directly. Then, by putting said recipe in your runlist, you would get both done. So, either:
# recipe B::dummy.rb
# do nothing
OR
# recipe B::useme.rb
node['some']['attribute'] = 'B::dothis.rb'
Cookbook dependencies based on chef version
TL;DR
You're using a constraint from the Chef DSL in a way that it's not meant to be used. You need to branch based on a Boolean expression, not a metadata constraint. I provide a couple of ways to do that using String#to_f as examples (not recommended if you care about patch levels in semantic versioning), as well as the more accurate but often-overlooked Gem::Version.
Don't Use a Constraint for Branching
if chef_version '<= 12'
You're trying to use a constraint from the DSL. This constraint has a specific purpose: to declare the chef-client versions supported by the cookbook, not to provide logical branching. Without looking at the underlying Chef code for the DSL, I'd say it's unlikely that the expression is feeding your if-then expression the way you expect. Setting aside for the moment whether this is the right pattern to follow at all, you can try grabbing the current version of your Chef tools in a couple of different ways:
Branching on the chef-client version, likely cast as a Float (it's normally a String). For instance:
if Chef::VERSION.to_f <= 12
Get the node value from ohai with something like:
if node['chef_packages']['chef']['version'].to_f <= 12
Parse the value directly from the client, e.g.:
depends %x(chef-client --version).split[1].to_f <= 12 ? 'ypg_tomcat' : 'yp_tomcat'
However, in all cases, you're going to have to deal with the fact that you're being passed a String containing semantic versioning, not a Float or Integer. So, you'll have to figure out how you really want to parse the information, which is potentially error-prone (see below for a trick using Gem::Version, though). In any case, once you've parsed it the way you want, you can match it using a comparison operator to get the branching behavior you want.
Better Options
Rather than trying to make the metadata constraint hold business logic, you should probably move the data out to an attribute. Consider an attribute such as node['yp_linko']['tomcat_cookbook']
, which you can set based on some other detectable node value other than semantic versioning.
Another approach would be to declare both cookbooks a dependency, and then include the one you want inside a recipe in your yp_linko cookbook. For example, assuming you haven't declared incompatible chef-client versions in the Tomcat cookbooks:
# metadata.rb
depends 'yp_tomcat'
depends 'ypg_tomcat'
# default.rb
if Chef::VERSION <= Gem::Version.new(12)
include ypg_tomcat::default
else
include yp_tomcat::default
end
And finally, you should consider whether it really makes sense to be running different versions of your Chef clients within the infrastructure in the first place. There may be a business need to do that, but it's the real problem you're actually trying to solve for. Branching in your cookbooks is an X/Y solution to an infrastructure issue. It seems likely that you'd have other cookbooks with similar issues, so it's at least worth considering whether it makes more sense to get all your clients on the same version rather than solving the problem at the cookbook level.
Adding Dependencies to Chef Cookbooks
Check out http://berkshelf.com. It allows you to create a Berksfile where you specify the gems you will need, and handles dependency resolution.
Trying to run Chef-client without using dependencies of a certain cookbook
Chef does not support optional dependencies.
Related Topics
Polyline Is Not on the Roads: It Goes Straight from One Point to Other
Android and Getting a View with Id Cast as a String
Using Asynctask with Passing a Value
Multiple Dex Files Define Landroid/Support/Annotation/Animres
Simple Date Format Returns Wrong Date Intermittently
Is There on Install Event in Android
How to Activate "Share" Button in Android App
String-Date Conversion with Nanoseconds
Prevent Webview from Displaying "Web Page Not Available"
How to Convert Rgb Color to Int in Java
Recyclerview Scrolled Up/Down Listener
How to Change Size of Title's Text on Action Bar
Calculating the Angle Between a Line and the X-Axis