Question

I am currently updating the community MySQL cookbook so that it can be used to install Percona, which is a drop in replacement for stock MySQL but has some added functionality to easily enable HA and clustering.

All my additions have worked well until I wanted to be able to use the 'ruby' recipe within the cookbook. This uses the 'chef_gem' provider to install the 'mysql' rubygem. As this is a native extension it needs to be compiled and, to do this, the development files for MySQL need to be installed.

If I use the normal MySQL binaries everything works well as MySQL is already in the Centos repositories. However, so that I can install the Percona packages, I need to ensure that the repo is in '/etc/yum.repos.d'. The problem I am having is that I cannot get chef to do that work before attempting to install the mysql gem.

So, what ends up happening is the system attempts to compile the mysql gem without the development header files for MySQL (Percona) being installed and, even if they are referenced correctly, they are not found as the repository has not been setup.

I created a 'percona-repo' recipe that does this work using the 'yum' provider but it does not run before the 'chef_gem' does. I know that chef has two phases for running and I am assuming that 'chef_gem' is gathering all gems up in the compile phase, regardless of where they are in the overall run list, and then installing all items requested at the beginning. The repository recipe would then be run afterwards.

I tried to play around with the Ruby recipe to do things like:

include_recipe "mysql::percona_repo"

node['mysql']['client']['packages'].each do |mysql_pack|
    package mysql_pack do
        action :nothing
    end.run_action(:install)
end

chef_gem "mysql" do
   action :nothing
end.run_action(:install)

But this does not work. The chef_gem always runs before my "precona_repo" recipe, so the the package installs fail which, if it got that far, would mean that the ruby gem installation would also fail.

If anyone has any bright ideas on how I can solve this please let me know.

Update

Thanks to the suggestion from Mark, I have now update the 'ruby' recipe so that I call the resources to add the new key and repo to the server:

resources(:yum_key => "RPM-GPG-KEY-percona").run_action(:add)
resources(:yum_repository => "Percona").run_action(:add)

And now I can see these being activated in the chef run. However when I look at the filesystem the files are not there so the installation of the mysql client packages fails.

I have done some digging around in the yum cookbook and have found that the provider for the yum_key attempts to run 'remote_file' to download the key as you would expect. However this 'remote_file' is not running. So then I tried to run this as a resource like the above but it has a variable in the name so I cannot call it effectively, e.g.:

remote_file "/etc/pki/rpm-gpg/#{new_resource.key}" do
    ...
end

I think I am beginning to go down a bit of a rabbit warren here. I will keep attempting to get the thing to work but any more ideas are most welcome. I am trying not to go down the route of directly coding in the repo in this recipe as I prefer to reuse things that I know work.

Was it helpful?

Solution

Whatever resource(s) you need from your percona_repo recipe, just call the desired action on it/them manually before the chef_gem.

For instance, if the thing you need looks like this:

yum_repo "percona-repo" do
  action :install
 ...
end

Then you could do this right before the chef_gem declaration:

resources(:yum_repo => 'percona-repo').run_action(:install)

This does, unfortunately, introduce a tight coupling between the two recipes, but there's no way to say "hey, Chef, include this recipe, but do everything in it right away instead of later, 'kay?"

OTHER TIPS

Ok, I went all the way down the rabbit hole.

This appears to work:

include_recipe "percona::client"

resources(:yum_key => "RPM-GPG-KEY-percona").run_action(:add)
begin
  resources(:remote_file => "/etc/pki/rpm-gpg/RPM-GPG-KEY-percona").run_action(:create)
rescue Chef::Exceptions::ResourceNotFound
end

resources("yum_repository[CentOS-Percona]").run_action(:add)
begin
  resources(:template => "/etc/yum.repos.d/CentOS-Percona.repo").run_action(:create)
rescue Chef::Exceptions::ResourceNotFound
end

%w(
  Percona-Server-shared-compat
  Percona-Server-client-55
  Percona-Server-devel-55
).each do |package|
  package(package).run_action(:install)
end

chef_gem "mysql"
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top