Friday, June 21, 2013

Configure Chef to Install Packages from a Custom Repo

Going Nuts

This was driving me completely nuts last week. I could write Chef recipes to install packages from standard repos but I could not get Chef set up so that the recipe would add a new repo and then install packages using the Chef package configuration.

Truth be told I could do this in a really crude way. I could add a repo by writing a file on the node, and then run a command to install a package directly. It just wouldn't be managed by Chef.

The wrong way

I first created a new cookbook called myinstaller. Then in the templates directory I created a file called custom.repo.erb (The Chef template format) with the following contents:


Note that the baseurl parameter is pointing to a yum repository I have created on one of the virtual machines running on my virtual network.

I then edited the recipe file recipes/default.rb
and added the following:

template "custom.repo" do
  path "/etc/yum.repos.d/custom.repo"
  source "custom.repo.erb"

execute "installjdk" do
    command "yum -y --disablerepo='*' --enablerepo='bmchef' install jdk.x86_64"

This works. But it is crude because I am not using Chef to manage the packages that are installed.

The right way

When you search around into this topic you will come across pages like this one that talk about adding packages with the yum_package command. However if you change the install section above to use this command it will not work. It seems to be related to the fact that simply adding a file to the yum repos directory on the node (while recognized on the machine itself) is not recognized by Chef.

I dug deeper and tried many different versions of adding that repo configuration and I eventually started finding references to the command 'yum_repository'. However, if you try to whack this command into your recipe it doesn't bloody work. It turns out that this is because it is not a command that is built into Chef (unlike 'package' and 'yum_package') it is in fact a command that comes from this open source cookbook for installing yum packages.

If you do not want to use this entire cookbook the critical files to grab are as follows
(I took the three files from this last directory, which may not be strictly necessary).

Now before you can use the command there are a couple of gotchas. 
1) If you copy all of this to a new cookbook called myyum, then the repository command will now be 'myyum_repository'
2) You will need to edit the file yum/providers/repository.rb 
 go to the bottom where the repo config is being written and change the line:
cookbook "yum"
So that the name of your cookbook appears there instead.

You will now be able to add a repository by putting the following in a recipe

myyum_repository "custom" do
  description "MyRepo"
  url "http://chef.vb:8088/yum/Redhat/6/x86_64"
  repo_name "custom"
  action :add

yum_package "mypackage" do
  action :install
  flush_cache [:before]

Just upload your new cookbook: 
sudo knife cookbook upload myyum

Add the recipe to your node: 
knife node run_list add node2.vb 'recipe[myyum::default]'

And execute: 
knife ssh name:node2.vb -x <USER> -P <PASSWORD> "sudo chef-client"