Knife is the command-line interface for the chef server,It uses the Restful API exposed by the chef server to do its work and helps you to interact with the chef server.
Sometimes,you may want to peek into files stored on your chef server.You might not be sure about an implementation detail of the specific cookbook version currently installed on your chef server and need to look it up.Knife can help you out by letting you show various aspects of life stored on your Chef server.
Install the iptables community cookbook by executing the following command
local@workstation:~ $ knife cookbook site install iptables
Installing iptables to /Users/mma/work/chef-repo/cookbooks
When you execute the command, we get the error.
ERROR: IOError cannot open or read ..../chef-repo/cookbooks/iptables/metadata.rb !
Note:If you get the preceding error, your cookbook only has a metadata.json file.Make sure that you delete it and create a valid metadata.rb, file instead.
Upload the iptables cookbook on your chef server by executing the following command:
local@workstation:~ $ knife cookbook upload iptables --include-dependencies
uploading iptables
uploading combat_resources
uploading 2 cookbooks
Lets find out how knife can help you to look in to the cookbook stored in your chef server?
1) First, you want to find out the current version of the cookbook your interested in.In our case, we are interested in the iptables cookbook:
local@workstation:~ $ knife cookbook show iptables
iptables 3.0.0.0.14.1
2) Then, you can look up the definitions of the iptables cookbook , using the version number that you found in the previous step.
local@workstation:~ $ knife cookbook show iptables 0.14.1 definitions
checksum
name
path
specificity
url: https://s3-external-1.amazonaws.com:443/opscode-platform
3) Now,you can even show the contents of the iptables_rule.rb definition file as stored on the server:
local@workstation:~ $ knife cookbook show iptables 0.14.1 definitions iptables_rule.rb
# Cookbook_Name::iptables
# Definition::iptables_rule
#
#
define :iptables_rule, :enable => true, :source => nil, :variables => {}, :cookbook => nil do
How it works
The knife cookbook show subcommand helps you what exactly is stored on the Chef Server.It lets you drill down in to specific sections of your cookbook and see the exact contents of the files stored in your Chef Server.
You can pass patterns to the knife show command to tell it exactly what you want to see.
Showing the attributes defined by the cookbook can be done as follows:
local@workstation:~ $ knife show cookbooks/iptables/attributes/*
cookbooks/iptables/attributes/default.rb
#
# Cookbook Name::iptables
# Attribute:: default
Truncated OUTPUT
To find some more examples on knife show , visit https://docs.chef.io/knife_show.html
Defining Cookbook Dependencies
Quite often, you might want to use features of other cookbooks in your cookbooks. For example, if you want to make sure that all packages required for compiling software written in c are installed, you want to include the build essential cookbook, which does just that.
The Chef Server needs to know about such dependencies in your cookbooks. You declare them in a cookbook's metadata.
Make sure you have a cookbook named my_cookbook and the run_list of your node includes my_cookbook, as described in the creating and using cookbook.
How to do it
Edit the metadata of your cookbook in the file cookbooks/my_cookbook/metadata.rb to add a dependency to the build-essential cookbook:
local@workstation:~/chef-repo $ subl cookbooks/my_cookbook/metadata.rb
...
depends 'build-essential', ' >= 7.0.3'
How it works
If you want to use a feature of another cookbook inside your cookbook, you will need to include the other cookbook in your recipe using the include_recipe directive:
include_recipe 'build-essential'
To Tell the Chef Server that your cookbook requires the build-essential cookbook, you need to declare that dependency in the metadata.rb file.If you uploaded all the dependencies to your chef server either using the knife cookbook upload my_cookbook --include-dependencies or berks install and berks upload, as described in the Managing cookbook dependencies with Berkshelf
recipe, the chef server will then send all the required cookbooks to the node.
The depends function call tells the Chef Server that your cookbook depends on a version greater than or equal to 7.0.3 of the build-essential cookbook
You may use any of these version constraints with depends calls:
< (less than)
<= (less than or equal to)
= (equal to)
>= (greater than or equal to)
~> (approximate greater that)
> (greater that)
Note:
If you include another recipe inside your recipe,withour declaring the cookbook dependency in your metadata.rb file, FOODCRITIC will warn you:
local@workstation:~/chef-repo $ foodcritic cookbook/my_cookbook
FC007: Ensure recipe dependencies are reflected in cookbook metadata:
cookbooks/my_cookbook/recipes/default.rb:9
This is where Berkshelf comes into play. It works like Bundler for ruby gems,managing cookbook dependencies for you. Berkshelf downloads all the dependencies you defined recursively and helps you to upload all cookbooks to your Chef server.
Instead of polluting your chef repository, it stores all the cookbooks in a central location.You just commit your Berkshelf dependency file (called Berksfile) to your repository every colleague or build server can download and install all those dependent cookbooks based on it.
Lets see how to use Berkshelf to manage dependencies of your cookbook.
Make sure you have a cookbook named my_cookbook and run_list of your node includes my_cookbook as described in the Creating and using cookbook.
How to do it?
Berkshelf helps you to keep those utility cookbooks out of your chef repository.this makes it much easier to maintain the important cookbooks.
Lets see how to write a cookbook by running a bunch of utility recipes and manage the required cookbooks with Berkshelf :
1) Edit your cookbook's metadata
local@workstation:~/chef-repo $ subl cookbooks/my_cookbook/metadata.rb
.....
depends "chef-client"
depends "apt"
depends "ntp"
2) Edit your cookbook's default recipe
local@workstation:~/chef-repo $ subl cookbooks/my_cookbook/recipes/default.rb
.....
include_recipe "chef-client"
include_recipe "apt"
include_recipe "ntp"
3) Run Berkshelf to install all the required cookbooks:
local@workstation:~/chef-repo $ cd cookbooks/my_cookbook
local@workstation:~/chef-repo/cookbooks/my_cookbook $ berks install
Resolving cookbook dependencies
Fetching 'my_cookbook' from source at .
Fetching cookbook index from https://supermarket.chef.io
Installing apt (4.0.2)
4) Upload all the cookbooks on the chef server
local@workstation:~/chef-repo/cookbooks/my_cookbook $ berks upload
Using my_cookbook (0.1.0)
Truncated output
How it works ?
Berkshelf comes with the Chef DK
We edit our cookbook and tell it use a few basic cookbooks
Instead of making us manually install all the cookbooks using knife cookbook site install,Chef generates a Berksfile,besides the metadata.rb file.
The Berksfile is simple .It tells Berkshelf to use the Chef supermarket as the default source for all the cookbooks:
source "https://supermarket.chef.io"
And the Berksfile tells Berkshelf to read the metadata.rb file to find all the required cookbooks.This is the simplest way when working inside a single cookbook, please see the below to see more advanced usage of Berksfile.
After telling Berkshelf where to find all the required cookbook names, we use it to install all those cookbooks:
berks install
Note:Berkshelf stores cookbooks in ~/.berkshelf/cookbooks, by default.This keeps your chef repository clutter free (means confusion/disorder state free).Instead of having to manage all the required cookbooks inside your own chef repository,Berkshelf takes care of them.You simply need to check in Berksfile with your cookbook and everyone using your cookbook can download all the required cookbooks using Berkshelf.
To make sure the that there's no mixup with different cookbooks versions when sharing your cookbook,Berkshelf creates a file called Berksfile.lock alongside Berksfile.
Note:
Don't commit the Berksfile.lock to the version control .If you use berks generate it will automatically populate the .gitignore for you.Otherwise you need to add Berksfile.lock to your .gitignore manually.
Here you will find exact versions of all the cookbooks that Berkshelf installed:
Dependencies
my_cookbook
path: .
metadata true
GRAPH
apt (4.0.2)
compact_resource (>=12.10)
chef-client (6.0.0)
cron (>=1.7.0)
logrotate (>=1.9.0)
windows (>=1.42.0)
..
..
..
Berkshelf will only use the exact versions specified in the Berksfile.lock file,if it finds this file.
Finally we use the Berkshelf to upload all the required cookbooks to the Chef server.
berks upload
Berkshelf integrate with the vagrant:
Berkshelf integrates tightly with Vagrant via the vagrant-berkshelf plugin.You can setup the Berkshelf and Vagrant in such a way that Berkshelf installs and uploads all the required cookbooks on your chef server whenever you execute vagrantup or vagrant provision.You will save all the work of running berks install and berks upload manually before creating you node with the vagrant.
How you can integrate Berkshelf and vagrant ?
1)local@workstation:~/chef-repo $ vagrant plugin install vagrant-berkshelf
Installing the 'vagrant-berkshelf' plugin.This can take a few minutes
Installed the plugin 'vagrant-berkshelf (5.0.0)'!
2)Then you have to say the vagrant to make use of the plugin.You do this by enabling the plugin in Vagrantfile :
local@workstation:~/chef-repo $ subl (sublime) Vagrantfile
config.berkshelf.enabled = true
3)Then you need a Berksfile in the root directory of your chef repository to tell Berkshelf which cookbooks to install on each vagrant run:
local@workstation:~/chef-repo $ sublBerksfile
source 'https://supermarket.chef.io'
cookbook 'my_cookbook',path: 'cookbook/my_cookbook'
4) Eventually you can start your VM using vagrant.Berkshelf will first download and then install the cookbooks in the Berkshelf and upload them to the Chef server.Only after all the cookbooks are made available on the Chef server by Berkshelf will vagrant go on:
local@workstation:~/chef-repo $ vagrant up
Bringing machine server with virtual box provider
==> default: Updating Vagrant's Berkshelf...
==> default: Resolving cookbook dependencies
==> default: 'Fetching 'my_cookbook' from source at cookbooks/my_cookbook
==> default: 'Fetching cookbook index from https://supermarket.chef.io.....
5) This way using Berkshelf together with Vagrant saves a lot of manual steps and gets faster cycle times for your cookbook development.If your using your manual vagrant setup instead of Test kitchen
References:
http://berkshelf.com/
https://github.com/berkshelf/berkshelf
Vagrant Berkshelf plugin source code at
https://github.com/berkshelf/vagrant-berkshelf
No comments:
Post a Comment