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


Chronological Thread 
  • From: Brian Fletcher < >
  • To: " " < >
  • Subject: [chef] Re: NoMethodError for LWRP within a ruby_block?
  • Date: Wed, 4 Dec 2013 22:39:23 +0000
  • Accept-language: en-IE, en-US

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



On 04/12/2013 19:06, 
" "
 
< >
 wrote:

>
>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.

§