我用以下目录结构创建了一个厨师食谱“ lcd_web_source”。
我的 helpers.rb 的内容如下所示
module Lcd_web_source
module Helpers
def platform_package_httpd
case node['platform']
when 'centos' then 'httpd'
when 'ubuntu' then 'apache2'
end
end
def platform_service_httpd
case node['platform']
when 'centos' then 'httpd'
when 'ubuntu' then 'apache2'
end
end
end
end
Chef::Recipe.include(Lcd_web_source::Helpers)
Chef::Resource.include(Lcd_web_source::Helpers)
资源文件“ hello.rb”的内容如下
include Lcd_web_source::Helpers
resource_name :hello_httpd
property :greeting, :kind_of => String
default_action :create
action :create do
package platform_package_httpd
service platform_service_httpd do
action [:enable, :start]
end
template '/var/www/html/index.html' do
source 'index.html.erb'
owner 'apache'
group 'apache'
variables(
greeting_scope: node['greeting_scope'],
greeting: new_resource.greeting,
fqdn: node['fqdn']
)
end
end
和我的食谱default.rb看起来像
package platform_package_httpd
hello_httpd 'greet world' do
greeting "Hello"
action :create
end
运行此配方时,第一个语句
package platform_package_httpd
运行正常,这意味着该配方能够找到库函数。
但是第二条语句失败并出现以下错误
NameError: undefined local variable or method `platform_package_httpd' for #<#<Class:0x0000000004326f00>:0x0000000004244268>
简而言之,资源无法找到库中定义的函数。 帮助我了解为什么会发生这种情况。
答案 0 :(得分:0)
该示例似乎来自Linux Academy课程。我必须在自定义资源DSL中使用action_class
。使用action_class
块,我可以使用在librarys / helper.rb
更改hello.rb,使其包含action_class
块
action_class do
include Lcd_web_source::Helpers
end
resource_name :hello_httpd
property :greeting, :kind_of => String
default_action :create
action :create do
package platform_package_httpd
参考: https://docs.chef.io/custom_resources.html#custom-resource-dsl
答案 1 :(得分:0)
我想为那些还有另一个类似问题的人留下备忘录。
如果您在providers / .rb中实现自定义资源(定义以不同的方式在resources / .rb中,请参见https://docs-archive.chef.io/release/12-3/custom_resources.html)
在这种情况下,action_class
成为无效的语法,
我在提供商模式下找不到此文档,
但受到@Paul B的启发,我发现解决方案是将此语句放在provider / *。rb中:
include ::YourModule::YourSubModule