Chef食谱execute资源中根据服务器标签设置command报错及优化问题
这个问题我之前也碰到过,本质是Chef的上下文范围问题——你用的tagged?是Recipe DSL里的快捷方法,但直接写在execute资源块里时,代码的上下文变成了Chef::Resource::Execute对象,而这个对象并没有tagged?方法,所以才会报NoMethodError。
下面给你几个优雅的解决思路,完全不用重复写整个资源:
1. 最简洁的方案:直接调用node.tagged?
node是Chef里全局可用的对象,在资源块里也能正常访问,它的tagged?方法是原生支持的,直接替换掉原来的tagged?就行:
execute 'application_settings_control' do command node.tagged?('test-server') ? "/usr/sbin/application_settings --disablessl --fix /etc/correct-settings.json" : "/usr/sbin/application_settings --fix /etc/correct-settings.json" # 这里可以添加其他属性,比如 user 'root', group 'root', timeout 30 等 end
2. 更易读的方案:提前定义命令变量
如果判断逻辑后续可能变复杂,或者你想让资源块更干净,可以把命令逻辑抽到资源外面的变量里:
# 在食谱的顶级上下文(资源块外部)定义命令字符串 application_command = if node.tagged?('test-server') "/usr/sbin/application_settings --disablessl --fix /etc/correct-settings.json" else "/usr/sbin/application_settings --fix /etc/correct-settings.json" end execute 'application_settings_control' do command application_command # 其他属性 end
3. 特殊场景方案:用lazy延迟求值
如果你的节点标签可能在Chef编译阶段之后被其他资源修改(这种场景比较少见),可以用lazy块把命令的求值延迟到执行阶段:
execute 'application_settings_control' do command lazy do node.tagged?('test-server') ? "/usr/sbin/application_settings --disablessl --fix /etc/correct-settings.json" : "/usr/sbin/application_settings --fix /etc/correct-settings.json" end # 其他属性 end
这些方法都能避免代码冗余,保持食谱的可维护性,比重复写两个资源要优雅得多。
内容的提问来源于stack exchange,提问作者Henrik supports the community
相关产品推荐
相关产品推荐

