Chef infra 厨师配方-资源中没有可用的模块方法

Chef infra 厨师配方-资源中没有可用的模块方法,chef-infra,Chef Infra,我通过一个模块扩展了recipe类,以提供一些属性,这些属性使我能够全局访问动态构造的路径。 例如: 问题是,在资源块中,这些方法不可用 bash "do_something_with_property" do user user code "somecommand #{user_home}" end NoMethodError:Chef::Resource::Bash的未定义方法“user\u home” 奇怪的行为是,user属性工作正常,但代码块中使用的a属性不工作 在此之后,我

我通过一个模块扩展了recipe类,以提供一些属性,这些属性使我能够全局访问动态构造的路径。 例如:

问题是,在资源块中,这些方法不可用

bash "do_something_with_property" do
  user user
  code "somecommand #{user_home}"
end
NoMethodError:Chef::Resource::Bash的未定义方法“user\u home”

奇怪的行为是,user属性工作正常,但代码块中使用的a属性不工作

在此之后,我还通过以下操作将模块包括在所有资源中:

class Chef::Resource
  include Variables
end
现在,my user_home属性在资源块内的行为与在“外部”使用时不同,这意味着:

directory "#{user_home}/new_dir" do
  action :create
end
创建/home/user\u name/new\u dir

bash "create_dir" do
   code "mkdir #{user_home}/new_dir"
end
结果在/home//new\u目录中

我已经用一个小测试脚本测试过了,一切正常

module MyModule
def module_method
    puts "blablalba"
end
end

class A
def block_method (&block)
    block.call
end
end

class B
include MyModule

def doit
    a = A.new
    a.block_method { module_method }
end
end

B.new.doit
所以对我来说,这似乎是一个厨师特有的问题

谁能解释一下,为什么会这样

对于全局访问动态生成的路径和属性,是否有更好的解决方案


谢谢。

能否将路径作为属性输入

在环境级别还是节点级别

我们对cookbook属性做了类似的操作,我们这样做是为了构建安装说明。在本例中,我们从数据包构建安装说明

default['splunk']['server'] = Chef::DataBagItem.load('Splunk', 'Install')["Server"]
default['splunk']['install_args'] = Chef::DataBagItem.load('Splunk', 'Install')["Arguments"]

default['splunk']['installcommands'] = "RECEIVING_INDEXER=\"#{default['splunk']['server']}\" #{default['splunk']['install_args']} /quiet"
尽管如此,我确实认为资源类的扩展应该会让您感觉良好。当你说在资源内部和外部表现不同时。目录也是一种资源,所以在这种情况下,它在两种资源之间的行为是不同的


因此,可能是某个资源的问题导致了不一致的行为?

我已经成功地将方法注入到资源的范围中,如下所示:

库/helper.rb

module MyCookbook
  module Helper
    def my_method
      "foobar"
    end
  end
end

Chef::Resource.send(:include, MyCookbook::Helper)
file 'foo' do
  content my_method
end
配方/default.rb

module MyCookbook
  module Helper
    def my_method
      "foobar"
    end
  end
end

Chef::Resource.send(:include, MyCookbook::Helper)
file 'foo' do
  content my_method
end

这里的关键是<代码> CHIF::Realth.Stand(包括,…)<代码>将您的模块直接注入到 CHIF::资源类,使您的模块方法可用于所有的资源。< /P>属性的问题是,它们不考虑角色或环境中的重写值:
默认[用户]='user_name'default['user_home']=“/home#{node['user']}”这就是为什么我在配方中构建我的user_home路径(或我需要它的任何地方)导致不一致行为的原因,因为出于某种原因,某些属性在块上下文中进行计算(如bash上的code属性)而其他属性(如user和group)在配方上下文中进行计算,我在其中定义了属性。无论如何,我不应该在资源类中包含相同的模块,因为在它的上下文中,节点不可用并且返回不同的值。您是否可以使用一个配方在节点级节点['user_home']=“/home{node['user']}”设置属性,然后它将进入opscode设置的优先级模型。这个配方可以添加到角色的开头吗?这意味着所有配方都可以利用该属性并将其传递到资源中?也许这对于你想要做的事情或者使用环境变量来说有点古怪?