我们正在使用 Apache Ambari 建立集群。
由于需要使用 Ambari 来配置 Hadoop 集群,我们的 Chef 运行被中断。当前安装分为三个部分:
- 初始 Chef 运行以准备操作系统。
- 使用 Ambari 配置(并稍后管理)Hadoop 集群。
- 使用第二次 Chef 运行的后 Ambari 配置。
我搜索了类似的问题,但答案都围绕着使用包含条件保护属性的资源。第二次运行使用了一系列不接受保护属性的资源。
我一直在通过使用执行命令和“not_if”/“only_if”保护来解决这个问题。例如:
%w{package1 package2 package3 package4}.each do |package|
execute "Install #{package}" do
command "yum install #{package}"
user 'root'
only_if { ::File.exists?("/etc/yum.repos.d/ambari.repo")}
end
end
但为每个资源编写代码会很繁琐。一定有更好的方法。
如果满足一个条件,是否存在执行配方中所有剩余代码(或选择资源)的标准或“最佳”实践?
我考虑过包装在 Ruby 块中并使用通知,但块似乎是声明性的。我不确定如何最好地将它们设置为“如果 y 则执行 x,否则不执行任何操作”,或者这是否是适合这项工作的工具?
ruby_block "Check for Ambari.repo" do
block do
File.exists?("/etc/yum.repos.d/ambari.repo")
end
notifies :run "execute[package]" :immediately
end
%w{package1 package2 package3 package4}.each do |package|
execute "Install #{package}" do
command "yum install #{package}"
user 'root'
action :nothing
end
end
答案1
您要求的是 if 块,那么为什么不直接使用 if 块呢?
if File.exists?("/etc/yum.repos.d/ambari.repo")
%w{package1 package2}.each do |pkg|
package pkg
end
... do some other stuff here if you want...
end
包的默认操作是安装,因此在这种情况下您不需要完整的块。
答案2
CHEF(按设计)是声明式的,描述目标状态。也就是说,下面的一系列块应该可以实现您想要成功实现的目标...
# Ensure needed packages are installed
package %w{package1 package2 package3 package4} do
action :install
only_if { ::File.exists?("/etc/yum.repos.d/ambari.repo") }
end
# Conditional Block#1
if ( condition#1 )
<some chef or ruby block>
end
# Conditional Block#2
if ( condition#2 )
<some chef or ruby block>
end
如果您进一步解释所需的其余步骤,我将能够提供更具体的指导。例如,在服务启动并运行时运行条件 CHEF 和/或 Ruby 块。
也许可以看看ruby_block
或者这些条件 CHEF 块的示例https://stackoverflow.com/questions/46914926/chef-run-install-block-based-on-variable-condition。