[chef] Re: Re: Re: NoMethodError for LWRP within a ruby_block?


Chronological Thread 
  • From: Lucas Hrabovsky < >
  • To:
  • Subject: [chef] Re: Re: Re: NoMethodError for LWRP within a ruby_block?
  • Date: Thu, 5 Dec 2013 14:36:03 -0500

If your able to now get access to your LWRP and hitting the problem of things not running in 
the converge, have a look at converge_by
http://docs.opscode.com/lwrp_custom_provider_ruby.html#converge-by

Here's an example from my app cookbook https://gist.github.com/imlucas/7812280

On Thursday, December 5, 2013 at 2:17 PM, wrote:


Thanks for the response. I forgot chef DSL isn't available within a ruby_block.
Basically, I'm trying to get my recipe actions executing in the right order,
using the chef tools as I understand them so far. I'll probably try run_context
today.

Given my cookbook, the run order I desire is:

1. Start mysql
2. Wait for innodb recovery to complete (i.e. wait for mysql to respond to queries).
3. Query a value from mysql
4. Take action on that value using my LWRP

But the run order that actually happened before I tried putting 3 and 4 into
a ruby_block was:

1. Query a value from mysql (got executed at compile phase)
2. Take action on that value using my LWRP (got executed at compile phase)
3. Start mysql (got executed at convergence phase)
4. Wait for innodb recovery to complete (i.e. wait for mysql to respond to queries). (got executed at convergence phase)


Items executing at compile phase rather than convergence phase is working
against me, I feel. I'll keep trying.

thx,
kallen



On Wed, 04 Dec 2013, Brian Fletcher wrote:

Hi Callen,

When inside a ruby_block the chef DSL doesn't work. You need to use pure
ruby. Here is an example of how you can execute a resource from a
ruby_block. The cookbook is called 'test' and the lwrp is called 'mine'.

ruby_block 'dd' do
block do
mine = Chef::Resource::TestMine.new('bb', run_context)
mine.run_action(:create)
end
action :create
end



You will need something like the following. The lwrp name is turned into
camel case.

mysqlacl = Chef::Resource::ClonerDbSvcMysqlacl("mysqlgrants", run_context)
mysqlacl.ipv4_address(quux_ip)
?

mysqlacl.run_action(:create_acl)

Regarding whether its the right thing to do, I try to avoid them if
possible. This is because it is difficult to make assertions about the
actions executed within a ruby_block using chefspec (unit testing for
chef).

Thanks,

Brian





Hiya,

How do I make an LWRP that I created available in a recipe within a
ruby_block?
It's not working for me.

[2013-12-04T00:13:14+00:00] DEBUG: Re-raising exception: NoMethodError -
ruby_block[do stuff] (cloner::grants line 30) had an error:
NoMethodError: undefined method `cloner_db_svc_mysqlacl' for
Chef::Resource::RubyBlock
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/resource.
rb:294:in `method_missing'
/var/cache/chef/cookbooks/cloner/recipes/grants.rb:67:in `block (2
levels) in from_file'

/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/provider/
ruby_block.rb:33:in `call'

/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/provider/
ruby_block.rb:33:in `block in action_run'

/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/mixin/why
_run.rb:52:in `call'

/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/mixin/why
_run.rb:52:in `add_action'

/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/provider.
rb:149:in `converge_by'

/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/provider/
ruby_block.rb:32:in `action_run'

/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/provider.
rb:114:in `run_action'

/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.2/lib/chef/resource.
rb:625:in `run_action'
...


Afaict, the recipe code needs to execute during the convergence phase of
the
chef-client run. In my case, the code needs to (1) first start mysql, (2)
wait
for mysql to complete its startup (wait for innodb recovery to complete)
and (3)
then query a value from a table. (4) And then do another action depending
on the
value returned.

I tried doing the above outside a ruby_block my first time through, then
realized #3 was executing before #2 had completed. IOW #3 was executing
at the
compile phase. So now I'm trying to put all of this into a ruby_block,
but the
call to my LWRP is failing. (Is using a ruby_block for this the right
answer?)

The LWRP lives in 'cloner-db-svc' cookbook. The cookbook::recipe that
calls it
is 'cloner::grants'. The cloner cookbook depends on cloner-db-svc. When
the code
runs outside of a ruby_block, the recipe finds the LWRP method just fine,
but
the behavior I need doesn't occur.


::Chef::Recipe.send(:include, ::Cloner::Chef::DbSvc::Helper)

ruby_block "do stuff" do
block do
quux_ip = search(:node, 'roles:quux').map {|server|
server['ipaddress'] }.join(",")
cli_password = ::Cloner::Chef::DbSvc::Helper.fetchsecret( "secrets",
"#{node['cloner']['environment']}", "rootpass" )
current_ip = %x( mysql --skip-column-names -hlocalhost -uroot
-p#{cli_password} -e \"SELECT Host FROM mysql.user WHERE
User='cloner_admin'\" )

if current_ip.empty?
Chef::Log.debug("HIGGS-BOSON: current_ip is empty, applying
grants.")
cloner_admin_pass = ::Cloner::Chef::DbSvc::Helper.fetchsecret(
"secrets", "#{node['cloner']['environment']}", "cloner_admin_pass" )
cloner_proc_pass = ::Cloner::Chef::DbSvc::Helper.fetchsecret(
"secrets", "#{node['cloner']['environment']}", "cloner_proc_pass" )

cloner_db_svc_mysqlacl "mysqlgrants" do
action :create_acl
ipv4_address quux_ip
cli_password cli_password
cloner_admin_pass cloner_admin_pass
cloner_proc_pass cloner_proc_pass
end
current_ip = %x( mysql --skip-column-names -hlocalhost -uroot
-p#{cli_password} -e \"SELECT Host FROM mysql.user WHERE
User='cloner_admin'\" )
Chef::Log.debug("HIGGS-BOSON: After applying mysqlgrants, quux_ip
#{quux_ip}; current_ip #{current_ip}")

else # snipped for brevity
end
end
action :create
end



Thanks!
kallen




Archive powered by MHonArc 2.6.16.

§