【发布时间】:2016-06-18 03:33:35
【问题描述】:
我收到错误提示
NoMethodError
-------------
undefined method `registry_key' for HashOperations:Module
在融合 Chef 食谱时。
这是 libraries/hash_operations.rb 中代码的简短版本:
module HashOperations
# Tried: require 'chef/mixin/shell_out'
# Tried: include Chef::Mixin::ShellOut
def self.create_reg_keys(item_hash)
item_hash.each do |item_name, item_props|
# (...) construct the item_keys array
registry_key "HKEY_LOCAL_MACHINE\\SOFTWARE\\#{item_name}" do
recursive true
values item_keys
action :create
end
end
end
def self.generate_reg_keys_for_item_key(...)
# some hash operations here
create_reg_keys(item_hash)
end
end unless defined?(HashOperations)
class Chef::Resource
# Tried: Chef::Resource.send(:include, HashOperations)
# Tried: include HashOperations
extend HashOperations
end
这里是 recipes/default.rb:
Chef::Resource.send(:include, HashOperations)
ruby_block "test" do
block do
# Tried: Chef::Recipe.send(:include, HashOperations)
items_keys.each do |item_key|
HashOperations.generate_reg_keys_for_item_key(..., item_key)
end
end
end
我猜主要问题来自于尝试在模块内的方法中使用 Chef 资源 registry_key,而该方法又从配方中调用。
如果我不使用 模块,我有一个工作版本,但如果我想用 ChefSpec 测试代码,我需要一个模块,正如几篇文章指出的那样(比如这个:Stubbing library class methods in ChefSpec)
上面提到的链接是我在模块内部使用 end unless defined?(HashOperations) 的原因。
我尝试使用包含语句,它可以在 cmets 或配方的第一行中看到,正如一些 StackOverflow 帖子所建议的那样,但没有运气。一篇文章讨论了 LWRP 的用法,但我真的不认为这里是这种情况,因为代码与这个食谱严格相关,不会在其他食谱中使用。
注意:我使用 self. 是为了让 def 彼此可见,否则我会收到关于 generate_reg_keys_for_item_key 的错误 不可用。
因此,考虑到我花了很多时间寻找解决方案,包括 StackOverflow 建议的解决方案,问题是:解决此错误的最佳方法是什么,并有一个简单的解决方案可以使用 ChefSpec 进行测试(虽然我并不完全排除 LWRP),我应该包括什么和如何使 registry_key 在收敛操作中可见?
【问题讨论】:
标签: ruby chef-infra chef-recipe chefspec lwrp