我想检查是否有从属数据包。如果有,并且其中包含数据,那么我想为每个从属执行一个操作。
我有以下代码:
slaves = data_bag('slaves')
if slaves.length > 0
for slave in slaves
...xyz..
end
end
这种方法有效,除非数据包尚不存在。我如何检查数据包是否存在?或者我的做法完全错误?
答案1
当您尝试访问尚不存在的数据包时,Chef 将引发异常,具体取决于您正在运行的 Chef 客户端类型。
例如,在 Chef Solo 中,您将引发一个名为的异常Chef::Exceptions::InvalidDataBagPath
,而使用 Chef Client(针对 Chef Server)时Net::HTTPServerException
将引发异常,因为在对服务器的 API 调用中找不到该对象。
因此,您可以将设置包装在 Ruby 块中,如下所示:
slaves = begin
data_bag('slaves')
rescue Net::HTTPServerException, Chef::Exceptions::InvalidDataBagPath
[] # empty array for length comparison
end
if slaves.length > 0
for slave in slaves
...xyz..
但是,这会返回一个空数组,因为您正在使用它进行.length
比较。
如果目标是任何从属,然后对它们进行迭代,我会做这样的事情:
slaves = begin
data_bag('slaves')
rescue Net::HTTPServerException, Chef::Exceptions::InvalidDataBagPath
nil
end
if slaves
slaves.each do |slave|
...xyz..
nil
如果数据包不存在,则返回一个,而不是一个数组,如果数据包存在但为空,则返回正确的值,并且xyz
只有在不存在的情况下才会执行步骤nil
。
(我还将其改为for slave in slaves
更符合 Ruby 习惯的.each
迭代器。)
您可以查看数据包加载器代码这里如果有兴趣的话。