Order of operations in recipe

I have a recipe that installs various base packages to my systems that are required for all systems across the enterprise.

In the recipe, I have the following block:

node['basepackages']['packages'].each do |curpackage|
  package curpackage
end    

This iterates through an array of packages set in the attributes file.

At this point, we are trying to bring in SuSE to the mix. The problem is, one of the base packages is sysstat and there is a conflict with an installed package (gettext-runtime) which needs to be removed before sysstat is installed.

How can I force the removal of the gettext-runtime package before it tries to install the array of packages?

Because of the way the packages are installed (see above) I can’t use methods such as “subscribes” or “notifies” and such. I also tried to enclose the above block inside of a ruby block to see if I could get it to run later in the process:

ruby_block “package_install” do
block do
node[‘basepackages’][‘packages’].each do |curpackage|
package curpackage
end
end
end

This gave me an error about the “package” method.

How can I write this recipe so that it runs things in the correct order?

Thanks!!

Unless there is some other constraint you are not mentioning in you post, you should be able to do:

package "gettext-runtime" do
  action :remove
end

array_of_packages.each { |p| package p }

You can also use the multi package syntax to install all of your packages more quickly where supported. See: package Resource

Thanks!

I do have that block just above my install array. The entire section of that recipe looks like this:

package 'gettext-runtime' do
action :remove
end

node['basepackages']['packages'].each do |curpackage|
package curpackage
end

This implies that one of your other packages is re-installing gettext-runtime as a dependency, correct? Using the multipackage syntax might force the package manager to do the right thing or give you a better error at least.

Ok. I think I see what you’re saying. I’ll try to remove some of the packages in the array and try them one at a time and see if that’s the case.

Thanks!

That's one way to go, you could also query the package manager's metadata.

My point about multi-package is that on supported platforms it does INSTALLER_COMMAND package1 package2 package3, if two packages in the list are mutually exclusive, then you should get an error back from the package manager telling you that. Also, when it succeeds it should be faster than looping over the packages.

Thanks again.

I think I did get past this. I created a separate array of packages to uninstall and cycled through that. I noticed in the output when I ran the 'chef-client' command that it was doing the removal first. So, now my code looks like this:

node['basepackages']['uninstall_packages'].each do |rmvpkg|
package rmvpkg do
action :remove
end
end

node['basepackages']['packages'].each { |curpackage| package curpackage }

It seems to be getting through this recipe now and I'm on to the next issue.

Thanks for your help!