首页 > 解决方案 > 我可以在厨师节点属性数组上使用 sort 和 uniq 吗?

问题描述

我们有一个生成 bash 脚本的模板,其中包括要根据节点属性检查的补丁列表 - 特别是分配给节点的角色。

patchlist=( <%= node['oracledb']['install']['oneoff']['db_oo_apply'] rescue nil %> <%= node['oracledb']['install']['oneoff']['db_psu_num'] rescue nil %> )

我已经剪掉了实际的列表,但你明白了。

问题是这些属性之间可能存在重复条目,因此我们希望对它们进行排序并获得一个唯一列表。

此外,更复杂的是,并非每个环境中的所有节点都具有这些属性——这就是我们在其中rescue nil撒上这些属性的原因。

我可以将数组构建为

patchlist=( <%= ( node['oracledb']['install']['oneoff']['db_oo_apply'] + ' ' + node['oracledb']['install']['oneoff']['db_psu_num'] rescue nil).split(' ').uniq.sort.join(' ') %> )

如果所有属性都具有值,则该方法有效。

但似乎发生的情况是,如果列表中的任何单个属性为空,则rescue nil启动并且整个数组返回为 nil。

我认为在第一个变体中, 的范围rescue nil仅限于特定属性,但在第二个变体中,它适用于整个字符串。

那么,我能以某种方式构建这个数组,让它排序和唯一,并且仍然控制数组中单个元素可能为空的情况吗?

标签: rubychef-infra

解决方案


实现此目的的一种方法是创建一个实际的节点属性数组。在您当前的实现中,它不是一个数组,只是由空格分隔的属性。

这在模板上有点逻辑过载,但它应该可以工作。

示例模板:

<% p_list = %W( #{node['oracledb']['install']['oneoff']['db_oo_apply']} #{node['oracledb']['install']['oneoff']['db_psu_num']} )

<% p_list_fin = p_list.uniq.sort %>

patchlist=( <% p_list_fin.each do |p| %><% next if p.nil? %><%= p %> <% end %>)

当然p_list,节点属性数组的创建可以在配方中完成,也可以传入variables资源template


推荐阅读