Race condition in the postgresql::ruby recipe


#1

Dear Chefs and esp. Jesse H,

I have encountered in another race condition in the postgresql::ruby
recipe. This recipe installs the pg gem which depends on the
postgresql-devel package. It is installed as a chef_gem which means it runs
immediately at compile time. This is problematic since it depends on the
resource that installs the postgresql-devel package. The current recipe
gets around this by forcing that package to install immediately before
processing the chef_gem resource.

This is problematic for me as I use another resource to configure the yum
repository for postgresql. The current postgresql::ruby recipe fails for me
as the postgresql repository is not yet configured. The postgresql90-devel
package can’t be found. I would have monkey patch that resource to run
immediately prior to installing postgresql-devel.

I have an alternate solution that I have submitted as a patch

There is a little extra weirdness here as the recipe fails for me if
pg_config binary isn’t in the PATH

Rather than running a bunc of resources at compile-time, I chain them using
my hacky check for the existence of a package + the subscribes attribute.

pg_devel_pkg = node[‘postgresql’][‘client’][‘packages’].select { |pkg|
pkg =~ /devel/ }.first
pg_devel_status = Chef::ShellOut.new(“rpm -qa
#{pg_devel_pkg}”).run_command.stdout
pg_devel_installed = ! pg_devel_status.empty?

link “/usr/bin/pg_config” do
to "/usr/pgsql-#{node[‘postgresql’][‘version’]}/bin/pg_config"
unless pg_devel_installed
action :nothing
subscribes :create, resources(“package[#{pg_devel_pkg}]”), :immediately
else
action :create
end
end

chef_gem “pg” do
if ::File.exists? "/usr/bin/pg_config"
action :install
else
action :nothing
subscribes :install, resources(“link[/usr/bin/pg_config]”), :immediately
end
end

The first 3 lines here could be generically encapsulated as a function
like Package.installed? "postgresql-devel" such a method could be
immensely useful

This patch fixes my problems on Centos 6.3 but I have not tested on
any other platform. Is my use of the hacky Package.installed? +
subscribes a good idea?

I keep running into issues w/ cookbooks that push the execution of
resources into compile-time. This strategy is really fragile in my
humble opinion. We need to find a better way to handle such run-time
dependencies.