Mat*_*att 11 ruby attributes chef-infra
我有两个LWRP.第一个涉及创建磁盘卷,格式化它并将其安装在虚拟机上,我们将调用此资源cloud_volume
.第二个资源(它不是真正重要的)需要一个UUID用于新格式化的卷,这是一个必需的属性,我们将调用此资源foobar
.
资源cloud_volume
和foobar
用于食谱的东西如下.
volumes.each do |mount_point, volume|
cloud_volume "#{mount_point}" do
size volume['size']
label volume['label']
action [:create, :initialize]
end
foobar "#{mount_point}" do
disk_uuid node[:volumes][mount_point][:uuid] # This is set by cloud_volume
action [:do_stuff]
end
end
Run Code Online (Sandbox Code Playgroud)
所以,当我做一个厨师运行时,我得到一个Required argument disk_identifier is missing!
例外.
在做了一些挖掘后,我发现配方分两个阶段进行处理,即编译阶段和执行阶段.看起来这个问题是在编译时,因为那node[:volumes][mount_point][:uuid]
是未设置的时间点.
不幸的是我不能使用OpsCode在这里的技巧,因为在cloud_volume LWRP中使用了通知(所以它会落入文档中显示的反模式)
所以,经过这一切,我的问题是,有没有办法解决disk_uuid
在编译时知道值的要求?
Gre*_*reg 15
更简洁的方法是使用惰性属性评估.这将node[:volumes][mount_point][:uuid]
在执行时而不是编译期间进行评估
foobar "#{mount_point}" do
disk_uuid lazy { node[:volumes][mount_point][:uuid] }
action [:do_stuff]
end
Run Code Online (Sandbox Code Playgroud)
Dra*_*ter 13
免责声明:在添加惰性属性评估之前,这是与老厨师(<11.6.0)相关的方法.
将foobar资源包装到ruby_block中并动态定义foobar.这样在编译阶段之后,您将在资源集合中拥有一个ruby代码,并将在运行阶段进行评估.
ruby_block "mount #{mount_point} using foobar" do
block do
res = Chef::Resource::Foobar.new( mount_point, run_context )
res.disk_uuid node[:volumes][mount_point][:uuid]
res.run_action :do_stuff
end
end
Run Code Online (Sandbox Code Playgroud)
这种方式node[:volumes][mount_point][:uuid]
在编译时不会知道,但在编译时也不会被访问.它只能在运行阶段访问,它应该已经设置好了.
归档时间: |
|
查看次数: |
6516 次 |
最近记录: |