Chef Cookbook中not_if执行RPM检查命令的警告问题求助
问题场景
我在Chef Cookbook中编写了如下代码:
unless app_rpm.nil? node.default['app_rpms'] = \ %w(agent1 agent2 agen3 agent4) node['app_rpms'].each do |rpm_package| package rpm_package do action :remove not_if { "rpm -qa | grep -qx '#{node['agents']['agent']['type']['rpm_full_name']}'" } end end end
尽管已在role中正确定义了node['agents']['agent']['type']['rpm_full_name']的值(格式如agent1-22.06-01.noarch),但运行rake unit时仍收到如下警告:
WARN: not_if block for yum_package[agent1] returned "rpm -qa | grep -qx ''", did you mean to run a command? If so use 'not_if "rpm -qa | grep -qx ''"' in your code
所有agent均出现该问题。
之后我将代码修改为单独定义命令变量,再在not_if中引用:
rpm_check_command = "rpm -qa | grep -qx '#{node['agent']['type']['rpm_full_name']}'" not_if { rpm_check_command }
现在收到的警告变为:
WARN: not_if block for yum_package[agent1] returned "rpm -qa | grep -qx 'agent1-21.11.2-0.noarch'", did you mean to run a command? If so use 'not_if "rpm -qa | grep -qx 'agent1-21.11.2-0.noarch'"' in your code.
正确写法
问题根源在于:not_if后使用大括号{}时,Chef会将其视为Ruby代码块执行。如果代码块返回字符串,Chef会把非空字符串判定为true,不会执行对应的系统命令,从而触发警告。
要让Chef执行系统命令,需要直接将命令字符串传给not_if,而非放在Ruby代码块中。
写法一:直接传入命令字符串
unless app_rpm.nil? node.default['app_rpms'] = %w(agent1 agent2 agen3 agent4) node['app_rpms'].each do |rpm_package| package rpm_package do action :remove not_if "rpm -qa | grep -qx '#{node['agents']['agent']['type']['rpm_full_name']}'" end end end
写法二:通过变量传入命令
如果需要单独定义命令变量,直接将变量传给not_if即可:
unless app_rpm.nil? node.default['app_rpms'] = %w(agent1 agent2 agen3 agent4) node['app_rpms'].each do |rpm_package| rpm_check_command = "rpm -qa | grep -qx '#{node['agents']['agent']['type']['rpm_full_name']}'" package rpm_package do action :remove not_if rpm_check_command end end end
这样修改后,Chef会正确识别并执行rpm检查命令,根据命令的退出码决定是否跳过package资源的移除操作。
内容的提问来源于stack exchange,提问作者Geoff Harrison

