chef from opscode and the power of ruby
Posted by Edmund Haselwanter on Wednesday, October 14, 2009
Recent releases of chef from opscode provide a new resource: ruby_block
This is really great news as this allows for interesting problem solving.
Consider you want to do a very special HTTP request. E.g. a GET to localhost but with custom “Host” header information.
Install a Ruby Http Client
First we have to install a Ruby http client library. I’ll use curb in this example. It builds on top of libcurl so lets install that first.
1 curl_devel = package "curl-devel" do 2 action :install 3 end 4 5 curl_devel.run_action(:install)
With this code we tell chef to immediately execute this code. Otherwise we would have to face the problem that we just fullfill the chefrun post-condition that we have curl-devel installed. Next we have to install the curb gem.
1 curb_gem = gem_package "curb" do 2 action :install 3 end 4 5 curb_gem.run_action(:install)
as you see this is done the same way. Next we want to use curb in THIS chef-run. So we have tell chef the update of Gem, followed by requiring curb
1 Gem.clear_paths 2 3 require 'curb'
Ruby Code in Action
Now we are ready to take action.
1 ruby_block "do-http-request-with-cutom-header" do 2 block do 3 timeout = 600 4 host = "localhost:8080" 5 real_host = "my.realhost.com" 6 Chef::Log.info "call get on #{host}, maximal request time: #{timeout} seconds" 7 c = Curl::Easy.new("http://#{host}/maintenance/do_something") do |curl| 8 curl.headers['Host'] = real_host 9 curl.verbose = true 10 curl.timeout = timeout 11 end 12 c.perform 13 if c.response_code == 200 14 Chef::Log.info "GET success! response was:#{c.body_str}" 15 else 16 Chef::Log.error "GET FAILED. request response was HTTP #{c.response_code}, body: #{c.body_str}" 17 end 18 end 19 action :create 20 end
Great. Isn’t it? :-)