We have a few packages we like to install through Amazon Linux Extras repo, but we discovered that this doesn't work right:
execute 'Enable java 11 via amazon-linux-extras' do
command 'amazon-linux-extras enable java-openjdk11'
end
package 'java-11-openjdk'
The chef run would always terminate with No candidate version available
, and frustratingly, a simple yum install java-11-openjdk
on the server's command line would work just fine. Further, a subsequent run of Chef on the same machine would also converge successfully.
This is caused by the python yum helper that Chef uses to maintain an in-memory copy of the available packages on the system. If you modify yum repos during a Chef run but don't use chef itself to make this change—by using amazon-linux-extras
for example—this in-memory copy of available packages doesn't get updated, and Chef barfs at you. This has caused problems elsewhere.
The fix is to forcibly reset the helper inside of your chef code via a ruby block. Using the example above, it looks like this:
execute 'Enable java 11 via amazon-linux-extras' do
command 'amazon-linux-extras enable java-openjdk11'
end
ruby_block 'reset yum python helper for java' do
block do
Chef::Provider::Package::Yum::PythonHelper::instance.restart
end
end
package 'java-11-openjdk'
If you want to get fancy, we can add a guard and a notifier to the execute resource. Even though these actions are idempotent, it takes several seconds to restart the helper and you may want to avoid that on subsequent runs.
execute 'Enable java 11 via amazon-linux-extras' do
command 'amazon-linux-extras enable java-openjdk11'
notifies :run, 'ruby_block[reset yum python helper for java]', :immediately
not_if 'rpm -qa | grep java-11-openjdk'
end
ruby_block 'reset yum python helper for java' do
block do
Chef::Provider::Package::Yum::PythonHelper::instance.restart
end
action :nothing
end
package 'java-11-openjdk'
To be frank, this would probably make for a good LWRP cookbook.