# Howto install a ruby gem that's a pre-req of a chef recipe

**URL:** <https://discourse.chef.io/t/howto-install-a-ruby-gem-thats-a-pre-req-of-a-chef-recipe/3013>\
**Category:** Chef Infra (archive)\
**Created:** [August 15, 2012, 2:55am UTC](https://discourse.chef.io/t/howto-install-a-ruby-gem-thats-a-pre-req-of-a-chef-recipe/3013 "2012-08-15T02:55:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joshua\_Blatt](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/joshua_blatt/32/683_2.png) [@Joshua\_Blatt](https://discourse.chef.io/u/Joshua_Blatt)\
**Post date:** [August 15, 2012, 2:55am UTC](https://discourse.chef.io/t/howto-install-a-ruby-gem-thats-a-pre-req-of-a-chef-recipe/3013/1 "2012-08-15T02:55:55Z")

</div>

Hi guys,

Wondering if you can help me with a little ordering issue.

I want to create a library with an s3\_file resource and provider: [https://gist.github.com/470321](https://gist.github.com/470321)

That code depends on the aws-s3 ruby gem [http://amazon.rubyforge.org](http://amazon.rubyforge.org)

My reading of [http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run](http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run) makes me think the gem won’t be installed until the execution phase but it’ll be ruby required in the compilation phase.

Is there a way to install a ruby gem earlier in the process? Seems like the sort of thing that’d be really useful every once in a while.

Thanks,

Josh

---

<div class="post-metadata">

**Author:** ![AJ\_Christensen](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/aj_christensen/32/525_2.png) [@AJ\_Christensen](https://discourse.chef.io/u/AJ_Christensen)\
**Post date:** [August 15, 2012, 3:15am UTC](https://discourse.chef.io/t/howto-install-a-ruby-gem-thats-a-pre-req-of-a-chef-recipe/3013/2 "2012-08-15T03:15:34Z")

</div>

I believe the s3\_file cookbook on the community site is now written in  
pure ruby (uses OpenSSL to generate the headers), so this is no longer  
necessary.

Regardless, the solution is to use the 'chef\_gem' resource during  
0.10.x (or the chef\_gem cookbook for \<= 0.10.10\*)

chef\_gem "aws-s3"

Also, you can manipulate and fire the resource created by the DSL (the  
'old way') during compile time:

r = gem\_package("aws-s3") { action :nothing }  
r.run\_action(:install)

Cheers,

--AJ

On 15 August 2012 14:55, Joshua Blatt [jblatt@verticloud.com](mailto:jblatt@verticloud.com) wrote:

> Hi guys,
> 
> Wondering if you can help me with a little ordering issue.
> 
> I want to create a library with an s3\_file resource and provider: [https://gist.github.com/470321](https://gist.github.com/470321)
> 
> That code depends on the aws-s3 ruby gem [http://amazon.rubyforge.org](http://amazon.rubyforge.org)
> 
> My reading of [http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run](http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run) makes me think the gem won't be installed until the execution phase but it'll be ruby required in the compilation phase.
> 
> Is there a way to install a ruby gem earlier in the process? Seems like the sort of thing that'd be really useful every once in a while.
> 
> Thanks,
> 
> Josh

---

<div class="post-metadata">

**Author:** ![Joshua\_Blatt](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/joshua_blatt/32/683_2.png) [@Joshua\_Blatt](https://discourse.chef.io/u/Joshua_Blatt)\
**Post date:** [August 15, 2012, 4:28am UTC](https://discourse.chef.io/t/howto-install-a-ruby-gem-thats-a-pre-req-of-a-chef-recipe/3013/3 "2012-08-15T04:28:10Z")

</div>

Thanks for the tip

On Aug 14, 2012, at 8:15 PM, AJ Christensen [aj@junglist.gen.nz](mailto:aj@junglist.gen.nz) wrote:

> I believe the s3\_file cookbook on the community site is now written in  
> pure ruby (uses OpenSSL to generate the headers), so this is no longer  
> necessary.
> 
> Regardless, the solution is to use the 'chef\_gem' resource during  
> 0.10.x (or the chef\_gem cookbook for \<= 0.10.10\*)
> 
> chef\_gem "aws-s3"
> 
> Also, you can manipulate and fire the resource created by the DSL (the  
> 'old way') during compile time:
> 
> r = gem\_package("aws-s3") { action :nothing }  
> r.run\_action(:install)
> 
> Cheers,
> 
> --AJ
> 
> On 15 August 2012 14:55, Joshua Blatt [jblatt@verticloud.com](mailto:jblatt@verticloud.com) wrote:
> 
> > Hi guys,
> > 
> > Wondering if you can help me with a little ordering issue.
> > 
> > I want to create a library with an s3\_file resource and provider: [https://gist.github.com/470321](https://gist.github.com/470321)
> > 
> > That code depends on the aws-s3 ruby gem [http://amazon.rubyforge.org](http://amazon.rubyforge.org)
> > 
> > My reading of [http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run](http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run) makes me think the gem won't be installed until the execution phase but it'll be ruby required in the compilation phase.
> > 
> > Is there a way to install a ruby gem earlier in the process? Seems like the sort of thing that'd be really useful every once in a while.
> > 
> > Thanks,
> > 
> > Josh

---

<div class="post-metadata">

**Author:** ![Joshua\_Blatt](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/joshua_blatt/32/683_2.png) [@Joshua\_Blatt](https://discourse.chef.io/u/Joshua_Blatt)\
**Post date:** [August 16, 2012, 5:12pm UTC](https://discourse.chef.io/t/howto-install-a-ruby-gem-thats-a-pre-req-of-a-chef-recipe/3013/4 "2012-08-16T17:12:47Z")

</div>

After playing with this a bit, I found that chef loads libraries before the recipe is compiled so sometimes you can't use that gem\_package resource in time.

I also noticed that the opscode database cookbook has this problem too. The 'added:' lines below addressed the problem for me, but is this a colossal hack? Would love to know if I'm doing something stupid here or depending on internals that may change in the future….

class Chef  
class Provider  
class Database  
class MysqlUser \< Chef::Provider::Database::Mysql  
include Chef::Mixin::ShellOut

```
    def load_current_resource

```

added: gem\_package = Chef::Resource::GemPackage.new('mysql')  
added: gem\_package.action(:nothing)  
added: gem\_package.run\_action(:install)  
Gem.clear\_paths  
require 'mysql'  
@current\_resource = Chef::Resource::DatabaseUser.new(@new\_resource.name)  
@current\_resource.username(@new\_resource.name)  
@current\_resource  
end

Before I added those lines I saw this:

LoadError: no such file to load -- mysql  
/opt/chef/embedded/lib/ruby/site\_ruby/1.9.1/rubygems/custom\_require.rb:55:in `require' /opt/chef/embedded/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:55:in `require'  
/tmp/exec/cookbooks/database/libraries/provider\_database\_mysql\_user.rb:29:in `load_current_resource' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource.rb:453:in `run\_action'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:49:in `run_action' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:85:in `block (2 levels) in converge'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:85:in `each' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:85:in `block in converge'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource\_collection.rb:94:in `block in execute_each_resource' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection/stepable_iterator.rb:116:in `call'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource\_collection/stepable\_iterator.rb:116:in `call_iterator_block' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection/stepable_iterator.rb:85:in `step'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource\_collection/stepable\_iterator.rb:104:in `iterate' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource_collection/stepable_iterator.rb:55:in `each\_with\_index'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/resource\_collection.rb:92:in `execute_each_resource' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/runner.rb:80:in `converge'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/client.rb:330:in `converge' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/client.rb:163:in `run'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/application/solo.rb:207:in `block in run_application' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/application/solo.rb:195:in `loop'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/application/solo.rb:195:in `run_application' /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/lib/chef/application.rb:70:in `run'  
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-10.12.0/bin/chef-solo:25:in `\<top (required)\>'

Thanks,

Josh

On Aug 14, 2012, at 8:15 PM, AJ Christensen wrote:

> I believe the s3\_file cookbook on the community site is now written in  
> pure ruby (uses OpenSSL to generate the headers), so this is no longer  
> necessary.
> 
> Regardless, the solution is to use the 'chef\_gem' resource during  
> 0.10.x (or the chef\_gem cookbook for \<= 0.10.10\*)
> 
> chef\_gem "aws-s3"
> 
> Also, you can manipulate and fire the resource created by the DSL (the  
> 'old way') during compile time:
> 
> r = gem\_package("aws-s3") { action :nothing }  
> r.run\_action(:install)
> 
> Cheers,
> 
> --AJ
> 
> On 15 August 2012 14:55, Joshua Blatt [jblatt@verticloud.com](mailto:jblatt@verticloud.com) wrote:
> 
> > Hi guys,
> > 
> > Wondering if you can help me with a little ordering issue.
> > 
> > I want to create a library with an s3\_file resource and provider: [https://gist.github.com/470321](https://gist.github.com/470321)
> > 
> > That code depends on the aws-s3 ruby gem [http://amazon.rubyforge.org](http://amazon.rubyforge.org)
> > 
> > My reading of [http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run](http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run) makes me think the gem won't be installed until the execution phase but it'll be ruby required in the compilation phase.
> > 
> > Is there a way to install a ruby gem earlier in the process? Seems like the sort of thing that'd be really useful every once in a while.
> > 
> > Thanks,
> > 
> > Josh

---

<div class="post-metadata">

**Author:** ![Andrea\_Campi](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/andrea_campi/32/514_2.png) [@Andrea\_Campi](https://discourse.chef.io/u/Andrea_Campi)\
**Post date:** [August 16, 2012, 8:08pm UTC](https://discourse.chef.io/t/howto-install-a-ruby-gem-thats-a-pre-req-of-a-chef-recipe/3013/5 "2012-08-16T20:08:00Z")

</div>

On Thu, Aug 16, 2012 at 7:12 PM, Joshua Blatt [jblatt@verticloud.com](mailto:jblatt@verticloud.com) wrote:

> After playing with this a bit, I found that chef loads libraries before the recipe is compiled so sometimes you can't use that gem\_package resource in time.

Did you try chef\_gem as suggested, nay, strongly recommended?

---

<div class="post-metadata">

**Author:** ![Bryan\_McLellan](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.chef.io/bryan_mclellan/32/81_2.png) [@Bryan\_McLellan](https://discourse.chef.io/u/Bryan_McLellan)\
**Post date:** [August 17, 2012, 3:11pm UTC](https://discourse.chef.io/t/howto-install-a-ruby-gem-thats-a-pre-req-of-a-chef-recipe/3013/6 "2012-08-17T15:11:42Z")

</div>

On Thu, Aug 16, 2012 at 1:12 PM, Joshua Blatt [jblatt@verticloud.com](mailto:jblatt@verticloud.com) wrote:

> After playing with this a bit, I found that chef loads libraries before the recipe is compiled so sometimes you can't use that gem\_package resource in time.

libraries are evaluated before recipes in the compilation phase [1].  
What you need to do is a) use chef\_gem and b) move your requires in  
your libraries where they aren't evaluated until the recipe is  
converged.

# library\_gem/libraries/check\_mysql.rb

module CheckMysql  
def check  
require 'mysql'

```
# do something

```

end  
end

# EOF

# library\_gem/recipes/default.rb

class Chef::Recipe  
include CheckMysql  
end

chef\_gem "mysql"

check

# EOF

> I also noticed that the opscode database cookbook has this problem too. The 'added:' lines below addressed the problem for me, but is this a colossal hack? Would love to know if I'm doing something stupid here or depending on internals that may change in the future….

That is an unnecessary hack.

The mysql gem should (must) be installed with chef\_gem (or the old  
gem\_package.run\_action hack) in a recipe before the mysql library is  
required in a chef cookbook library.

The simplest course of action for this part of the discussion is to  
look at the database cookbook refactor that was recently completed  
[1].

Bryan

[1] [http://lists.opscode.com/sympa/arc/chef/2012-08/msg00206.html](http://lists.opscode.com/sympa/arc/chef/2012-08/msg00206.html)
