How to make chef check for RPM package and then install?

22,747

Solution 1

I know this is old, but I believe you want:

remote_file "your-remote-file" do
  ...
  not_if "rpm -qa | grep -qx 'your-package'"
end

Solution 2

I am not familiar with RPM, but you can check out how chef learns if the package is already installed (the load_current_resource method). You can implement something similar in your recipe and add this condition to remote_file:

remote_file "#{Chef::Config[:file_cache_path]}/#{javaRPM}" do
  not_if { [your_code_that_checks_if_package_installed] }
  ...
end

Solution 3

Chef provide a resource for rpm_packages. and you can find a lot numbers of examples that show how chef verify if a package is installed

Solution 4

There is another way with not_if, see an example below

execute 'yum -y install ntp' do
  not_if "rpm -qa | grep 'ntp'"
end

Solution 5

You can first remove the package using ignore_failure and then install it

package 'package_name'
  ignore_failure true
  action         :remove
end

Then grab the file

remote_file localPath do
    source packageUrl
    mode 0644
    checksum checkSum
end

Then install the package

package packageName do
      source localPath
      action :install
      allow_downgrade true
end

This will work with any package type. For rpm's ideally you do not need to remove the package. allow_downgrade should work. But it didn't work for me.

For checksum use curl packageUrl | shasum -a 256

Share:
22,747
noMAD
Author by

noMAD

"State is the root of all evil"

Updated on September 06, 2020

Comments

  • noMAD
    noMAD over 3 years

    I am currently using chef to install the RPM JDK package but the problem is that it does it every single time even if the package is already downloaded and installed. I tried finding an option for checking before installing but there wasn't any. Is there a way to get around this such that I can skip packages that are already installed? Debian's package management skips already installed packages by default, but RPM package manager doesn't seem to do that.

    [Tue, 23 Oct 2012 10:34:32 -0500] INFO: Processing remote_file[/var/chef/cache/jdk-1.6-u30-linux-amd64.rpm] action create_if_missing (sun_java::default line 18)
    [Tue, 23 Oct 2012 10:34:36 -0500] INFO: Processing package[jdk-1.6-u30-linux-amd64.rpm] action upgrade (sun_java::default line 25)
    [Tue, 23 Oct 2012 10:37:15 -0500] INFO: Processing bash[update-alternatives java] action nothing (sun_java::default line 40)
    

    The recipe is show below:

        urlVersion = "1."+node["sun_java"]["version"].sub(/[u]/, "-u")
        node.default["sun_java"]["rpm_url"] = "http://***/#{urlVersion}/jdk-#{urlVersion}-linux-#{node["sun_java"]["arch"]}.rpm"
    
        #Check that we are using the .rpm file because of the recent change
        if File.extname(File.basename(node["sun_java"]["rpm_url"]))!=".rpm"
          raise "You must use the jdk*.rpm file to install the Sun JDK. You can get it from the jdk*-rpm.bin file by running the command './jdk*-rpm.bin -x'"
        end
    
        javaRPM = File.basename(node["sun_java"]["rpm_url"])
    
        remote_file "#{Chef::Config[:file_cache_path]}/#{javaRPM}" do
          action :create_if_missing
          source node["sun_java"]["rpm_url"]
          mode "0755"
          backup false
        end
    
        package javaRPM do
          action :install
          source "#{Chef::Config[:file_cache_path]}/#{javaRPM}"
          options "--nogpgcheck" # sun/oracle doesn't sign their RPMs o_O
          notifies :run, "bash[update-alternatives java]", :immediately
        end
    
        javaHomeFolder = "/usr/java/jdk1.#{node["sun_java"]["version"].sub(/[u]/, ".0_")}"
        jdkFolder = "#{javaHomeFolder}/bin"
        slaveString = ""
    
        node["sun_java"]["update_slaves"].each do |java_bin|
          slaveString = slaveString + "--slave \"/usr/bin/#{java_bin}\" \"#{java_bin}\" \"#{jdkFolder}/#{java_bin}\" "
        end
    
        bash "update-alternatives java" do
          action :nothing
          code <<-EOH
            update-alternatives --install "/usr/bin/java" "java" "#{jdkFolder}/java" 1 #{slaveString}
            update-alternatives --set java #{jdkFolder}/java
          EOH
        end
    
        #Remove old environment then notify new environment to be created
        ruby_block "delete_environement" do
                block do
                    editBashrc = Chef::Util::FileEdit.new("/etc/profile")
                        editBashrc.search_file_delete_line(/^.*#JAVA_HOME environment settings.*$/)
                        editBashrc.search_file_delete_line(/^.*#Auto-generated by Chef Cookbook sun_java.*$/)
                        editBashrc.search_file_delete_line(/^.*export JAVA_HOME=.*$/)
                        editBashrc.write_file 
                end
                action :create
        end
    
        #create environment of root user
        execute "create_environment" do
          user "root"
          command "echo -e '#JAVA_HOME environment settings\n#Auto-generated by Chef Cookbook sun_java\nexport JAVA_HOME=#{javaHomeFolder}' >> /etc/profile"
        end