ext_conf and its uses with omnibus!

So I’ve mentioned in the past that I was struggling to integrate kitchen-cabinet with omnibus tools like chef (or chefdk). My old solution was to do this:

 def self.chef_check
    if File.exist?('/opt/chef')
      ENV['GEM_HOME'] = '/opt/chef/embedded/lib/ruby/gems/1.9.1'
    elsif File.exist?('C:\opscode\chef\\')
      ENV['GEM_HOME'] = 'C:\opscode\chef\embedded\lib\ruby\gems\1.9.1'
    elsif Gem::Specification.find_by_name('chef')
      ENV['GEM_HOME']
    else
      puts 'You don\'t appear to have chef installed.'
      puts 'Please install the gem or omnibus version - `gem install chef` or http://www.getchef.com/chef/install/'
      exit
    end
  end

Now, this allowed me not to step on any toes, but it did leave a little bit to be desired. If the user didn’t have chef installed, it wouldn’t go ahead and take care of it for them. It also did some strange things the the GEM_HOME variable in order to check for chef’s existence (and to be able to use it without shelling out).

I’ve gotten a bit more clever about that though, especially since chefdk was released. Now I can check for chefdk, and then install gems in the embedded chefdk ruby! Omnibus chef and chefdk differ in the way they handle gems - chefdk will save user-installed gems in your home directory, while omnibus-chef would keep them in /opt/chef. What this means is that chefdk can be upgraded without losing gems, while omnibus-chef gets wiped out every time!

In addition, instead of checking dependencies at runtime, ext_conf allows me to install native extensions at the time of gem install.

Basically, I have a file (`ext/mkrf_conf.rb) that looks like this:

require 'rubygems'
require 'rubygems/command.rb'
require 'rubygems/dependency_installer.rb'

Gem::Command.build_args = ARGV

inst = Gem::DependencyInstaller.new
if File.exist?('/opt/chefdk')
  %w(chefspec serverspec guard guard-rubocop guard-foodcritic guard-kitchen guard-rspec rspec).each do |gems|
    `chef gem install #{gems}`
  end

elsif File.exist?('/opt/chef')
  puts 'Consider switching to chefdk or the gem version of chef.'
  puts 'Some functionality of kitchen-cabinet may not be unavailable with your current setup.'
  %w(foodcritic rubocop test-kitchen kitchen-vagrant chefspec serverspec guard guard-rubocop guard-foodcritic guard-kitchen guard-rspec rspec).each do |gems|
    `sudo /opt/chef/embedded/bin/gem install #{gems} --no-ri --no-rdoc`
  end
else
  inst.install 'chef', '~> 11.12.2'
  inst.install 'chefspec', '~> 0.0.0'
end

# create dummy rakefile to indicate success
f = File.open(File.join(File.dirname(__FILE__), 'Rakefile'), 'w')
f.write("task :default\n")
f.close

and in my Gemspec, I reference that like this:
s.extensions = 'ext/mkrf_conf.rb'

Now when kitchen-cabinet is installed, it goes ahead and checks dependencies, and installs things where it should! I’d like to clean things up a bit - maybe check for the chef command that is part of chefdk instead of the directory, and maybe I could do something similar for omnibus-chef. I’d also like to work on pinning versions for gems that I install, since the newest may not always be what I want!

In the end, this was released in version 3.0 of kitchen-vabinet, and I think it’s a huge improvement. There definitely needs to be more work done with the gemfile, as it’s currently very lacking, but all in all, I’m happy with where it is going.

 
0
Kudos
 
0
Kudos

Now read this

PSUMac Admin - Best Of Show!

Links to presentations are up - they can be found here. My personal favorites are as follows - Packet Sniffing for Humans - Yoann Gini Performance Automation with Munki - Matt Hansen, Joshua D. Miller SUStenance via Resposado (and... Continue →