How to add ruby lib as depend at LWRP


#1

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


#2

juanje

how about this?

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

this is just an idea. I have done something similar w/ execute resources
but not with package resources

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


#3

yum. thats the way you do it,
you can see an example of this in aws community cookbook, which provides
elastic ip and eb colume resources but needs right_aws gem .

https://github.com/opscode/cookbooks/blob/master/aws/recipes/default.rb

regards

On Tue, Dec 13, 2011 at 5:38 PM, Bryan Berry bryan.berry@gmail.com wrote:

juanje

how about this?

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

this is just an idea. I have done something similar w/ execute resources
but not with package resources

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


#4

On Tue, Dec 13, 2011 at 1:08 PM, Bryan Berry bryan.berry@gmail.com wrote:

juanje

how about this?

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

this is just an idea. I have done something similar w/ execute resources but
not with package resources

Like that, doesn’t work, but I think is good start. After some tries I got:

f = Chef::Resource::AptPackage.new “libsqlite3-ruby” do
action :install
end
f.run_action(:install)

But it ask me for the run_context:

FATAL: ArgumentError: apt_package[libsqlite3-ruby] (dynamically
defined) had an error: Cannot find the provider for a resource with no
run context set

I tried this:
f = Chef::Resource::AptPackage.new(“libsqlite3-ruby”,
Chef::RunContext.new(@node,
Chef::CookbookCollection.new(Chef::CookbookLoader.new(Chef::Config[:cookbook_path]))))
f.run_action(:install)

Still no luck:
NoMethodError: undefined method `cookbook_collection=’ for nil:NilClass

But getting close. I think…

Thanks for the help :slight_smile:

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


Juanje


#5

Actually, this doesn’t help, because the recipe is loaded at the end,
but I need the package available when the provider is loading (just
after libraries and before the resources, attributes, definitions and
recipes:

http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run

But thanks anyway for the help :slight_smile:

On Tue, Dec 13, 2011 at 3:06 PM, Ranjib Dey ranjibd@thoughtworks.com wrote:

yum. thats the way you do it,
you can see an example of this in aws community cookbook, which provides
elastic ip and eb colume resources but needs right_aws gem .

https://github.com/opscode/cookbooks/blob/master/aws/recipes/default.rb

regards

On Tue, Dec 13, 2011 at 5:38 PM, Bryan Berry bryan.berry@gmail.com wrote:

juanje

how about this?

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

this is just an idea. I have done something similar w/ execute resources
but not with package resources

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


Juanje


#6

that code should work if you run it inside your provider, iirc

it should run immediately and not at the end

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Actually, this doesn’t help, because the recipe is loaded at the end,
but I need the package available when the provider is loading (just
after libraries and before the resources, attributes, definitions and
recipes:

http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run

But thanks anyway for the help :slight_smile:

On Tue, Dec 13, 2011 at 3:06 PM, Ranjib Dey ranjibd@thoughtworks.com
wrote:

yum. thats the way you do it,
you can see an example of this in aws community cookbook, which provides
elastic ip and eb colume resources but needs right_aws gem .

https://github.com/opscode/cookbooks/blob/master/aws/recipes/default.rb

regards

On Tue, Dec 13, 2011 at 5:38 PM, Bryan Berry bryan.berry@gmail.com
wrote:

juanje

how about this?

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

this is just an idea. I have done something similar w/ execute resources
but not with package resources

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


Juanje


#7

Hey
plain ruby code is executed at Compile time, not at converge time, so
the timing is right. That said, I’ve only done similar in a recipe
context, but i think the following code should do what you need:

run_context = Chef::RunContext.new(node, {})
p = Chef::Resource::AptPackage.new(“libsqlite3-ruby”, run_context)
p.run_action(:install)

-T

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com:

On Tue, Dec 13, 2011 at 1:08 PM, Bryan Berry bryan.berry@gmail.com wrote:

juanje

how about this?

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

this is just an idea. I have done something similar w/ execute resources but
not with package resources

Like that, doesn’t work, but I think is good start. After some tries I got:

f = Chef::Resource::AptPackage.new “libsqlite3-ruby” do
action :install
end
f.run_action(:install)

But it ask me for the run_context:

FATAL: ArgumentError: apt_package[libsqlite3-ruby] (dynamically
defined) had an error: Cannot find the provider for a resource with no
run context set

I tried this:
f = Chef::Resource::AptPackage.new(“libsqlite3-ruby”,
Chef::RunContext.new(@node,
Chef::CookbookCollection.new(Chef::CookbookLoader.new(Chef::Config[:cookbook_path]))))
f.run_action(:install)

Still no luck:
NoMethodError: undefined method `cookbook_collection=’ for nil:NilClass

But getting close. I think…

Thanks for the help :slight_smile:

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


Juanje


#8

I did put at the code at the begining of the provider and didn’t work,
I dot those errores I put before.

Seems like there is not package resource or node’s run_context at that
point of the compile time.

On Tue, Dec 13, 2011 at 3:29 PM, Bryan Berry bryan.berry@gmail.com wrote:

that code should work if you run it inside your provider, iirc

it should run immediately and not at the end

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Actually, this doesn’t help, because the recipe is loaded at the end,
but I need the package available when the provider is loading (just
after libraries and before the resources, attributes, definitions and
recipes:

http://wiki.opscode.com/display/chef/Anatomy+of+a+Chef+Run

But thanks anyway for the help :slight_smile:

On Tue, Dec 13, 2011 at 3:06 PM, Ranjib Dey ranjibd@thoughtworks.com
wrote:

yum. thats the way you do it,
you can see an example of this in aws community cookbook, which
provides
elastic ip and eb colume resources but needs right_aws gem .

https://github.com/opscode/cookbooks/blob/master/aws/recipes/default.rb

regards

On Tue, Dec 13, 2011 at 5:38 PM, Bryan Berry bryan.berry@gmail.com
wrote:

juanje

how about this?

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

this is just an idea. I have done something similar w/ execute
resources
but not with package resources

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


Juanje


Juanje


#9

Hi :slight_smile:

Acctually, I did try that before the last solution I put before, but I
got this message:
FATAL: NameError: undefined local variable or method `node’ for
#Class:0xb6c506b4

So I used @node instead of node:
run_context = Chef::RunContext.new(@node, {})
f = Chef::Resource::AptPackage.new(“libsqlite3-ruby”, run_context)
f.run_action(:install)

And I got this:
FATAL: NoMethodError: undefined method `cookbook_collection=’ for nil:NilClass

I’ll keep looking on this.

Thanks for the feedback.

On Tue, Dec 13, 2011 at 4:12 PM, Thom May thom@clearairturbulence.org wrote:

Hey
plain ruby code is executed at Compile time, not at converge time, so
the timing is right. That said, I’ve only done similar in a recipe
context, but i think the following code should do what you need:

run_context = Chef::RunContext.new(node, {})
p = Chef::Resource::AptPackage.new(“libsqlite3-ruby”, run_context)
p.run_action(:install)

-T

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com:

On Tue, Dec 13, 2011 at 1:08 PM, Bryan Berry bryan.berry@gmail.com wrote:

juanje

how about this?

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

this is just an idea. I have done something similar w/ execute resources but
not with package resources

Like that, doesn’t work, but I think is good start. After some tries I got:

f = Chef::Resource::AptPackage.new “libsqlite3-ruby” do
action :install
end
f.run_action(:install)

But it ask me for the run_context:

FATAL: ArgumentError: apt_package[libsqlite3-ruby] (dynamically
defined) had an error: Cannot find the provider for a resource with no
run context set

I tried this:
f = Chef::Resource::AptPackage.new(“libsqlite3-ruby”,
Chef::RunContext.new(@node,
Chef::CookbookCollection.new(Chef::CookbookLoader.new(Chef::Config[:cookbook_path]))))
f.run_action(:install)

Still no luck:
NoMethodError: undefined method `cookbook_collection=’ for nil:NilClass

But getting close. I think…

Thanks for the help :slight_smile:

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com

Hi :slight_smile:

I was tring to find a example or doc about how to do it and I didn’t
find. Maybe I didn’t know where to search…

My problem is that I have a LWRP that need a Ruby library ( require
’sqlite3’ ) and I don’t know how to be sure that the library is
already installed.
Is there any way to install the package from the cookbook before the
provider (LWRP) be loaded?

Any pointers will help. I’m already trying at
$COOKBOOK/libraries/default.rb with no much luck. At least I don’t
know how to call properly from there the ‘package’ provider.

Thanks :slight_smile:


Juanje


Juanje


Juanje


#10

Hi,

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com:

On Tue, Dec 13, 2011 at 1:08 PM, Bryan Berry bryan.berry@gmail.com wrote:

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

Like that, doesn’t work, but I think is good start. After some tries I got:

Bryan’s advice is basically correct, but you will also need to reload
Gem’s cache. See this article for information:

If you are trying this and it doesn’t work, could you please include
more information about how it fails? The right solution should not be
so complicated as to manually create a RunContext in your recipes.

Zac


#11

Hi Zac,

On Tue, Dec 13, 2011 at 4:55 PM, Zac Stevens zts@cryptocracy.com wrote:

Hi,

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com:

On Tue, Dec 13, 2011 at 1:08 PM, Bryan Berry bryan.berry@gmail.com wrote:

at beginning of lwrp

f = package “foo” do
action :install
end
f.run_action(:install)

this might trigger the install action immediately

Like that, doesn’t work, but I think is good start. After some tries I got:

Bryan’s advice is basically correct, but you will also need to reload
Gem’s cache. See this article for information:

http://www.opscode.com/blog/2009/06/01/cool-chef-tricks-install-and-use-rubygems-in-a-chef-run/

If you are trying this and it doesn’t work, could you please include
more information about how it fails? The right solution should not be
so complicated as to manually create a RunContext in your recipes.

I know it shouldn’t be so complicated, but the the Bryan’s solution
doesn’t work like that, because I need the library installed at the
node for the provider. I mean, before my provider (LWRP) is loaded.

The ‘require’ is at the provider, so use the package resource from the
recipe doesn’t help at all. The compile fails before the recipe is
even loaded.

Here is the original I trying to fix:

As I said before, If I try to put Bryan’s code there (before the
’require’), chef-client tell me:
FATAL: NoMethodError: undefined method `package’ for #Class:0xb6c8998c

Because there is no resource ‘package’ loaded at this point. That’s
whay I was trying with Chef::Resource::Package.new and so on.

I don’t think either create manually RunContext or any similar
solution would be a good idea, so I guess I’m going to create a new
cookbook with a simple recipe to install the library and make this
cookbook a dependency of my current one.
At least this will work and is not so ugly…

Thanks for the help to all of you :slight_smile:


Juanje


#12

Hi Juan,

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com:

I know it shouldn’t be so complicated, but the the Bryan’s solution
doesn’t work like that, because I need the library installed at the
node for the provider. I mean, before my provider (LWRP) is loaded.

The ‘require’ is at the provider, so use the package resource from the
recipe doesn’t help at all. The compile fails before the recipe is
even loaded.

Here is the original I trying to fix:
https://github.com/gecos-team/cookbook-bookmarks/blob/master/providers/bookmarks.rb

Okay, I understand now. I’m solving this (in a library, but it should
also work for an LWRP) by requiring the gem like so:

begin
require 'mygem’
rescue LoadError => e
Chef::Log.warn(“Dependency ‘gem’ not loaded: #{e}”)
end
<-- rest of the library code goes here -->

This prevents Chef from failing when the library can’t require the
gem, but the library code is still loaded. The recipe code then has:

package ‘rubygem-mygem’ do
action :nothing
end.run_action(:install)
Gem.clear_paths
require ‘mygem’

This runs at compile time, and ensures that ‘mygem’ has been loaded
before the converge stage. So long as the library code is only used
during the converge stage, that works fine.

I believe the same should be true for your LWRP - you will only have
problems if you’re invoking your LWRP actions at compile-time, using
the run_action() approach used here to install the gem.
Unfortunately, I don’t have an example of this in an LWRP myself, so
I’m not certain that it will work for you.

Zac


#13

Hi :slight_smile:

On Tue, Dec 13, 2011 at 6:16 PM, Zac Stevens zts@cryptocracy.com wrote:

Hi Juan,

2011/12/13 Juan Jesús Ojeda Croissier juanje.ojeda@gmail.com:

I know it shouldn’t be so complicated, but the the Bryan’s solution
doesn’t work like that, because I need the library installed at the
node for the provider. I mean, before my provider (LWRP) is loaded.

The ‘require’ is at the provider, so use the package resource from the
recipe doesn’t help at all. The compile fails before the recipe is
even loaded.

Here is the original I trying to fix:
https://github.com/gecos-team/cookbook-bookmarks/blob/master/providers/bookmarks.rb

Okay, I understand now. I’m solving this (in a library, but it should
also work for an LWRP) by requiring the gem like so:

begin
require 'mygem’
rescue LoadError => e
Chef::Log.warn(“Dependency ‘gem’ not loaded: #{e}”)
end
<-- rest of the library code goes here -->

Nice! Good idea :slight_smile:

This prevents Chef from failing when the library can’t require the
gem, but the library code is still loaded. The recipe code then has:

package ‘rubygem-mygem’ do
action :nothing
end.run_action(:install)
Gem.clear_paths
require ‘mygem’

This runs at compile time, and ensures that ‘mygem’ has been loaded
before the converge stage. So long as the library code is only used
during the converge stage, that works fine.

I believe the same should be true for your LWRP - you will only have
problems if you’re invoking your LWRP actions at compile-time, using
the run_action() approach used here to install the gem.
Unfortunately, I don’t have an example of this in an LWRP myself, so
I’m not certain that it will work for you.

You were right, I made the changes you suggest and it’s working fine so far :slight_smile:

Thanks a lot!


Juanje