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